mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-06 11:24:07 +08:00
🛸 Sync 2026-10-29 02:04:12
This commit is contained in:
1 parent
b21929fceb
commit
bfd56813e0
37 files changed
+3918
-4346
No files matched your search
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=isp-split
|
PKG_NAME:=isp-split
|
||||||
PKG_VERSION:=0.2.1
|
PKG_VERSION:=0.2.2
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=3
|
||||||
PKG_LICENSE:=MIT
|
PKG_LICENSE:=MIT
|
||||||
PKG_LICENSE_FILES:=LICENSE
|
PKG_LICENSE_FILES:=LICENSE
|
||||||
PKG_MAINTAINER:=jihebube <jihebube@users.noreply.github.com>
|
PKG_MAINTAINER:=jihebube <jihebube@users.noreply.github.com>
|
||||||
|
|||||||
@@ -15,7 +15,14 @@
|
|||||||
# install 注册开机自启与每日更新
|
# install 注册开机自启与每日更新
|
||||||
# uninstall 卸载所有改动
|
# uninstall 卸载所有改动
|
||||||
set -u
|
set -u
|
||||||
ISP_VERSION="0.2.1-logo"
|
ISP_VERSION="0.2.2"
|
||||||
|
|
||||||
|
# 配置表里的注释行(# 开头,允许前导空白)必须在按空白展开之前整行删掉
|
||||||
|
# (B-1)。否则 `for row in $ISP_TABLE` 会把 "#" 与后面的文字拆成两个
|
||||||
|
# token,注释片段被当成数据行。只改内存,不写回配置文件。
|
||||||
|
_strip_comments() {
|
||||||
|
printf '%s\n' "$1" | sed 's/^[[:space:]]*#.*$//' | sed '/^[[:space:]]*$/d'
|
||||||
|
}
|
||||||
|
|
||||||
CONF=${ISP_SPLIT_CONF:-/etc/isp-split.conf}
|
CONF=${ISP_SPLIT_CONF:-/etc/isp-split.conf}
|
||||||
BASE=${ISP_SPLIT_BASE:-/etc/isp-split}
|
BASE=${ISP_SPLIT_BASE:-/etc/isp-split}
|
||||||
@@ -47,9 +54,10 @@ DNSMASQ_SERVICE=${DNSMASQ_SERVICE:-/etc/init.d/dnsmasq}
|
|||||||
# 但 ISP_TABLE 的最后一列会变成 "1\r",`[ "$4" = "1" ]` 永远不成立:
|
# 但 ISP_TABLE 的最后一列会变成 "1\r",`[ "$4" = "1" ]` 永远不成立:
|
||||||
# plan 只剩一张空表、status 只剩兜底行、apply 报"没有启用的运营商",
|
# plan 只剩一张空表、status 只剩兜底行、apply 报"没有启用的运营商",
|
||||||
# 而真正的原因(行尾多了一个 \r)完全看不出来。这里在入口统一去掉。
|
# 而真正的原因(行尾多了一个 \r)完全看不出来。这里在入口统一去掉。
|
||||||
ISP_TABLE=$(printf '%s' "${ISP_TABLE:-}" | tr -d '\r')
|
# 注释行也在同一处删掉(B-1):删除必须发生在任何按空白展开之前。
|
||||||
DNS_TABLE=$(printf '%s' "${DNS_TABLE:-}" | tr -d '\r')
|
ISP_TABLE=$(_strip_comments "$(printf '%s' "${ISP_TABLE:-}" | tr -d '\r')")
|
||||||
DOMAIN_SPLIT=$(printf '%s' "${DOMAIN_SPLIT:-}" | tr -d '\r')
|
DNS_TABLE=$(_strip_comments "$(printf '%s' "${DNS_TABLE:-}" | tr -d '\r')")
|
||||||
|
DOMAIN_SPLIT=$(_strip_comments "$(printf '%s' "${DOMAIN_SPLIT:-}" | tr -d '\r')")
|
||||||
|
|
||||||
# ---- 多数据源(0.2.1 默认双源)----
|
# ---- 多数据源(0.2.1 默认双源)----
|
||||||
# ISP_SOURCES 为空 = 单源兼容模式:仍按 ISP_MIRROR/<源名>.txt 拉取,
|
# ISP_SOURCES 为空 = 单源兼容模式:仍按 ISP_MIRROR/<源名>.txt 拉取,
|
||||||
@@ -1453,7 +1461,7 @@ cmd_apply() {
|
|||||||
# 取第一个 enabled=1 的行,而不是无条件取第一行:用户禁用第一个
|
# 取第一个 enabled=1 的行,而不是无条件取第一行:用户禁用第一个
|
||||||
# 运营商后,wire 不会为它建集合,旧写法会让每日 refresh 永久失败。
|
# 运营商后,wire 不会为它建集合,旧写法会让每日 refresh 永久失败。
|
||||||
_fs=""
|
_fs=""
|
||||||
for _row in $(_conf_val ISP_TABLE 2>/dev/null); do
|
for _row in $(_conf_table ISP_TABLE 2>/dev/null); do
|
||||||
_old_ifs=$IFS
|
_old_ifs=$IFS
|
||||||
IFS=':'
|
IFS=':'
|
||||||
set -- $_row
|
set -- $_row
|
||||||
@@ -1596,6 +1604,112 @@ _write_rule() {
|
|||||||
} >> "$WORK/rules.txt"
|
} >> "$WORK/rules.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ---- 孤儿 ipset 段收敛(B-4)----
|
||||||
|
# 段名可以改名/删除/禁用,但 mwan3 的 config ipset 段不会自己消失:
|
||||||
|
# 旧段仍然 enabled=1、loadfile 指向旧数据文件,mwan3 下次 reload 照样
|
||||||
|
# 建集合、灌元素,永久驻留。旧版 uninstall 也只看"当前表里的名字",
|
||||||
|
# 连卸载都清不掉。
|
||||||
|
#
|
||||||
|
# 识别方式只有一个:isp_split=1 标记(_wire_ipset 写入)。绝不按 isp_
|
||||||
|
# 前缀猜 —— 用户自己的 mwan3 ipset 段可能也叫 isp_xxx。没有标记的段
|
||||||
|
# (0.2.1-happy 之前的旧版本写的)一律不动,只在日志里列出来。
|
||||||
|
#
|
||||||
|
# 当前仍有效的集合名:ISP_TABLE 里第 4 列=1 的行。DNS_TABLE 不引用
|
||||||
|
# ipset,但把它的字段也纳入保护集合,避免同名段被误删(保守兜底)。
|
||||||
|
_keep_set_names() {
|
||||||
|
_ks=" "
|
||||||
|
for _row in $ISP_TABLE; do
|
||||||
|
[ -n "$_row" ] || continue
|
||||||
|
_old_ifs=$IFS
|
||||||
|
IFS=':'
|
||||||
|
set -- $_row
|
||||||
|
IFS=$_old_ifs
|
||||||
|
[ $# -ge 4 ] || continue
|
||||||
|
[ "$4" = "1" ] || continue
|
||||||
|
_ks="$_ks$2 "
|
||||||
|
done
|
||||||
|
for _row in ${DNS_TABLE:-}; do
|
||||||
|
[ -n "$_row" ] || continue
|
||||||
|
_old_ifs=$IFS
|
||||||
|
IFS=':'
|
||||||
|
set -- $_row
|
||||||
|
IFS=$_old_ifs
|
||||||
|
for _f in "$@"; do
|
||||||
|
case "$_f" in "" | *[!A-Za-z0-9_]*) continue ;; esac
|
||||||
|
_ks="$_ks$_f "
|
||||||
|
done
|
||||||
|
done
|
||||||
|
printf '%s\n' "$_ks"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 所有 config rule 引用的 ipset 名(空格分隔,带前后空格便于整词匹配)
|
||||||
|
_rule_ipset_refs() {
|
||||||
|
_ri=" "
|
||||||
|
for _ri_sec in $(uci -q show mwan3 2>/dev/null |
|
||||||
|
sed -n 's/^mwan3\.\([^=]*\)=rule$/\1/p'); do
|
||||||
|
_ri_v=$(uci -q get "mwan3.$_ri_sec.ipset" 2>/dev/null) || continue
|
||||||
|
for _ri_x in $_ri_v; do
|
||||||
|
case "$_ri_x" in "" | *[!A-Za-z0-9_]*) continue ;; esac
|
||||||
|
_ri="$_ri$_ri_x "
|
||||||
|
done
|
||||||
|
done
|
||||||
|
printf '%s\n' "$_ri"
|
||||||
|
}
|
||||||
|
|
||||||
|
_prune_orphan_ipsets() {
|
||||||
|
[ -f "$CFG_MWAN3" ] || return 0
|
||||||
|
_po_keep=$(_keep_set_names)
|
||||||
|
_po_refs=$(_rule_ipset_refs)
|
||||||
|
_po_changed=0
|
||||||
|
for _po_sec in $(uci -q show mwan3 2>/dev/null |
|
||||||
|
sed -n 's/^mwan3\.\([^=]*\)=ipset$/\1/p'); do
|
||||||
|
_po_name=$(uci -q get "mwan3.$_po_sec.name" 2>/dev/null) || continue
|
||||||
|
[ -n "$_po_name" ] || continue
|
||||||
|
# 仍被当前启用的行引用:保留
|
||||||
|
case "$_po_keep" in *" $_po_name "*) continue ;; esac
|
||||||
|
# 没有标记的段不是本工具写的(或旧版本写的):绝不删
|
||||||
|
if [ "$(uci -q get "mwan3.$_po_sec.isp_split" 2>/dev/null)" != "1" ]; then
|
||||||
|
case "$_po_name" in
|
||||||
|
isp_*)
|
||||||
|
log "提示:ipset 段 $_po_sec($_po_name)没有 isp_split 标记,保留不动(旧版本或用户自建)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# 仍被任何 mwan3 规则引用:删了会让 mwan3 渲染失败,只告警
|
||||||
|
case "$_po_refs" in
|
||||||
|
*" $_po_name "*)
|
||||||
|
log "警告:孤儿 ipset 段 $_po_sec($_po_name)仍被 mwan3 规则引用,保留"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if uci -q delete "mwan3.$_po_sec" 2>/dev/null; then
|
||||||
|
log "已清理孤儿 ipset 段 $_po_sec($_po_name)"
|
||||||
|
_po_changed=1
|
||||||
|
else
|
||||||
|
log "警告:清理 ipset 段 $_po_sec 失败,保留"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[ "$_po_changed" = "1" ] && uci -q commit mwan3 2>/dev/null
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 卸载:按 isp_split=1 标记删除所有本工具的 ipset 段。
|
||||||
|
# 不能按"当前 ISP_TABLE 的名字"删:改名/删除的旧段会漏掉,永远清不掉。
|
||||||
|
# 无标记的段一律不碰。
|
||||||
|
_uninstall_ipsets() {
|
||||||
|
_ui_n=0
|
||||||
|
for _ui_sec in $(uci -q show mwan3 2>/dev/null |
|
||||||
|
sed -n 's/^mwan3\.\([^=]*\)=ipset$/\1/p'); do
|
||||||
|
[ "$(uci -q get "mwan3.$_ui_sec.isp_split" 2>/dev/null)" = "1" ] || continue
|
||||||
|
uci -q delete "mwan3.$_ui_sec" 2>/dev/null && _ui_n=$((_ui_n + 1))
|
||||||
|
done
|
||||||
|
uci -q commit mwan3 2>/dev/null
|
||||||
|
[ "$_ui_n" -gt 0 ] &&
|
||||||
|
log "已删除 $_ui_n 个带 isp_split 标记的 ipset 段(含改名/删除的孤儿段)"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
cmd_wire() {
|
cmd_wire() {
|
||||||
_openclash_fakeip_warn
|
_openclash_fakeip_warn
|
||||||
need_nft
|
need_nft
|
||||||
@@ -1651,6 +1765,9 @@ cmd_wire() {
|
|||||||
|
|
||||||
cat "$WORK/mwan3.new" > "$CFG_MWAN3"
|
cat "$WORK/mwan3.new" > "$CFG_MWAN3"
|
||||||
log "规则已注入(备份: $WORK/mwan3.bak)"
|
log "规则已注入(备份: $WORK/mwan3.bak)"
|
||||||
|
# 5. 收敛孤儿 ipset 段:必须放在规则块重写之后 —— 改名时旧规则
|
||||||
|
# 这一刻才消失;若在注入前做,旧规则仍引用旧段,会被误判成"保留"。
|
||||||
|
_prune_orphan_ipsets
|
||||||
/etc/init.d/mwan3 reload
|
/etc/init.d/mwan3 reload
|
||||||
_fallback_counter ||
|
_fallback_counter ||
|
||||||
log "警告:兜底计数规则未安装成功(status 的兜底行会缺失或为旧值),可稍后重跑 isp-split apply"
|
log "警告:兜底计数规则未安装成功(status 的兜底行会缺失或为旧值),可稍后重跑 isp-split apply"
|
||||||
@@ -1748,8 +1865,9 @@ cmd_verify() {
|
|||||||
echo "⚠ DNS 旁路规则缺失(mwan3 重启会清掉运行时插入的规则)"
|
echo "⚠ DNS 旁路规则缺失(mwan3 重启会清掉运行时插入的规则)"
|
||||||
echo " 恢复:isp-split dns (或 isp-split wire)"
|
echo " 恢复:isp-split dns (或 isp-split wire)"
|
||||||
fi
|
fi
|
||||||
if [ "$(nft list chain inet mwan3 mwan3_rules 2>/dev/null | grep -c "counter name")" -eq 0 ] &&
|
# 兜底计数器由 COUNT_FALLBACK 控制,与 DNS_TABLE 无关(B-2)。
|
||||||
[ -n "${DNS_TABLE:-}" ]; then
|
if [ "${COUNT_FALLBACK:-1}" = "1" ] &&
|
||||||
|
[ "$(nft list chain inet mwan3 mwan3_rules 2>/dev/null | grep -c "counter name")" -eq 0 ]; then
|
||||||
echo "⚠ 兜底计数规则缺失(同上)"
|
echo "⚠ 兜底计数规则缺失(同上)"
|
||||||
echo " 恢复:isp-split apply"
|
echo " 恢复:isp-split apply"
|
||||||
fi
|
fi
|
||||||
@@ -1761,6 +1879,23 @@ cmd_verify() {
|
|||||||
|
|
||||||
# ---------------------------------------------------------------- plan (dry-run)
|
# ---------------------------------------------------------------- plan (dry-run)
|
||||||
|
|
||||||
|
# dnsmasq 是否编译了 nftset(域名→nftset 钉线的前置条件,F-5)。
|
||||||
|
# 返回:0=支持,1=不支持,2=没有 dnsmasq。
|
||||||
|
# OpenWrt 基础版 dnsmasq 的编译选项是 no-ipset no-nftset,必须装
|
||||||
|
# dnsmasq-full 才有。这里只检测并提示,不阻断、不改变任何行为。
|
||||||
|
_dnsmasq_nftset() {
|
||||||
|
command -v dnsmasq >/dev/null 2>&1 || return 2
|
||||||
|
_dn_opts=$(dnsmasq --version 2>/dev/null |
|
||||||
|
sed -n 's/^Compile time options:[[:space:]]*//p' | head -1)
|
||||||
|
# 没有 Compile time options 行的老版本无法证明支持,按不支持处理
|
||||||
|
[ -n "$_dn_opts" ] || return 1
|
||||||
|
case " $_dn_opts " in
|
||||||
|
*" no-nftset "*) return 1 ;;
|
||||||
|
*" nftset "* | *" +nftset "*) return 0 ;;
|
||||||
|
esac
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# 只读预演:不写任何文件、不发任何 uci/nft 改动。
|
# 只读预演:不写任何文件、不发任何 uci/nft 改动。
|
||||||
cmd_plan() {
|
cmd_plan() {
|
||||||
_openclash_fakeip_warn
|
_openclash_fakeip_warn
|
||||||
@@ -1813,7 +1948,7 @@ cmd_plan() {
|
|||||||
done
|
done
|
||||||
[ "$_dp_any" = "1" ] || echo " (无)"
|
[ "$_dp_any" = "1" ] || echo " (无)"
|
||||||
echo " 说明: 未启用项不会被 apply 写入;残留的 nft 规则会在下次 wire 重写规则块时移除,"
|
echo " 说明: 未启用项不会被 apply 写入;残留的 nft 规则会在下次 wire 重写规则块时移除,"
|
||||||
echo " mwan3 ipset 配置段与对应 nft 集合会在 uninstall 时清理。"
|
echo " mwan3 ipset 配置段(带 isp_split=1 标记)会在下次 wire 与 uninstall 时清理。"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "dnsmasq confdir(多线路 DNS 片段写入位置):"
|
echo "dnsmasq confdir(多线路 DNS 片段写入位置):"
|
||||||
@@ -1853,6 +1988,24 @@ cmd_plan() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "dnsmasq nftset 能力(域名钉线的前置条件;本版本只检测,不启用钉线):"
|
||||||
|
_dnsmasq_nftset
|
||||||
|
_nf=$?
|
||||||
|
case "$_nf" in
|
||||||
|
0)
|
||||||
|
echo " ✓ 支持 nftset(dnsmasq 编译选项含 nftset)"
|
||||||
|
;;
|
||||||
|
1)
|
||||||
|
echo " ⚠ 不支持 nftset(dnsmasq 编译选项为 no-nftset 或缺少该选项)"
|
||||||
|
echo " 域名钉线不可用;多线路 DNS 的 server=/域名/IP@接口 不受影响。"
|
||||||
|
echo " 需要域名→nftset 时请安装 dnsmasq-full。"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo " ⚠ 未找到 dnsmasq,无法检测 nftset 能力"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "将会写入的 nft 集合声明(每个启用的运营商一个):"
|
echo "将会写入的 nft 集合声明(每个启用的运营商一个):"
|
||||||
_p3() {
|
_p3() {
|
||||||
@@ -2173,8 +2326,10 @@ cmd_status() {
|
|||||||
grep -oE "packets [0-9]+ bytes [0-9]+" | head -1)
|
grep -oE "packets [0-9]+ bytes [0-9]+" | head -1)
|
||||||
_fp=$(echo "$_fb" | awk '{print $2}')
|
_fp=$(echo "$_fb" | awk '{print $2}')
|
||||||
_fb_b=$(echo "$_fb" | awk '{print $4}')
|
_fb_b=$(echo "$_fb" | awk '{print $4}')
|
||||||
|
# 与其余行走同一个 _human 换算,否则这一列是裸字节数、
|
||||||
|
# 既不对齐也没有单位(B-3)。--json 里的 bytes 保持纯数字。
|
||||||
printf '%-14s %-10s %10s %12s %10s %s\n' \
|
printf '%-14s %-10s %10s %12s %10s %s\n' \
|
||||||
"兜底" "-" "-" "${_fp:-0}" "${_fb_b:-0}" "未命中集合"
|
"兜底" "-" "-" "${_fp:-0}" "$(_human "${_fb_b:-0}")" "未命中集合"
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
echo "注: 命中包/流量为连接首包统计(ct state new;后续包由 conntrack 恢复标记,不再经过规则链)。"
|
echo "注: 命中包/流量为连接首包统计(ct state new;后续包由 conntrack 恢复标记,不再经过规则链)。"
|
||||||
@@ -3035,6 +3190,12 @@ _conf_val() {
|
|||||||
' "${2:-$CONF}"
|
' "${2:-$CONF}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 取配置表的值并删掉注释行。conf_get / apply 直接读文件,不能只依赖入口
|
||||||
|
# 那次清理(B-1)。必须先整行删注释、再按空白展开,顺序不能反。
|
||||||
|
_conf_table() {
|
||||||
|
_strip_comments "$(_conf_val "$1")"
|
||||||
|
}
|
||||||
|
|
||||||
conf_get() {
|
conf_get() {
|
||||||
[ -f "$CONF" ] || die "找不到 $CONF"
|
[ -f "$CONF" ] || die "找不到 $CONF"
|
||||||
printf 'dns_mode\t%s\n' "$(_conf_val DNS_MODE)"
|
printf 'dns_mode\t%s\n' "$(_conf_val DNS_MODE)"
|
||||||
@@ -3042,11 +3203,11 @@ conf_get() {
|
|||||||
"$(uci -q show mwan3 2>/dev/null | sed -n 's/^mwan3\.\([^=]*\)=policy$/\1/p' | tr '\n' ' ')"
|
"$(uci -q show mwan3 2>/dev/null | sed -n 's/^mwan3\.\([^=]*\)=policy$/\1/p' | tr '\n' ' ')"
|
||||||
# 值支持两种书写格式:多行(每行一条)或单行空格分隔。
|
# 值支持两种书写格式:多行(每行一条)或单行空格分隔。
|
||||||
# 先把所有空白折叠成换行,再按冒号拆字段——两种格式统一处理。
|
# 先把所有空白折叠成换行,再按冒号拆字段——两种格式统一处理。
|
||||||
_conf_val ISP_TABLE | tr -s ' \t' '\n' |
|
_conf_table ISP_TABLE | tr -s ' \t' '\n' |
|
||||||
awk -F: 'NF >= 4 { printf "isp\t%s\t%s\t%s\t%s\n", $1, $2, $3, $4 }'
|
awk -F: 'NF >= 4 { printf "isp\t%s\t%s\t%s\t%s\n", $1, $2, $3, $4 }'
|
||||||
_conf_val DNS_TABLE | tr -s ' \t' '\n' |
|
_conf_table DNS_TABLE | tr -s ' \t' '\n' |
|
||||||
awk -F: 'NF >= 2 { printf "dns\t%s\t%s\n", $1, $2 }'
|
awk -F: 'NF >= 2 { printf "dns\t%s\t%s\n", $1, $2 }'
|
||||||
_conf_val DOMAIN_SPLIT | tr -s ' \t' '\n' |
|
_conf_table DOMAIN_SPLIT | tr -s ' \t' '\n' |
|
||||||
awk -F: 'NF >= 2 { printf "domain\t%s\t%s\n", $1, $2 }'
|
awk -F: 'NF >= 2 { printf "domain\t%s\t%s\n", $1, $2 }'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3103,6 +3264,11 @@ _row_check() {
|
|||||||
|
|
||||||
# 直接对一整行做校验(不拆字段的调用点用)
|
# 直接对一整行做校验(不拆字段的调用点用)
|
||||||
_row_check_row() {
|
_row_check_row() {
|
||||||
|
# 双保险(B-1):入口已删注释行,这里再挡一次带前导空白的 # 行,
|
||||||
|
# 避免将来新增调用点绕过入口清理时又把注释当数据。
|
||||||
|
case "$1" in
|
||||||
|
'#'* | [[:space:]]*'#'*) return 0 ;;
|
||||||
|
esac
|
||||||
_rr_ifs=$IFS
|
_rr_ifs=$IFS
|
||||||
IFS=':'
|
IFS=':'
|
||||||
set -- $1
|
set -- $1
|
||||||
@@ -3134,6 +3300,12 @@ _valid_ipv4() {
|
|||||||
_conf_validate() {
|
_conf_validate() {
|
||||||
_key=$1
|
_key=$1
|
||||||
_val=$2
|
_val=$2
|
||||||
|
# 注释行不参与校验(B-1):整行删掉后再按空白拆字段。清理必须发生在
|
||||||
|
# 空白展开之前,否则 "# 说明:xxx" 会被拆成 "#" 和 "说明:xxx" 两段。
|
||||||
|
# 这里只改局部副本,写回文件的内容仍保留用户注释。
|
||||||
|
case "$_key" in
|
||||||
|
ISP_TABLE | DNS_TABLE | DOMAIN_SPLIT) _val=$(_strip_comments "$_val") ;;
|
||||||
|
esac
|
||||||
case "$_val" in
|
case "$_val" in
|
||||||
*'$'* | *'`'* | *'"'* | *"'"* | *'\'* | *';'* | *'|'*)
|
*'$'* | *'`'* | *'"'* | *"'"* | *'\'* | *';'* | *'|'*)
|
||||||
die "配置值含不允许的字符(\$ \` \" ' \\ ; |)"
|
die "配置值含不允许的字符(\$ \` \" ' \\ ; |)"
|
||||||
@@ -3684,17 +3856,8 @@ cmd_uninstall() {
|
|||||||
cat "$WORK/mwan3.new" > "$CFG_MWAN3"
|
cat "$WORK/mwan3.new" > "$CFG_MWAN3"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for row in $ISP_TABLE; do
|
# 按标记删,而不是按当前表名:改名/删除的孤儿段也要清掉(B-4)。
|
||||||
_old_ifs=$IFS
|
_uninstall_ipsets
|
||||||
IFS=':'
|
|
||||||
set -- $row
|
|
||||||
IFS=$_old_ifs
|
|
||||||
case "$row" in \#*) continue ;; esac
|
|
||||||
[ $# -ge 2 ] || continue
|
|
||||||
_valid_name "$2" || continue
|
|
||||||
uci -q delete "mwan3.ipset_$2" 2>/dev/null
|
|
||||||
done
|
|
||||||
uci -q commit mwan3
|
|
||||||
/etc/init.d/mwan3 reload >/dev/null 2>&1
|
/etc/init.d/mwan3 reload >/dev/null 2>&1
|
||||||
|
|
||||||
# 恢复 dnsmasq confdir 原值(状态文件在 $BASE 里,必须先恢复再删目录)
|
# 恢复 dnsmasq confdir 原值(状态文件在 $BASE 里,必须先恢复再删目录)
|
||||||
|
|||||||
@@ -203,6 +203,13 @@ function renderListeners(s, uciconfig, isClient) {
|
|||||||
o.depends('type', 'mieru');
|
o.depends('type', 'mieru');
|
||||||
o.modalonly = true;
|
o.modalonly = true;
|
||||||
|
|
||||||
|
o = s.taboption('field_general', form.Value, 'mieru_tcp_idle_timeout', _('TCP idle timeout'),
|
||||||
|
_('In seconds.'), _('Minimum value is $s.').format('60'));
|
||||||
|
o.placeholder = '1800';
|
||||||
|
o.validate = hm.validateTimeDuration;
|
||||||
|
o.depends('type', 'mieru');
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
o = s.taboption('field_general', form.Value, 'mieru_traffic_pattern', _('Traffic pattern'),
|
o = s.taboption('field_general', form.Value, 'mieru_traffic_pattern', _('Traffic pattern'),
|
||||||
_('A base64 string is used to fine-tune network behavior.<br/>Please refer to the <a target="_blank" href="%s" rel="noreferrer noopener">document</a>.')
|
_('A base64 string is used to fine-tune network behavior.<br/>Please refer to the <a target="_blank" href="%s" rel="noreferrer noopener">document</a>.')
|
||||||
.format('https://github.com/enfein/mieru/blob/main/docs/traffic-pattern.md'));
|
.format('https://github.com/enfein/mieru/blob/main/docs/traffic-pattern.md'));
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -265,6 +265,7 @@ export function parseListener(cfg) {
|
|||||||
transport: cfg.mieru_transport,
|
transport: cfg.mieru_transport,
|
||||||
"traffic-pattern": cfg.mieru_traffic_pattern,
|
"traffic-pattern": cfg.mieru_traffic_pattern,
|
||||||
"user-hint-is-mandatory": strToBool(cfg.mieru_user_hint_is_mandatory),
|
"user-hint-is-mandatory": strToBool(cfg.mieru_user_hint_is_mandatory),
|
||||||
|
"tcp-idle-timeout": durationToSecond(cfg.mieru_tcp_idle_timeout),
|
||||||
|
|
||||||
/* Sudoku */
|
/* Sudoku */
|
||||||
key: cfg.sudoku_key,
|
key: cfg.sudoku_key,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-isp-split
|
PKG_NAME:=luci-app-isp-split
|
||||||
PKG_VERSION:=0.2.1
|
PKG_VERSION:=0.2.2
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=3
|
||||||
PKG_LICENSE:=MIT
|
PKG_LICENSE:=MIT
|
||||||
PKG_LICENSE_FILES:=LICENSE
|
PKG_LICENSE_FILES:=LICENSE
|
||||||
PKG_MAINTAINER:=jihebube <jihebube@users.noreply.github.com>
|
PKG_MAINTAINER:=jihebube <jihebube@users.noreply.github.com>
|
||||||
|
|||||||
@@ -131,6 +131,10 @@ return view.extend({
|
|||||||
out.split('\n').forEach(function(line) {
|
out.split('\n').forEach(function(line) {
|
||||||
if (!line)
|
if (!line)
|
||||||
return;
|
return;
|
||||||
|
/* 注释行不是数据行(B-1)。conf get 已在 shell 侧过滤,
|
||||||
|
这里再挡一次,避免旧版脚本或手工拼接的输出被渲染成红行。 */
|
||||||
|
if (/^\s*#/.test(line))
|
||||||
|
return;
|
||||||
var f = line.split('\t');
|
var f = line.split('\t');
|
||||||
if (f[0] === 'dns_mode')
|
if (f[0] === 'dns_mode')
|
||||||
model.mode = (f[1] || 'bind').trim();
|
model.mode = (f[1] || 'bind').trim();
|
||||||
|
|||||||
@@ -354,7 +354,13 @@ return view.extend({
|
|||||||
box.removeChild(box.firstChild);
|
box.removeChild(box.firstChild);
|
||||||
|
|
||||||
var rows = (this.status || []).filter(function(r) {
|
var rows = (this.status || []).filter(function(r) {
|
||||||
return r && r.set !== '兜底';
|
/* B-1:注释行不是运营商行。shell 侧已过滤,这里兜底,
|
||||||
|
防止旧脚本/手工数据在总览页多出一张卡片。 */
|
||||||
|
if (!r || r.set === '兜底')
|
||||||
|
return false;
|
||||||
|
if (/^\s*#/.test(String(r.set || '')) || /^\s*#/.test(String(r.src || '')))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!rows.length) {
|
if (!rows.length) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-open-box
|
PKG_NAME:=luci-app-open-box
|
||||||
PKG_VERSION:=0.1.370
|
PKG_VERSION:=0.1.371
|
||||||
PKG_RELEASE:=50
|
PKG_RELEASE:=51
|
||||||
|
|
||||||
PKG_MAINTAINER:=liandu2024
|
PKG_MAINTAINER:=liandu2024
|
||||||
PKG_LICENSE:=GPL-3.0-or-later
|
PKG_LICENSE:=GPL-3.0-or-later
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-passwall
|
PKG_NAME:=luci-app-passwall
|
||||||
PKG_VERSION:=26.10.22
|
PKG_VERSION:=26.10.29
|
||||||
PKG_RELEASE:=353
|
PKG_RELEASE:=354
|
||||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS:= \
|
PKG_CONFIG_DEPENDS:= \
|
||||||
|
|||||||
@@ -246,9 +246,9 @@ end
|
|||||||
|
|
||||||
function UrlEncode(szText)
|
function UrlEncode(szText)
|
||||||
if type(szText) ~= "string" then return "" end
|
if type(szText) ~= "string" then return "" end
|
||||||
return szText:gsub("([^%w%-_%.%~])", function(c)
|
return (szText:gsub("([^%w%-_%.%~])", function(c)
|
||||||
return string.format("%%%02X", string.byte(c))
|
return string.format("%%%02X", string.byte(c))
|
||||||
end)
|
end))
|
||||||
end
|
end
|
||||||
|
|
||||||
function UrlDecode(szText)
|
function UrlDecode(szText)
|
||||||
@@ -1401,9 +1401,11 @@ function to_download_progress(app_name, task_id, total_size)
|
|||||||
|
|
||||||
total_size = tonumber(total_size) or 0
|
total_size = tonumber(total_size) or 0
|
||||||
local tmp_file = "/tmp/" .. app_name .. "_download." .. task_id
|
local tmp_file = "/tmp/" .. app_name .. "_download." .. task_id
|
||||||
local downloaded = tonumber(fs.stat(tmp_file, "size")) or 0
|
local downloaded
|
||||||
if app_name == appname then
|
if app_name == appname then
|
||||||
downloaded = (tonumber(fs.stat(tmp_file .. "1", "size")) or 0) + (tonumber(fs.stat(tmp_file .. "2", "size")) or 0)
|
downloaded = (tonumber((fs.stat(tmp_file .. "1", "size"))) or 0) + (tonumber((fs.stat(tmp_file .. "2", "size"))) or 0)
|
||||||
|
else
|
||||||
|
downloaded = tonumber((fs.stat(tmp_file, "size"))) or 0
|
||||||
end
|
end
|
||||||
local percent
|
local percent
|
||||||
if total_size > 0 then
|
if total_size > 0 then
|
||||||
@@ -1558,7 +1560,7 @@ function get_version()
|
|||||||
end
|
end
|
||||||
version = (version or ""):match("^%s*(.-)%s*$")
|
version = (version or ""):match("^%s*(.-)%s*$")
|
||||||
-- Normalize APK's -rN release notation while retaining the release number.
|
-- Normalize APK's -rN release notation while retaining the release number.
|
||||||
return version:gsub("%-r(%d+)$", "-%1")
|
return (version:gsub("%-r(%d+)$", "-%1"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function to_check_self()
|
function to_check_self()
|
||||||
|
|||||||
@@ -259,6 +259,17 @@ local com = self.com
|
|||||||
detail.textContent = installingNotice;
|
detail.textContent = installingNotice;
|
||||||
// Read the tiny result file even if rpcd restart invalidates the session.
|
// Read the tiny result file even if rpcd restart invalidates the session.
|
||||||
var pending = false, finished = false;
|
var pending = false, finished = false;
|
||||||
|
function finishInstall(code) {
|
||||||
|
if (finished) return;
|
||||||
|
finished = true;
|
||||||
|
clearInterval(timer);
|
||||||
|
removePageNotice(appname);
|
||||||
|
if (code) onRequestError(btn, updateFailedText);
|
||||||
|
else {
|
||||||
|
window.onbeforeunload = undefined;
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
var timer = setInterval(function() {
|
var timer = setInterval(function() {
|
||||||
if (pending) return;
|
if (pending) return;
|
||||||
pending = true;
|
pending = true;
|
||||||
@@ -271,27 +282,28 @@ local com = self.com
|
|||||||
if (finished) return;
|
if (finished) return;
|
||||||
var json;
|
var json;
|
||||||
try { json = JSON.parse(xhr.responseText); } catch (e) { return; }
|
try { json = JSON.parse(xhr.responseText); } catch (e) { return; }
|
||||||
if (typeof json.code !== 'number') return;
|
if (!json || typeof json.code !== 'number') return;
|
||||||
finished = true;
|
finishInstall(json.code);
|
||||||
clearInterval(timer);
|
|
||||||
removePageNotice(appname);
|
|
||||||
if (json.code) onRequestError(btn, updateFailedText);
|
|
||||||
else {
|
|
||||||
window.onbeforeunload = undefined;
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
XHR.post(url, {token: tokenStr, task: 'install', id: id,
|
// Legacy LuCI has no static XHR.post(), and its instance callback has no JSON argument.
|
||||||
force: appInfoList[appname].has_update ? '0' : '1'}, function(x, json) {
|
var request = new XMLHttpRequest();
|
||||||
if (!finished && json && json.code) {
|
request.open('POST', url, true);
|
||||||
finished = true;
|
request.timeout = 300000;
|
||||||
clearInterval(timer);
|
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
removePageNotice(appname);
|
request.onerror = request.ontimeout = function() { finishInstall(1); };
|
||||||
onRequestError(btn, updateFailedText);
|
request.onload = function() {
|
||||||
|
if (finished) return;
|
||||||
|
var json;
|
||||||
|
try { json = JSON.parse(request.responseText); } catch (e) {}
|
||||||
|
if (request.status < 200 || request.status >= 300 || !json ||
|
||||||
|
typeof json.code !== 'number' || json.code) {
|
||||||
|
finishInstall(1);
|
||||||
}
|
}
|
||||||
}, 300);
|
};
|
||||||
|
request.send('token=' + encodeURIComponent(tokenStr) + '&task=install&id=' + encodeURIComponent(id) +
|
||||||
|
'&force=' + (appInfoList[appname].has_update ? '0' : '1'));
|
||||||
}
|
}
|
||||||
|
|
||||||
//]]>
|
//]]>
|
||||||
|
|||||||
@@ -300,89 +300,36 @@ table td, .table .td {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-dropdown {
|
.pw-group-select {
|
||||||
position: relative;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 2px;
|
|
||||||
width: 180px;
|
width: 180px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
font-size: 13px;
|
flex: 0 0 180px;
|
||||||
background: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-display {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-display:hover {
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-list {
|
|
||||||
position: absolute;
|
|
||||||
top: calc(100% + 2px);
|
|
||||||
left: -1px;
|
|
||||||
width: calc(100% + 2px);
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 2px;
|
|
||||||
border-top: none;
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.15);
|
|
||||||
background: #fff;
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
max-height: 200px;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
z-index: 100;
|
|
||||||
box-sizing: border-box;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item {
|
|
||||||
padding: 4px 8px;
|
|
||||||
line-height: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item.selected {
|
|
||||||
background-color: #1e90ff;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.create-item-input::placeholder {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item.custom-input input {
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 3px;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 20px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow-down-small {
|
.pw-group-select > .cbi-dropdown,
|
||||||
width: 0;
|
.pw-group-select > .cbi-input-text,
|
||||||
height: 0;
|
.pw-group-select > .cbi-input-select {
|
||||||
border-left: 4px solid transparent;
|
width: 100% !important;
|
||||||
border-right: 4px solid transparent;
|
min-width: 0 !important;
|
||||||
border-top: 5px solid #555;
|
max-width: 100% !important;
|
||||||
display: inline-block;
|
height: 28px !important;
|
||||||
vertical-align: middle;
|
min-height: 28px !important;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pw-group-select > .cbi-dropdown > ul:not(.dropdown) > li,
|
||||||
|
.pw-group-select > .cbi-dropdown > .open {
|
||||||
|
height: 26px;
|
||||||
|
min-height: 0;
|
||||||
|
line-height: 26px;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -1077,97 +1024,103 @@ table td, .table .td {
|
|||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
//Pop-up logic
|
//Pop-up logic
|
||||||
|
|
||||||
// Custom group dropdown list events
|
function normalize_group_name(value, groups) {
|
||||||
function dropdown_list_fun(div_id) {
|
const name = value.trim();
|
||||||
const dropdown = document.getElementById(div_id);
|
return groups.find(group => group.toLowerCase() === name.toLowerCase()) || name;
|
||||||
if (!dropdown) return;
|
}
|
||||||
|
|
||||||
const display = dropdown.querySelector(".selected-display");
|
function init_group_dropdown(div_id) {
|
||||||
const displayText = display.querySelector(".text");
|
const container = document.getElementById(div_id);
|
||||||
const list = dropdown.querySelector(".dropdown-list");
|
if (!container || container._group_ready || container._group_loading) return;
|
||||||
const hidden = dropdown.querySelector('input[type="hidden"]');
|
const tabs = document.querySelector("#node_list .cbi-tabmenu");
|
||||||
const input = dropdown.querySelector(".create-item-input");
|
if (!tabs) {
|
||||||
|
setTimeout(() => init_group_dropdown(div_id), 50);
|
||||||
display.addEventListener("click", function() {
|
return;
|
||||||
list.style.display = list.style.display === "none" ? "block" : "none";
|
|
||||||
input.value = "";
|
|
||||||
//input.focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
function selectItem(li) {
|
|
||||||
list.querySelectorAll(".dropdown-item").forEach(function(el){
|
|
||||||
el.classList.remove("selected");
|
|
||||||
});
|
|
||||||
li.classList.add("selected");
|
|
||||||
hidden.value = li.dataset.value;
|
|
||||||
displayText.textContent = li.dataset.value || "<%:default%>";
|
|
||||||
list.style.display = "none";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list.addEventListener("click", function(e){
|
const choices = { "default": "<%:default%>" };
|
||||||
const li = e.target.closest(".dropdown-item");
|
const groups = ["default"];
|
||||||
if (!li || li.classList.contains("custom-input")) return;
|
tabs.querySelectorAll("li[group_name]").forEach(function(tab) {
|
||||||
selectItem(li);
|
const group = tab.getAttribute("group_name");
|
||||||
});
|
if (group !== "default" && !groups.includes(group)) {
|
||||||
|
choices[group] = group;
|
||||||
input.addEventListener("keydown", function(e){
|
groups.push(group);
|
||||||
const isEnter = e.key === "Enter" || e.keyCode === 13;
|
|
||||||
if (!isEnter) return;
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const val = input.value.trim();
|
|
||||||
if (!val) return;
|
|
||||||
|
|
||||||
if (val.toLowerCase() === "default") {
|
|
||||||
const emptyLi = Array.from(list.querySelectorAll(".dropdown-item"))
|
|
||||||
.find(function(el){ return !el.dataset.value; });
|
|
||||||
if (emptyLi) selectItem(emptyLi);
|
|
||||||
input.value = "";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
let li = Array.from(list.querySelectorAll(".dropdown-item")).find(function(el){
|
const input = container.querySelector("input");
|
||||||
return el.dataset.value && el.dataset.value.toLowerCase() === val.toLowerCase();
|
<% if is_js_luci then -%>
|
||||||
|
container._group_loading = true;
|
||||||
|
L.require("ui").then(function(ui) {
|
||||||
|
const widget = new ui.Dropdown("default", choices, {
|
||||||
|
id: input.id,
|
||||||
|
name: input.name,
|
||||||
|
multiple: false,
|
||||||
|
optional: false,
|
||||||
|
create: true,
|
||||||
|
sort: groups,
|
||||||
|
custom_placeholder: "-- <%:custom%> --"
|
||||||
});
|
});
|
||||||
if (!li) {
|
const dropdown = widget.render();
|
||||||
li = document.createElement("li");
|
// Normalize before LuCI handles Enter and replaces its single custom item.
|
||||||
li.className = "dropdown-item";
|
dropdown.addEventListener("keydown", function(e) {
|
||||||
li.dataset.value = val;
|
if (!e.target.classList.contains("create-item-input") ||
|
||||||
li.textContent = val;
|
(e.key !== "Enter" && e.keyCode !== 13)) return;
|
||||||
list.insertBefore(li, input.parentNode);
|
if (e.isComposing) {
|
||||||
}
|
e.stopPropagation();
|
||||||
|
return;
|
||||||
input.value = "";
|
}
|
||||||
selectItem(li);
|
const values = Array.from(dropdown.querySelectorAll("ul.dropdown > li[data-value]:not([unselectable])"), li => li.dataset.value);
|
||||||
});
|
e.target.value = normalize_group_name(e.target.value, values);
|
||||||
// Read group names from tab
|
if (!e.target.value) {
|
||||||
function InsertGroup(list, input) {
|
e.preventDefault();
|
||||||
const tabs = document.querySelectorAll(".cbi-tabmenu li");
|
e.stopPropagation();
|
||||||
if (!tabs.length) {
|
}
|
||||||
setTimeout(() => InsertGroup(list, input), 50);
|
}, true);
|
||||||
return;
|
const customInput = dropdown.querySelector(".create-item-input");
|
||||||
}
|
// The custom input row must not shadow a group named "-".
|
||||||
|
customInput.parentNode.removeAttribute("data-value");
|
||||||
tabs.forEach(function(li){
|
customInput.setAttribute("inputmode", "text");
|
||||||
const group = li.id.split('.').pop();
|
customInput.setAttribute("enterkeyhint", "done");
|
||||||
if(group === "default") return;
|
dropdown.addEventListener("cbi-dropdown-change", function() {
|
||||||
if(Array.from(list.querySelectorAll(".dropdown-item")).some(el => el.dataset.value === group)) return;
|
customInput.value = "";
|
||||||
const newLi = document.createElement("li");
|
|
||||||
newLi.className = "dropdown-item";
|
|
||||||
newLi.dataset.value = group;
|
|
||||||
newLi.textContent = group;
|
|
||||||
list.insertBefore(newLi, input.parentNode);
|
|
||||||
});
|
});
|
||||||
}
|
container.replaceChild(dropdown, input);
|
||||||
InsertGroup(list, input);
|
container._group_widget = widget;
|
||||||
|
container._group_ready = true;
|
||||||
// Automatically collapses when clicking on the outside.
|
container._group_loading = false;
|
||||||
document.addEventListener("click", function(e) {
|
}).catch(function(error) {
|
||||||
if (!dropdown.contains(e.target)) {
|
container._group_loading = false;
|
||||||
list.style.display = "none";
|
console.error("Group dropdown init failed:", error);
|
||||||
|
alert("<%:Error%>");
|
||||||
|
});
|
||||||
|
<% else -%>
|
||||||
|
input.disabled = false;
|
||||||
|
input.addEventListener("blur", function() {
|
||||||
|
input.value = normalize_group_name(input.value, groups) || "default";
|
||||||
|
});
|
||||||
|
input.addEventListener("keydown", function(e) {
|
||||||
|
if ((e.key === "Enter" || e.keyCode === 13) && !e.isComposing) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
input.blur();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
cbi_combobox_init(input.id, choices, "<%:default%>", "-- <%:custom%> --");
|
||||||
|
container._group_ready = true;
|
||||||
|
<% end -%>
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_group_value(div_id) {
|
||||||
|
const container = document.getElementById(div_id);
|
||||||
|
return (container._group_widget ? container._group_widget.getValue() : container.querySelector("input").value) || "default";
|
||||||
|
}
|
||||||
|
|
||||||
|
function close_group_dropdown(div_id) {
|
||||||
|
const container = document.getElementById(div_id);
|
||||||
|
const dropdown = container.querySelector(".cbi-dropdown[open]");
|
||||||
|
if (dropdown) dropdown.dispatchEvent(new CustomEvent("cbi-dropdown-close"));
|
||||||
|
const input = container.querySelector(".create-item-input");
|
||||||
|
if (input) input.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBg(el) {
|
function getBg(el) {
|
||||||
@@ -1187,20 +1140,18 @@ table td, .table .td {
|
|||||||
const addLinkDiv = document.getElementById("add_link_div");
|
const addLinkDiv = document.getElementById("add_link_div");
|
||||||
addLinkDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
addLinkDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
||||||
addLinkDiv.style.display = "block";
|
addLinkDiv.style.display = "block";
|
||||||
if (!addLinkDiv._dropdown_inited) {
|
init_group_dropdown("addlink_group_custom");
|
||||||
addLinkDiv._dropdown_inited = true;
|
|
||||||
dropdown_list_fun("addlink_group_custom");
|
|
||||||
}
|
|
||||||
document.getElementById("nodes_link").focus();
|
document.getElementById("nodes_link").focus();
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
|
close_group_dropdown("addlink_group_custom");
|
||||||
document.getElementById('modal-mask').style.display = 'none';
|
document.getElementById('modal-mask').style.display = 'none';
|
||||||
document.getElementById("add_link_div").style.display = "none";
|
document.getElementById("add_link_div").style.display = "none";
|
||||||
document.body.classList.remove('modal-open');
|
document.body.classList.remove('modal-open');
|
||||||
},
|
},
|
||||||
add_node() {
|
add_node() {
|
||||||
let nodes_link = document.getElementById("nodes_link").value;
|
let nodes_link = document.getElementById("nodes_link").value;
|
||||||
const group = (document.querySelector('#addlink_group_custom input[type="hidden"]')?.value || "default");
|
const group = get_group_value("addlink_group_custom");
|
||||||
nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").replace(/<[^>]*>/g, '').trim();
|
nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").replace(/<[^>]*>/g, '').trim();
|
||||||
if (nodes_link != "") {
|
if (nodes_link != "") {
|
||||||
nodes_link = decodeIfBase64(nodes_link);
|
nodes_link = decodeIfBase64(nodes_link);
|
||||||
@@ -1279,23 +1230,21 @@ table td, .table .td {
|
|||||||
const reassignGroupDiv = document.getElementById("reassign_group_div");
|
const reassignGroupDiv = document.getElementById("reassign_group_div");
|
||||||
reassignGroupDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
reassignGroupDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
||||||
reassignGroupDiv.style.display = "block";
|
reassignGroupDiv.style.display = "block";
|
||||||
if (!reassignGroupDiv._dropdown_inited) {
|
init_group_dropdown("reassign_group_custom");
|
||||||
reassignGroupDiv._dropdown_inited = true;
|
|
||||||
dropdown_list_fun("reassign_group_custom");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
alert("<%:You no select nodes !%>");
|
alert("<%:You no select nodes !%>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
|
close_group_dropdown("reassign_group_custom");
|
||||||
document.getElementById('modal-mask').style.display = 'none';
|
document.getElementById('modal-mask').style.display = 'none';
|
||||||
document.getElementById("reassign_group_div").style.display = "none";
|
document.getElementById("reassign_group_div").style.display = "none";
|
||||||
document.body.classList.remove('modal-open');
|
document.body.classList.remove('modal-open');
|
||||||
},
|
},
|
||||||
action() {
|
action() {
|
||||||
const ids = [];
|
const ids = [];
|
||||||
const group = (document.querySelector('#reassign_group_custom input[type="hidden"]')?.value || "default");
|
const group = get_group_value("reassign_group_custom");
|
||||||
const visibleContainer = document.querySelector('#cbi-passwall-nodes > .cbi-tabcontainer[style*="display:block"], #cbi-passwall-nodes > .cbi-tabcontainer[style*="display: block"]');
|
const visibleContainer = document.querySelector('#cbi-passwall-nodes > .cbi-tabcontainer[style*="display:block"], #cbi-passwall-nodes > .cbi-tabcontainer[style*="display: block"]');
|
||||||
if (!visibleContainer) return;
|
if (!visibleContainer) return;
|
||||||
const doms = visibleContainer.getElementsByClassName("nodes_select");
|
const doms = visibleContainer.getElementsByClassName("nodes_select");
|
||||||
@@ -1742,19 +1691,9 @@ table td, .table .td {
|
|||||||
</div>
|
</div>
|
||||||
<div class="value-custom">
|
<div class="value-custom">
|
||||||
<div class="value-field-custom">
|
<div class="value-field-custom">
|
||||||
<label class="value-title-custom" for="addlink_group_custom"><%:Group Name%></label>
|
<label class="value-title-custom" for="addlink_group"><%:Group Name%></label>
|
||||||
<div id="addlink_group_custom" class="custom-dropdown">
|
<div id="addlink_group_custom" class="pw-group-select">
|
||||||
<div class="selected-display">
|
<input id="addlink_group" name="addlink_group" class="cbi-input-text" type="text" value="default" disabled>
|
||||||
<span class="text"><%:default%></span>
|
|
||||||
<span class="arrow-down-small"></span>
|
|
||||||
</div>
|
|
||||||
<ul class="dropdown-list" style="display:none;">
|
|
||||||
<li class="dropdown-item selected" data-value=""><%:default%></li>
|
|
||||||
<li class="dropdown-item custom-input">
|
|
||||||
<input type="text" placeholder="-- <%:custom%> --" class="create-item-input" inputmode="text" enterkeyhint="done">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<input type="hidden" name="addlink_group" value="">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1770,19 +1709,9 @@ table td, .table .td {
|
|||||||
<h3><%:Reassign Node Group%></h3>
|
<h3><%:Reassign Node Group%></h3>
|
||||||
<div class="value-custom">
|
<div class="value-custom">
|
||||||
<div class="value-field-custom">
|
<div class="value-field-custom">
|
||||||
<label class="value-title-custom" for="reassign_group_custom"><%:Group Name%></label>
|
<label class="value-title-custom" for="to_group"><%:Group Name%></label>
|
||||||
<div id="reassign_group_custom" class="custom-dropdown">
|
<div id="reassign_group_custom" class="pw-group-select">
|
||||||
<div class="selected-display">
|
<input id="to_group" name="to_group" class="cbi-input-text" type="text" value="default" disabled>
|
||||||
<span class="text"><%:default%></span>
|
|
||||||
<span class="arrow-down-small"></span>
|
|
||||||
</div>
|
|
||||||
<ul class="dropdown-list" style="display:none;">
|
|
||||||
<li class="dropdown-item selected" data-value=""><%:default%></li>
|
|
||||||
<li class="dropdown-item custom-input">
|
|
||||||
<input type="text" placeholder="-- <%:custom%> --" class="create-item-input" inputmode="text" enterkeyhint="done">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<input type="hidden" name="to_group" value="">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -36,12 +36,7 @@
|
|||||||
101.125.6.0/24
|
101.125.6.0/24
|
||||||
101.126.0.0/18
|
101.126.0.0/18
|
||||||
101.126.128.0/19
|
101.126.128.0/19
|
||||||
101.126.172.0/22
|
101.126.168.0/21
|
||||||
101.126.176.0/20
|
|
||||||
101.126.192.0/19
|
|
||||||
101.126.228.0/22
|
|
||||||
101.126.232.0/21
|
|
||||||
101.126.240.0/20
|
|
||||||
101.126.64.0/19
|
101.126.64.0/19
|
||||||
101.126.96.0/20
|
101.126.96.0/20
|
||||||
101.128.0.0/22
|
101.128.0.0/22
|
||||||
@@ -132,6 +127,8 @@
|
|||||||
101.96.142.0/23
|
101.96.142.0/23
|
||||||
101.96.144.0/20
|
101.96.144.0/20
|
||||||
101.96.192.0/18
|
101.96.192.0/18
|
||||||
|
102.216.81.0/24
|
||||||
|
102.216.82.0/24
|
||||||
103.1.168.0/22
|
103.1.168.0/22
|
||||||
103.1.20.0/22
|
103.1.20.0/22
|
||||||
103.1.8.0/22
|
103.1.8.0/22
|
||||||
@@ -222,6 +219,7 @@
|
|||||||
103.140.14.0/23
|
103.140.14.0/23
|
||||||
103.141.10.0/23
|
103.141.10.0/23
|
||||||
103.142.234.0/23
|
103.142.234.0/23
|
||||||
|
103.142.82.0/24
|
||||||
103.142.96.0/23
|
103.142.96.0/23
|
||||||
103.143.16.0/22
|
103.143.16.0/22
|
||||||
103.143.228.0/23
|
103.143.228.0/23
|
||||||
@@ -301,9 +299,6 @@
|
|||||||
103.197.0.0/22
|
103.197.0.0/22
|
||||||
103.197.228.0/22
|
103.197.228.0/22
|
||||||
103.198.124.0/22
|
103.198.124.0/22
|
||||||
103.198.216.0/21
|
|
||||||
103.198.224.0/20
|
|
||||||
103.198.244.0/22
|
|
||||||
103.198.60.0/22
|
103.198.60.0/22
|
||||||
103.2.108.0/22
|
103.2.108.0/22
|
||||||
103.2.208.0/22
|
103.2.208.0/22
|
||||||
@@ -374,6 +369,7 @@
|
|||||||
103.217.184.0/21
|
103.217.184.0/21
|
||||||
103.217.192.0/20
|
103.217.192.0/20
|
||||||
103.218.216.0/22
|
103.218.216.0/22
|
||||||
|
103.218.92.0/22
|
||||||
103.219.100.0/23
|
103.219.100.0/23
|
||||||
103.219.176.0/22
|
103.219.176.0/22
|
||||||
103.219.184.0/22
|
103.219.184.0/22
|
||||||
@@ -394,7 +390,7 @@
|
|||||||
103.222.176.0/21
|
103.222.176.0/21
|
||||||
103.222.184.0/22
|
103.222.184.0/22
|
||||||
103.222.216.0/22
|
103.222.216.0/22
|
||||||
103.222.33.0/24
|
103.222.32.0/23
|
||||||
103.222.40.0/22
|
103.222.40.0/22
|
||||||
103.223.132.0/22
|
103.223.132.0/22
|
||||||
103.223.144.0/20
|
103.223.144.0/20
|
||||||
@@ -426,12 +422,12 @@
|
|||||||
103.230.236.0/22
|
103.230.236.0/22
|
||||||
103.231.16.0/24
|
103.231.16.0/24
|
||||||
103.231.64.0/21
|
103.231.64.0/21
|
||||||
103.232.144.0/22
|
|
||||||
103.232.166.0/23
|
103.232.166.0/23
|
||||||
103.233.128.0/22
|
103.233.128.0/22
|
||||||
103.233.136.0/24
|
103.233.136.0/24
|
||||||
103.233.138.0/24
|
103.233.138.0/24
|
||||||
103.233.162.0/23
|
103.233.162.0/23
|
||||||
|
103.233.228.0/22
|
||||||
103.233.4.0/22
|
103.233.4.0/22
|
||||||
103.233.52.0/22
|
103.233.52.0/22
|
||||||
103.234.128.0/23
|
103.234.128.0/23
|
||||||
@@ -488,7 +484,7 @@
|
|||||||
103.240.84.0/22
|
103.240.84.0/22
|
||||||
103.241.220.0/22
|
103.241.220.0/22
|
||||||
103.241.95.0/24
|
103.241.95.0/24
|
||||||
103.242.128.0/24
|
103.242.128.0/23
|
||||||
103.242.130.0/24
|
103.242.130.0/24
|
||||||
103.242.168.0/23
|
103.242.168.0/23
|
||||||
103.242.172.0/22
|
103.242.172.0/22
|
||||||
@@ -500,6 +496,7 @@
|
|||||||
103.244.64.0/22
|
103.244.64.0/22
|
||||||
103.244.80.0/22
|
103.244.80.0/22
|
||||||
103.245.128.0/22
|
103.245.128.0/22
|
||||||
|
103.245.25.0/24
|
||||||
103.246.152.0/22
|
103.246.152.0/22
|
||||||
103.247.168.0/22
|
103.247.168.0/22
|
||||||
103.247.176.0/22
|
103.247.176.0/22
|
||||||
@@ -642,8 +639,7 @@
|
|||||||
103.49.108.0/22
|
103.49.108.0/22
|
||||||
103.49.12.0/22
|
103.49.12.0/22
|
||||||
103.49.176.0/24
|
103.49.176.0/24
|
||||||
103.5.192.0/23
|
103.5.192.0/22
|
||||||
103.5.194.0/24
|
|
||||||
103.5.52.0/24
|
103.5.52.0/24
|
||||||
103.52.100.0/22
|
103.52.100.0/22
|
||||||
103.52.172.0/22
|
103.52.172.0/22
|
||||||
@@ -658,7 +654,6 @@
|
|||||||
103.56.100.0/22
|
103.56.100.0/22
|
||||||
103.56.104.0/22
|
103.56.104.0/22
|
||||||
103.56.152.0/22
|
103.56.152.0/22
|
||||||
103.56.184.0/22
|
|
||||||
103.56.60.0/22
|
103.56.60.0/22
|
||||||
103.56.76.0/22
|
103.56.76.0/22
|
||||||
103.57.12.0/22
|
103.57.12.0/22
|
||||||
@@ -706,6 +701,7 @@
|
|||||||
103.73.158.0/24
|
103.73.158.0/24
|
||||||
103.73.204.0/22
|
103.73.204.0/22
|
||||||
103.73.48.0/24
|
103.73.48.0/24
|
||||||
|
103.74.126.0/23
|
||||||
103.74.24.0/21
|
103.74.24.0/21
|
||||||
103.74.48.0/22
|
103.74.48.0/22
|
||||||
103.74.80.0/22
|
103.74.80.0/22
|
||||||
@@ -776,6 +772,7 @@
|
|||||||
103.98.125.0/24
|
103.98.125.0/24
|
||||||
103.98.127.0/24
|
103.98.127.0/24
|
||||||
103.98.220.0/22
|
103.98.220.0/22
|
||||||
|
103.98.224.0/22
|
||||||
103.98.248.0/23
|
103.98.248.0/23
|
||||||
103.98.251.0/24
|
103.98.251.0/24
|
||||||
103.98.252.0/22
|
103.98.252.0/22
|
||||||
@@ -849,7 +846,7 @@
|
|||||||
106.92.0.0/16
|
106.92.0.0/16
|
||||||
107.158.37.0/24
|
107.158.37.0/24
|
||||||
109.244.0.0/16
|
109.244.0.0/16
|
||||||
109.66.22.0/24
|
109.66.22.0/23
|
||||||
110.100.0.0/16
|
110.100.0.0/16
|
||||||
110.112.0.0/15
|
110.112.0.0/15
|
||||||
110.114.0.0/16
|
110.114.0.0/16
|
||||||
@@ -924,12 +921,14 @@
|
|||||||
111.223.12.0/22
|
111.223.12.0/22
|
||||||
111.224.0.0/14
|
111.224.0.0/14
|
||||||
111.228.0.0/18
|
111.228.0.0/18
|
||||||
|
111.228.80.0/22
|
||||||
111.229.0.0/16
|
111.229.0.0/16
|
||||||
111.230.0.0/15
|
111.230.0.0/15
|
||||||
111.235.156.0/22
|
111.235.156.0/22
|
||||||
111.235.160.0/22
|
111.235.160.0/22
|
||||||
111.235.164.0/23
|
111.235.164.0/23
|
||||||
111.235.168.0/22
|
111.235.169.0/24
|
||||||
|
111.235.170.0/23
|
||||||
111.235.172.0/23
|
111.235.172.0/23
|
||||||
111.235.174.0/24
|
111.235.174.0/24
|
||||||
111.235.178.0/23
|
111.235.178.0/23
|
||||||
@@ -995,6 +994,7 @@
|
|||||||
113.46.0.0/16
|
113.46.0.0/16
|
||||||
113.47.0.0/18
|
113.47.0.0/18
|
||||||
113.47.104.0/22
|
113.47.104.0/22
|
||||||
|
113.47.108.0/23
|
||||||
113.47.110.0/24
|
113.47.110.0/24
|
||||||
113.47.112.0/20
|
113.47.112.0/20
|
||||||
113.47.128.0/18
|
113.47.128.0/18
|
||||||
@@ -1022,6 +1022,7 @@
|
|||||||
113.8.0.0/15
|
113.8.0.0/15
|
||||||
114.104.0.0/14
|
114.104.0.0/14
|
||||||
114.110.0.0/20
|
114.110.0.0/20
|
||||||
|
114.110.112.0/22
|
||||||
114.110.96.0/22
|
114.110.96.0/22
|
||||||
114.111.0.0/23
|
114.111.0.0/23
|
||||||
114.111.16.0/20
|
114.111.16.0/20
|
||||||
@@ -1044,10 +1045,7 @@
|
|||||||
114.113.221.0/24
|
114.113.221.0/24
|
||||||
114.113.223.0/24
|
114.113.223.0/24
|
||||||
114.113.224.0/20
|
114.113.224.0/20
|
||||||
114.113.63.0/24
|
|
||||||
114.113.64.0/22
|
114.113.64.0/22
|
||||||
114.113.80.0/22
|
|
||||||
114.113.84.0/24
|
|
||||||
114.113.88.0/21
|
114.113.88.0/21
|
||||||
114.113.96.0/19
|
114.113.96.0/19
|
||||||
114.114.112.0/21
|
114.114.112.0/21
|
||||||
@@ -1124,6 +1122,7 @@
|
|||||||
115.31.64.0/22
|
115.31.64.0/22
|
||||||
115.32.0.0/19
|
115.32.0.0/19
|
||||||
115.32.104.0/21
|
115.32.104.0/21
|
||||||
|
115.32.112.0/22
|
||||||
115.32.120.0/21
|
115.32.120.0/21
|
||||||
115.32.128.0/19
|
115.32.128.0/19
|
||||||
115.32.32.0/20
|
115.32.32.0/20
|
||||||
@@ -1259,6 +1258,8 @@
|
|||||||
117.40.0.0/14
|
117.40.0.0/14
|
||||||
117.44.0.0/15
|
117.44.0.0/15
|
||||||
117.48.0.0/18
|
117.48.0.0/18
|
||||||
|
117.48.100.0/22
|
||||||
|
117.48.104.0/21
|
||||||
117.48.112.0/20
|
117.48.112.0/20
|
||||||
117.48.128.0/19
|
117.48.128.0/19
|
||||||
117.48.160.0/20
|
117.48.160.0/20
|
||||||
@@ -1482,6 +1483,7 @@
|
|||||||
119.37.2.0/24
|
119.37.2.0/24
|
||||||
119.38.0.0/21
|
119.38.0.0/21
|
||||||
119.38.192.0/19
|
119.38.192.0/19
|
||||||
|
119.38.224.0/24
|
||||||
119.39.0.0/16
|
119.39.0.0/16
|
||||||
119.4.0.0/14
|
119.4.0.0/14
|
||||||
119.40.128.0/17
|
119.40.128.0/17
|
||||||
@@ -1507,6 +1509,7 @@
|
|||||||
119.44.24.0/23
|
119.44.24.0/23
|
||||||
119.44.253.0/24
|
119.44.253.0/24
|
||||||
119.44.254.0/23
|
119.44.254.0/23
|
||||||
|
119.44.26.0/24
|
||||||
119.44.4.0/23
|
119.44.4.0/23
|
||||||
119.44.45.0/24
|
119.44.45.0/24
|
||||||
119.44.46.0/24
|
119.44.46.0/24
|
||||||
@@ -1550,6 +1553,7 @@
|
|||||||
119.80.200.0/22
|
119.80.200.0/22
|
||||||
119.80.240.0/22
|
119.80.240.0/22
|
||||||
119.80.248.0/21
|
119.80.248.0/21
|
||||||
|
119.80.56.0/24
|
||||||
119.80.8.0/22
|
119.80.8.0/22
|
||||||
119.84.0.0/14
|
119.84.0.0/14
|
||||||
119.88.128.0/17
|
119.88.128.0/17
|
||||||
@@ -1662,7 +1666,6 @@
|
|||||||
121.8.0.0/13
|
121.8.0.0/13
|
||||||
121.89.0.0/16
|
121.89.0.0/16
|
||||||
121.91.104.0/21
|
121.91.104.0/21
|
||||||
122.0.64.0/18
|
|
||||||
122.10.133.0/24
|
122.10.133.0/24
|
||||||
122.10.136.0/23
|
122.10.136.0/23
|
||||||
122.102.64.0/20
|
122.102.64.0/20
|
||||||
@@ -1800,8 +1803,11 @@
|
|||||||
123.4.0.0/14
|
123.4.0.0/14
|
||||||
123.49.192.0/23
|
123.49.192.0/23
|
||||||
123.49.194.0/24
|
123.49.194.0/24
|
||||||
|
123.49.196.0/24
|
||||||
123.49.231.0/24
|
123.49.231.0/24
|
||||||
123.49.232.0/24
|
123.49.232.0/24
|
||||||
|
123.49.237.0/24
|
||||||
|
123.49.238.0/23
|
||||||
123.49.240.0/24
|
123.49.240.0/24
|
||||||
123.49.242.0/23
|
123.49.242.0/23
|
||||||
123.49.245.0/24
|
123.49.245.0/24
|
||||||
@@ -1848,6 +1854,8 @@
|
|||||||
124.14.22.0/24
|
124.14.22.0/24
|
||||||
124.14.224.0/19
|
124.14.224.0/19
|
||||||
124.14.5.0/24
|
124.14.5.0/24
|
||||||
|
124.14.52.0/22
|
||||||
|
124.14.6.0/24
|
||||||
124.14.64.0/18
|
124.14.64.0/18
|
||||||
124.14.8.0/24
|
124.14.8.0/24
|
||||||
124.151.0.0/16
|
124.151.0.0/16
|
||||||
@@ -1901,6 +1909,7 @@
|
|||||||
124.71.128.0/18
|
124.71.128.0/18
|
||||||
124.71.192.0/19
|
124.71.192.0/19
|
||||||
124.71.224.0/20
|
124.71.224.0/20
|
||||||
|
124.71.244.0/23
|
||||||
124.71.250.0/24
|
124.71.250.0/24
|
||||||
124.72.0.0/13
|
124.72.0.0/13
|
||||||
124.88.0.0/13
|
124.88.0.0/13
|
||||||
@@ -1992,6 +2001,7 @@
|
|||||||
140.210.224.0/20
|
140.210.224.0/20
|
||||||
140.210.32.0/22
|
140.210.32.0/22
|
||||||
140.210.4.0/22
|
140.210.4.0/22
|
||||||
|
140.210.40.0/23
|
||||||
140.210.64.0/18
|
140.210.64.0/18
|
||||||
140.210.8.0/21
|
140.210.8.0/21
|
||||||
140.224.0.0/16
|
140.224.0.0/16
|
||||||
@@ -2003,7 +2013,10 @@
|
|||||||
140.250.0.0/16
|
140.250.0.0/16
|
||||||
140.255.0.0/16
|
140.255.0.0/16
|
||||||
140.75.0.0/16
|
140.75.0.0/16
|
||||||
|
141.11.210.0/24
|
||||||
141.11.219.0/24
|
141.11.219.0/24
|
||||||
|
142.86.252.0/23
|
||||||
|
142.86.254.0/24
|
||||||
143.20.246.0/24
|
143.20.246.0/24
|
||||||
143.64.0.0/16
|
143.64.0.0/16
|
||||||
144.0.0.0/16
|
144.0.0.0/16
|
||||||
@@ -2016,6 +2029,7 @@
|
|||||||
144.48.64.0/22
|
144.48.64.0/22
|
||||||
144.52.0.0/16
|
144.52.0.0/16
|
||||||
144.7.0.0/17
|
144.7.0.0/17
|
||||||
|
144.79.42.0/23
|
||||||
144.79.54.0/23
|
144.79.54.0/23
|
||||||
144.79.70.0/23
|
144.79.70.0/23
|
||||||
145.14.71.0/24
|
145.14.71.0/24
|
||||||
@@ -2028,6 +2042,7 @@
|
|||||||
145.14.90.0/24
|
145.14.90.0/24
|
||||||
146.19.167.0/24
|
146.19.167.0/24
|
||||||
146.19.236.0/24
|
146.19.236.0/24
|
||||||
|
146.19.53.0/24
|
||||||
146.196.112.0/21
|
146.196.112.0/21
|
||||||
146.196.56.0/22
|
146.196.56.0/22
|
||||||
146.196.68.0/22
|
146.196.68.0/22
|
||||||
@@ -2043,6 +2058,7 @@
|
|||||||
150.138.0.0/15
|
150.138.0.0/15
|
||||||
150.158.0.0/16
|
150.158.0.0/16
|
||||||
150.223.0.0/16
|
150.223.0.0/16
|
||||||
|
150.242.152.0/22
|
||||||
150.242.156.0/23
|
150.242.156.0/23
|
||||||
150.242.168.0/22
|
150.242.168.0/22
|
||||||
150.242.184.0/22
|
150.242.184.0/22
|
||||||
@@ -2111,26 +2127,28 @@
|
|||||||
155.102.24.0/24
|
155.102.24.0/24
|
||||||
155.102.26.0/23
|
155.102.26.0/23
|
||||||
155.102.28.0/22
|
155.102.28.0/22
|
||||||
155.102.32.0/21
|
155.102.32.0/23
|
||||||
|
155.102.34.0/24
|
||||||
|
155.102.36.0/22
|
||||||
155.102.4.0/23
|
155.102.4.0/23
|
||||||
155.102.40.0/23
|
155.102.40.0/23
|
||||||
155.102.43.0/24
|
155.102.43.0/24
|
||||||
155.102.44.0/22
|
155.102.44.0/22
|
||||||
155.102.48.0/20
|
155.102.49.0/24
|
||||||
155.102.64.0/23
|
155.102.50.0/23
|
||||||
155.102.67.0/24
|
155.102.52.0/22
|
||||||
155.102.68.0/23
|
155.102.56.0/21
|
||||||
|
155.102.64.0/24
|
||||||
|
155.102.69.0/24
|
||||||
155.102.70.0/24
|
155.102.70.0/24
|
||||||
155.102.72.0/23
|
155.102.72.0/21
|
||||||
155.102.74.0/24
|
|
||||||
155.102.76.0/22
|
|
||||||
155.102.8.0/22
|
155.102.8.0/22
|
||||||
155.102.80.0/22
|
155.102.80.0/24
|
||||||
155.102.84.0/24
|
155.102.82.0/23
|
||||||
155.102.86.0/23
|
155.102.84.0/22
|
||||||
155.102.88.0/22
|
155.102.91.0/24
|
||||||
155.102.94.0/23
|
155.102.94.0/24
|
||||||
155.102.96.0/22
|
155.102.98.0/23
|
||||||
155.126.176.0/23
|
155.126.176.0/23
|
||||||
156.107.160.0/23
|
156.107.160.0/23
|
||||||
156.107.170.0/24
|
156.107.170.0/24
|
||||||
@@ -2185,7 +2203,6 @@
|
|||||||
162.105.0.0/16
|
162.105.0.0/16
|
||||||
162.128.248.0/24
|
162.128.248.0/24
|
||||||
162.14.0.0/16
|
162.14.0.0/16
|
||||||
162.141.140.0/24
|
|
||||||
162.4.136.0/23
|
162.4.136.0/23
|
||||||
163.0.0.0/16
|
163.0.0.0/16
|
||||||
163.125.0.0/16
|
163.125.0.0/16
|
||||||
@@ -2210,11 +2227,14 @@
|
|||||||
163.181.136.0/22
|
163.181.136.0/22
|
||||||
163.181.140.0/24
|
163.181.140.0/24
|
||||||
163.181.142.0/23
|
163.181.142.0/23
|
||||||
163.181.144.0/20
|
163.181.144.0/22
|
||||||
|
163.181.148.0/23
|
||||||
163.181.15.0/24
|
163.181.15.0/24
|
||||||
|
163.181.150.0/24
|
||||||
|
163.181.152.0/21
|
||||||
163.181.16.0/22
|
163.181.16.0/22
|
||||||
163.181.160.0/24
|
163.181.160.0/24
|
||||||
163.181.162.0/23
|
163.181.163.0/24
|
||||||
163.181.164.0/22
|
163.181.164.0/22
|
||||||
163.181.168.0/21
|
163.181.168.0/21
|
||||||
163.181.176.0/21
|
163.181.176.0/21
|
||||||
@@ -2263,7 +2283,6 @@
|
|||||||
163.181.99.0/24
|
163.181.99.0/24
|
||||||
163.204.0.0/16
|
163.204.0.0/16
|
||||||
163.223.178.0/23
|
163.223.178.0/23
|
||||||
163.223.72.0/23
|
|
||||||
163.227.40.0/23
|
163.227.40.0/23
|
||||||
163.228.0.0/16
|
163.228.0.0/16
|
||||||
163.244.246.0/24
|
163.244.246.0/24
|
||||||
@@ -2271,6 +2290,7 @@
|
|||||||
163.5.166.0/24
|
163.5.166.0/24
|
||||||
163.5.53.0/24
|
163.5.53.0/24
|
||||||
163.5.79.0/24
|
163.5.79.0/24
|
||||||
|
163.52.28.0/23
|
||||||
163.53.128.0/22
|
163.53.128.0/22
|
||||||
163.53.168.0/22
|
163.53.168.0/22
|
||||||
163.53.44.0/22
|
163.53.44.0/22
|
||||||
@@ -2279,11 +2299,11 @@
|
|||||||
163.61.178.0/23
|
163.61.178.0/23
|
||||||
163.61.202.0/23
|
163.61.202.0/23
|
||||||
163.61.214.0/23
|
163.61.214.0/23
|
||||||
164.163.236.0/22
|
|
||||||
165.101.208.0/23
|
165.101.208.0/23
|
||||||
165.101.70.0/24
|
165.101.70.0/24
|
||||||
166.111.0.0/16
|
166.111.0.0/16
|
||||||
167.139.0.0/16
|
167.139.0.0/16
|
||||||
|
167.160.27.0/24
|
||||||
167.189.0.0/16
|
167.189.0.0/16
|
||||||
167.220.244.0/22
|
167.220.244.0/22
|
||||||
168.160.0.0/17
|
168.160.0.0/17
|
||||||
@@ -2291,7 +2311,7 @@
|
|||||||
168.160.158.0/23
|
168.160.158.0/23
|
||||||
168.160.160.0/21
|
168.160.160.0/21
|
||||||
168.160.168.0/24
|
168.160.168.0/24
|
||||||
170.33.98.0/24
|
169.40.59.0/24
|
||||||
171.104.0.0/13
|
171.104.0.0/13
|
||||||
171.112.0.0/12
|
171.112.0.0/12
|
||||||
171.208.0.0/12
|
171.208.0.0/12
|
||||||
@@ -2348,18 +2368,19 @@
|
|||||||
180.178.224.0/21
|
180.178.224.0/21
|
||||||
180.178.232.0/22
|
180.178.232.0/22
|
||||||
180.178.248.0/21
|
180.178.248.0/21
|
||||||
180.184.0.0/21
|
180.184.0.0/23
|
||||||
180.184.128.0/20
|
180.184.128.0/20
|
||||||
180.184.14.0/24
|
180.184.14.0/24
|
||||||
180.184.144.0/21
|
180.184.144.0/21
|
||||||
180.184.152.0/22
|
180.184.152.0/22
|
||||||
180.184.16.0/24
|
|
||||||
180.184.160.0/20
|
180.184.160.0/20
|
||||||
180.184.176.0/21
|
180.184.176.0/21
|
||||||
180.184.184.0/22
|
180.184.184.0/22
|
||||||
180.184.192.0/18
|
180.184.192.0/18
|
||||||
|
180.184.2.0/24
|
||||||
180.184.24.0/21
|
180.184.24.0/21
|
||||||
180.184.32.0/19
|
180.184.32.0/19
|
||||||
|
180.184.6.0/23
|
||||||
180.184.64.0/19
|
180.184.64.0/19
|
||||||
180.184.8.0/23
|
180.184.8.0/23
|
||||||
180.184.96.0/21
|
180.184.96.0/21
|
||||||
@@ -2445,14 +2466,12 @@
|
|||||||
183.91.48.0/21
|
183.91.48.0/21
|
||||||
183.91.56.0/24
|
183.91.56.0/24
|
||||||
183.91.61.0/24
|
183.91.61.0/24
|
||||||
183.91.63.0/24
|
|
||||||
183.92.0.0/14
|
183.92.0.0/14
|
||||||
185.39.51.0/24
|
185.39.51.0/24
|
||||||
185.75.173.0/24
|
185.75.173.0/24
|
||||||
185.75.174.0/24
|
185.75.174.0/24
|
||||||
|
187.7.197.0/24
|
||||||
188.131.128.0/17
|
188.131.128.0/17
|
||||||
188.220.42.0/24
|
|
||||||
188.220.68.0/24
|
|
||||||
192.140.160.0/19
|
192.140.160.0/19
|
||||||
192.140.208.0/21
|
192.140.208.0/21
|
||||||
192.144.128.0/17
|
192.144.128.0/17
|
||||||
@@ -2461,7 +2480,6 @@
|
|||||||
192.51.173.0/24
|
192.51.173.0/24
|
||||||
192.6.87.0/24
|
192.6.87.0/24
|
||||||
193.112.0.0/16
|
193.112.0.0/16
|
||||||
193.233.49.0/24
|
|
||||||
194.127.229.0/24
|
194.127.229.0/24
|
||||||
194.138.202.0/23
|
194.138.202.0/23
|
||||||
194.138.245.0/24
|
194.138.245.0/24
|
||||||
@@ -2476,6 +2494,9 @@
|
|||||||
198.23.184.0/24
|
198.23.184.0/24
|
||||||
198.23.195.0/24
|
198.23.195.0/24
|
||||||
199.182.239.0/24
|
199.182.239.0/24
|
||||||
|
199.19.20.0/23
|
||||||
|
199.19.22.0/24
|
||||||
|
199.190.46.0/24
|
||||||
199.244.144.0/24
|
199.244.144.0/24
|
||||||
2.58.86.0/24
|
2.58.86.0/24
|
||||||
2.59.182.0/24
|
2.59.182.0/24
|
||||||
@@ -2598,7 +2619,7 @@
|
|||||||
202.84.17.0/24
|
202.84.17.0/24
|
||||||
202.85.208.0/20
|
202.85.208.0/20
|
||||||
202.89.232.0/21
|
202.89.232.0/21
|
||||||
202.89.96.0/22
|
202.89.96.0/24
|
||||||
202.90.20.0/22
|
202.90.20.0/22
|
||||||
202.90.96.0/20
|
202.90.96.0/20
|
||||||
202.91.176.0/21
|
202.91.176.0/21
|
||||||
@@ -2620,6 +2641,7 @@
|
|||||||
203.107.120.0/22
|
203.107.120.0/22
|
||||||
203.107.124.0/23
|
203.107.124.0/23
|
||||||
203.107.13.0/24
|
203.107.13.0/24
|
||||||
|
203.107.14.0/24
|
||||||
203.107.2.0/24
|
203.107.2.0/24
|
||||||
203.107.20.0/22
|
203.107.20.0/22
|
||||||
203.107.24.0/24
|
203.107.24.0/24
|
||||||
@@ -2627,6 +2649,7 @@
|
|||||||
203.107.28.0/22
|
203.107.28.0/22
|
||||||
203.107.32.0/19
|
203.107.32.0/19
|
||||||
203.107.6.0/24
|
203.107.6.0/24
|
||||||
|
203.107.70.0/24
|
||||||
203.107.72.0/21
|
203.107.72.0/21
|
||||||
203.107.80.0/21
|
203.107.80.0/21
|
||||||
203.107.96.0/23
|
203.107.96.0/23
|
||||||
@@ -2713,6 +2736,7 @@
|
|||||||
203.205.80.0/21
|
203.205.80.0/21
|
||||||
203.205.88.0/22
|
203.205.88.0/22
|
||||||
203.205.92.0/23
|
203.205.92.0/23
|
||||||
|
203.205.94.0/24
|
||||||
203.207.104.0/22
|
203.207.104.0/22
|
||||||
203.207.112.0/20
|
203.207.112.0/20
|
||||||
203.207.128.0/18
|
203.207.128.0/18
|
||||||
@@ -2905,8 +2929,8 @@
|
|||||||
203.99.18.0/24
|
203.99.18.0/24
|
||||||
203.99.20.0/22
|
203.99.20.0/22
|
||||||
203.99.24.0/21
|
203.99.24.0/21
|
||||||
204.14.76.0/24
|
|
||||||
204.235.241.0/24
|
204.235.241.0/24
|
||||||
|
206.109.70.0/23
|
||||||
206.109.75.0/24
|
206.109.75.0/24
|
||||||
210.12.0.0/16
|
210.12.0.0/16
|
||||||
210.13.0.0/17
|
210.13.0.0/17
|
||||||
@@ -3108,8 +3132,8 @@
|
|||||||
211.160.8.0/22
|
211.160.8.0/22
|
||||||
211.160.80.0/20
|
211.160.80.0/20
|
||||||
211.161.0.0/20
|
211.161.0.0/20
|
||||||
211.161.101.0/24
|
211.161.100.0/22
|
||||||
211.161.102.0/23
|
211.161.104.0/22
|
||||||
211.161.120.0/21
|
211.161.120.0/21
|
||||||
211.161.192.0/22
|
211.161.192.0/22
|
||||||
211.161.203.0/24
|
211.161.203.0/24
|
||||||
@@ -3120,6 +3144,7 @@
|
|||||||
211.161.32.0/20
|
211.161.32.0/20
|
||||||
211.161.60.0/23
|
211.161.60.0/23
|
||||||
211.161.62.0/24
|
211.161.62.0/24
|
||||||
|
211.161.98.0/23
|
||||||
211.162.0.0/21
|
211.162.0.0/21
|
||||||
211.162.119.0/24
|
211.162.119.0/24
|
||||||
211.162.120.0/21
|
211.162.120.0/21
|
||||||
@@ -3183,9 +3208,9 @@
|
|||||||
211.99.64.0/18
|
211.99.64.0/18
|
||||||
211.99.8.0/21
|
211.99.8.0/21
|
||||||
212.129.128.0/17
|
212.129.128.0/17
|
||||||
212.212.26.0/24
|
|
||||||
212.64.0.0/17
|
212.64.0.0/17
|
||||||
216.105.166.0/24
|
216.105.166.0/24
|
||||||
|
217.217.211.0/24
|
||||||
218.0.0.0/11
|
218.0.0.0/11
|
||||||
218.100.88.0/21
|
218.100.88.0/21
|
||||||
218.104.0.0/15
|
218.104.0.0/15
|
||||||
@@ -3253,10 +3278,9 @@
|
|||||||
218.98.111.0/24
|
218.98.111.0/24
|
||||||
218.98.112.0/20
|
218.98.112.0/20
|
||||||
218.98.160.0/24
|
218.98.160.0/24
|
||||||
218.98.176.0/22
|
218.98.176.0/21
|
||||||
218.98.180.0/23
|
|
||||||
218.98.182.0/24
|
|
||||||
218.98.192.0/24
|
218.98.192.0/24
|
||||||
|
218.98.208.0/21
|
||||||
218.98.96.0/21
|
218.98.96.0/21
|
||||||
219.128.0.0/12
|
219.128.0.0/12
|
||||||
219.144.0.0/14
|
219.144.0.0/14
|
||||||
@@ -3322,9 +3346,10 @@
|
|||||||
220.113.96.0/21
|
220.113.96.0/21
|
||||||
220.114.250.0/23
|
220.114.250.0/23
|
||||||
220.154.0.0/20
|
220.154.0.0/20
|
||||||
|
220.154.116.0/23
|
||||||
220.154.128.0/20
|
220.154.128.0/20
|
||||||
220.154.147.0/24
|
220.154.147.0/24
|
||||||
220.154.16.0/22
|
220.154.16.0/21
|
||||||
220.154.64.0/20
|
220.154.64.0/20
|
||||||
220.154.80.0/22
|
220.154.80.0/22
|
||||||
220.160.0.0/12
|
220.160.0.0/12
|
||||||
@@ -3417,7 +3442,6 @@
|
|||||||
222.128.0.0/12
|
222.128.0.0/12
|
||||||
222.16.0.0/12
|
222.16.0.0/12
|
||||||
222.160.0.0/14
|
222.160.0.0/14
|
||||||
222.167.254.0/24
|
|
||||||
222.168.0.0/13
|
222.168.0.0/13
|
||||||
222.176.0.0/12
|
222.176.0.0/12
|
||||||
222.192.0.0/11
|
222.192.0.0/11
|
||||||
@@ -3531,7 +3555,6 @@
|
|||||||
31.77.184.0/22
|
31.77.184.0/22
|
||||||
36.1.0.0/16
|
36.1.0.0/16
|
||||||
36.112.0.0/15
|
36.112.0.0/15
|
||||||
36.114.0.0/16
|
|
||||||
36.128.0.0/10
|
36.128.0.0/10
|
||||||
36.16.0.0/12
|
36.16.0.0/12
|
||||||
36.192.0.0/16
|
36.192.0.0/16
|
||||||
@@ -3558,16 +3581,16 @@
|
|||||||
36.96.0.0/12
|
36.96.0.0/12
|
||||||
38.102.232.0/22
|
38.102.232.0/22
|
||||||
38.105.24.0/21
|
38.105.24.0/21
|
||||||
38.134.56.0/24
|
|
||||||
38.134.58.0/23
|
38.134.58.0/23
|
||||||
38.247.24.0/23
|
38.247.24.0/22
|
||||||
38.247.27.0/24
|
38.247.32.0/22
|
||||||
38.247.32.0/24
|
|
||||||
38.247.34.0/23
|
|
||||||
38.247.36.0/24
|
38.247.36.0/24
|
||||||
38.247.38.0/23
|
38.247.38.0/23
|
||||||
38.84.220.0/24
|
38.84.220.0/24
|
||||||
38.95.112.0/20
|
38.95.112.0/22
|
||||||
|
38.95.117.0/24
|
||||||
|
38.95.118.0/23
|
||||||
|
38.95.120.0/21
|
||||||
38.95.232.0/23
|
38.95.232.0/23
|
||||||
39.104.0.0/14
|
39.104.0.0/14
|
||||||
39.108.0.0/16
|
39.108.0.0/16
|
||||||
@@ -3579,7 +3602,6 @@
|
|||||||
40.125.128.0/17
|
40.125.128.0/17
|
||||||
40.126.64.0/18
|
40.126.64.0/18
|
||||||
40.162.0.0/16
|
40.162.0.0/16
|
||||||
40.183.101.0/24
|
|
||||||
40.72.0.0/15
|
40.72.0.0/15
|
||||||
42.100.0.0/14
|
42.100.0.0/14
|
||||||
42.120.0.0/15
|
42.120.0.0/15
|
||||||
@@ -3608,8 +3630,10 @@
|
|||||||
42.240.0.0/21
|
42.240.0.0/21
|
||||||
42.240.12.0/23
|
42.240.12.0/23
|
||||||
42.240.128.0/17
|
42.240.128.0/17
|
||||||
|
42.240.14.0/24
|
||||||
42.240.16.0/23
|
42.240.16.0/23
|
||||||
42.240.20.0/22
|
42.240.20.0/22
|
||||||
|
42.240.24.0/24
|
||||||
42.240.48.0/24
|
42.240.48.0/24
|
||||||
42.240.8.0/22
|
42.240.8.0/22
|
||||||
42.242.0.0/15
|
42.242.0.0/15
|
||||||
@@ -3649,43 +3673,45 @@
|
|||||||
43.109.116.0/23
|
43.109.116.0/23
|
||||||
43.109.118.0/24
|
43.109.118.0/24
|
||||||
43.109.12.0/22
|
43.109.12.0/22
|
||||||
43.109.120.0/23
|
43.109.120.0/22
|
||||||
43.109.126.0/24
|
43.109.124.0/24
|
||||||
43.109.133.0/24
|
43.109.126.0/23
|
||||||
43.109.134.0/23
|
43.109.128.0/20
|
||||||
43.109.136.0/22
|
|
||||||
43.109.140.0/23
|
|
||||||
43.109.143.0/24
|
|
||||||
43.109.144.0/23
|
43.109.144.0/23
|
||||||
43.109.146.0/24
|
43.109.146.0/24
|
||||||
43.109.148.0/23
|
43.109.148.0/23
|
||||||
43.109.150.0/24
|
43.109.150.0/24
|
||||||
43.109.156.0/24
|
43.109.156.0/24
|
||||||
|
43.109.158.0/23
|
||||||
43.109.16.0/23
|
43.109.16.0/23
|
||||||
43.109.160.0/22
|
43.109.160.0/22
|
||||||
43.109.164.0/23
|
43.109.164.0/23
|
||||||
43.109.167.0/24
|
43.109.167.0/24
|
||||||
43.109.168.0/21
|
43.109.168.0/21
|
||||||
43.109.176.0/24
|
43.109.176.0/24
|
||||||
|
43.109.178.0/23
|
||||||
43.109.184.0/23
|
43.109.184.0/23
|
||||||
43.109.186.0/24
|
43.109.186.0/24
|
||||||
43.109.19.0/24
|
43.109.19.0/24
|
||||||
43.109.190.0/23
|
43.109.190.0/23
|
||||||
43.109.192.0/21
|
43.109.192.0/22
|
||||||
|
43.109.197.0/24
|
||||||
|
43.109.199.0/24
|
||||||
43.109.2.0/24
|
43.109.2.0/24
|
||||||
43.109.200.0/23
|
43.109.200.0/23
|
||||||
43.109.202.0/24
|
43.109.202.0/24
|
||||||
43.109.206.0/23
|
43.109.206.0/23
|
||||||
43.109.208.0/23
|
43.109.208.0/22
|
||||||
43.109.21.0/24
|
43.109.21.0/24
|
||||||
43.109.214.0/23
|
43.109.214.0/23
|
||||||
43.109.216.0/21
|
43.109.216.0/21
|
||||||
43.109.22.0/24
|
43.109.22.0/24
|
||||||
43.109.224.0/23
|
43.109.224.0/23
|
||||||
43.109.226.0/24
|
43.109.226.0/24
|
||||||
43.109.239.0/24
|
43.109.235.0/24
|
||||||
43.109.24.0/23
|
43.109.237.0/24
|
||||||
43.109.26.0/24
|
43.109.238.0/23
|
||||||
|
43.109.24.0/22
|
||||||
43.109.28.0/24
|
43.109.28.0/24
|
||||||
43.109.30.0/23
|
43.109.30.0/23
|
||||||
43.109.32.0/23
|
43.109.32.0/23
|
||||||
@@ -3705,13 +3731,14 @@
|
|||||||
43.109.70.0/24
|
43.109.70.0/24
|
||||||
43.109.72.0/23
|
43.109.72.0/23
|
||||||
43.109.76.0/22
|
43.109.76.0/22
|
||||||
43.109.8.0/23
|
|
||||||
43.109.83.0/24
|
43.109.83.0/24
|
||||||
43.109.84.0/22
|
43.109.84.0/22
|
||||||
43.109.88.0/22
|
43.109.88.0/22
|
||||||
|
43.109.9.0/24
|
||||||
43.109.92.0/23
|
43.109.92.0/23
|
||||||
43.109.94.0/24
|
43.109.94.0/24
|
||||||
43.109.96.0/23
|
43.109.96.0/23
|
||||||
|
43.116.128.0/20
|
||||||
43.136.0.0/13
|
43.136.0.0/13
|
||||||
43.144.0.0/15
|
43.144.0.0/15
|
||||||
43.176.0.0/14
|
43.176.0.0/14
|
||||||
@@ -3893,7 +3920,8 @@
|
|||||||
44.30.152.0/24
|
44.30.152.0/24
|
||||||
44.30.164.0/24
|
44.30.164.0/24
|
||||||
44.30.171.0/24
|
44.30.171.0/24
|
||||||
44.30.190.0/24
|
44.30.180.0/24
|
||||||
|
44.30.226.0/24
|
||||||
44.31.216.0/24
|
44.31.216.0/24
|
||||||
44.31.28.0/24
|
44.31.28.0/24
|
||||||
44.31.43.0/24
|
44.31.43.0/24
|
||||||
@@ -3943,6 +3971,7 @@
|
|||||||
45.127.129.0/24
|
45.127.129.0/24
|
||||||
45.127.144.0/21
|
45.127.144.0/21
|
||||||
45.137.97.0/24
|
45.137.97.0/24
|
||||||
|
45.140.144.0/24
|
||||||
45.146.82.0/24
|
45.146.82.0/24
|
||||||
45.248.108.0/23
|
45.248.108.0/23
|
||||||
45.248.110.0/24
|
45.248.110.0/24
|
||||||
@@ -3963,7 +3992,6 @@
|
|||||||
45.251.96.0/21
|
45.251.96.0/21
|
||||||
45.252.0.0/22
|
45.252.0.0/22
|
||||||
45.252.104.0/22
|
45.252.104.0/22
|
||||||
45.252.48.0/22
|
|
||||||
45.253.112.0/21
|
45.253.112.0/21
|
||||||
45.253.132.0/22
|
45.253.132.0/22
|
||||||
45.253.136.0/21
|
45.253.136.0/21
|
||||||
@@ -3981,7 +4009,6 @@
|
|||||||
45.254.50.0/24
|
45.254.50.0/24
|
||||||
45.254.64.0/20
|
45.254.64.0/20
|
||||||
45.254.8.0/22
|
45.254.8.0/22
|
||||||
45.255.152.0/22
|
|
||||||
45.40.192.0/18
|
45.40.192.0/18
|
||||||
45.65.20.0/22
|
45.65.20.0/22
|
||||||
45.82.238.0/23
|
45.82.238.0/23
|
||||||
@@ -3990,13 +4017,12 @@
|
|||||||
46.37.112.0/24
|
46.37.112.0/24
|
||||||
47.112.0.0/13
|
47.112.0.0/13
|
||||||
47.120.0.0/14
|
47.120.0.0/14
|
||||||
47.246.0.0/22
|
47.246.1.0/24
|
||||||
47.246.12.0/23
|
47.246.12.0/23
|
||||||
47.246.15.0/24
|
47.246.2.0/23
|
||||||
47.246.20.0/24
|
47.246.20.0/24
|
||||||
47.246.22.0/23
|
47.246.22.0/23
|
||||||
47.246.24.0/24
|
47.246.24.0/24
|
||||||
47.246.26.0/24
|
|
||||||
47.246.28.0/22
|
47.246.28.0/22
|
||||||
47.246.36.0/22
|
47.246.36.0/22
|
||||||
47.246.4.0/24
|
47.246.4.0/24
|
||||||
@@ -4006,7 +4032,6 @@
|
|||||||
47.246.46.0/24
|
47.246.46.0/24
|
||||||
47.246.48.0/23
|
47.246.48.0/23
|
||||||
47.246.50.0/24
|
47.246.50.0/24
|
||||||
47.246.57.0/24
|
|
||||||
47.246.58.0/24
|
47.246.58.0/24
|
||||||
47.246.6.0/24
|
47.246.6.0/24
|
||||||
47.246.60.0/22
|
47.246.60.0/22
|
||||||
@@ -4048,7 +4073,7 @@
|
|||||||
52.82.134.0/23
|
52.82.134.0/23
|
||||||
52.82.136.0/24
|
52.82.136.0/24
|
||||||
52.82.144.0/23
|
52.82.144.0/23
|
||||||
52.82.148.0/23
|
52.82.148.0/22
|
||||||
52.82.160.0/21
|
52.82.160.0/21
|
||||||
52.82.170.0/23
|
52.82.170.0/23
|
||||||
52.82.172.0/22
|
52.82.172.0/22
|
||||||
@@ -4095,7 +4120,7 @@
|
|||||||
58.82.0.0/22
|
58.82.0.0/22
|
||||||
58.83.0.0/16
|
58.83.0.0/16
|
||||||
58.87.64.0/18
|
58.87.64.0/18
|
||||||
58.99.128.0/17
|
58.99.254.0/23
|
||||||
59.107.0.0/17
|
59.107.0.0/17
|
||||||
59.108.0.0/16
|
59.108.0.0/16
|
||||||
59.110.0.0/16
|
59.110.0.0/16
|
||||||
@@ -4147,6 +4172,7 @@
|
|||||||
59.152.38.0/23
|
59.152.38.0/23
|
||||||
59.153.164.0/22
|
59.153.164.0/22
|
||||||
59.153.168.0/24
|
59.153.168.0/24
|
||||||
|
59.153.172.0/24
|
||||||
59.153.32.0/22
|
59.153.32.0/22
|
||||||
59.153.4.0/23
|
59.153.4.0/23
|
||||||
59.153.92.0/22
|
59.153.92.0/22
|
||||||
@@ -4177,6 +4203,7 @@
|
|||||||
60.160.0.0/11
|
60.160.0.0/11
|
||||||
60.194.0.0/15
|
60.194.0.0/15
|
||||||
60.200.0.0/24
|
60.200.0.0/24
|
||||||
|
60.200.35.0/24
|
||||||
60.204.0.0/14
|
60.204.0.0/14
|
||||||
60.208.0.0/12
|
60.208.0.0/12
|
||||||
60.232.0.0/16
|
60.232.0.0/16
|
||||||
@@ -4212,7 +4239,6 @@
|
|||||||
62.84.174.0/24
|
62.84.174.0/24
|
||||||
63.140.0.0/24
|
63.140.0.0/24
|
||||||
63.140.3.0/24
|
63.140.3.0/24
|
||||||
64.204.200.0/24
|
|
||||||
64.50.181.0/24
|
64.50.181.0/24
|
||||||
66.102.240.0/21
|
66.102.240.0/21
|
||||||
66.102.248.0/22
|
66.102.248.0/22
|
||||||
@@ -4239,10 +4265,12 @@
|
|||||||
71.137.0.0/18
|
71.137.0.0/18
|
||||||
72.244.228.0/24
|
72.244.228.0/24
|
||||||
74.1.16.0/24
|
74.1.16.0/24
|
||||||
74.2.225.0/24
|
|
||||||
78.105.182.0/23
|
78.105.182.0/23
|
||||||
79.133.176.0/24
|
79.133.176.0/24
|
||||||
79.175.118.0/24
|
79.175.118.0/24
|
||||||
|
79.175.67.0/24
|
||||||
|
79.180.180.0/24
|
||||||
|
79.182.118.0/24
|
||||||
8.128.32.0/19
|
8.128.32.0/19
|
||||||
8.128.4.0/22
|
8.128.4.0/22
|
||||||
8.128.64.0/19
|
8.128.64.0/19
|
||||||
@@ -4295,5 +4323,4 @@
|
|||||||
87.76.222.0/24
|
87.76.222.0/24
|
||||||
87.84.190.0/23
|
87.84.190.0/23
|
||||||
89.106.68.0/24
|
89.106.68.0/24
|
||||||
89.116.144.0/24
|
|
||||||
94.191.0.0/17
|
94.191.0.0/17
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
2001:4510:1480::/41
|
2001:4510:1480::/41
|
||||||
2001:4510:400::/40
|
2001:4510:400::/40
|
||||||
2001:4511:1480::/41
|
2001:4511:1480::/41
|
||||||
|
2001:550:1601::/48
|
||||||
2001:678:53c::/48
|
2001:678:53c::/48
|
||||||
2001:678:970::/48
|
2001:678:970::/48
|
||||||
2001:7fa:5::/48
|
2001:7fa:5::/48
|
||||||
@@ -12,11 +13,13 @@
|
|||||||
2001:daa:1::/48
|
2001:daa:1::/48
|
||||||
2001:daa:2::/47
|
2001:daa:2::/47
|
||||||
2001:daa:4::/47
|
2001:daa:4::/47
|
||||||
|
2001:daa:6::/48
|
||||||
2001:daa:9::/48
|
2001:daa:9::/48
|
||||||
2001:dc7::/32
|
2001:dc7::/32
|
||||||
2001:dd8:1::/48
|
2001:dd8:1::/48
|
||||||
2001:dd9::/48
|
2001:dd9::/48
|
||||||
2001:df1:61c0::/48
|
2001:df1:61c0::/48
|
||||||
|
2001:df5:7800::/48
|
||||||
2001:df6:40::/48
|
2001:df6:40::/48
|
||||||
2400:1160::/32
|
2400:1160::/32
|
||||||
2400:3200::/32
|
2400:3200::/32
|
||||||
@@ -87,8 +90,8 @@
|
|||||||
2400:9620::/32
|
2400:9620::/32
|
||||||
2400:a860:1::/48
|
2400:a860:1::/48
|
||||||
2400:a860:2::/47
|
2400:a860:2::/47
|
||||||
2400:a860:4::/47
|
2400:a860:4::/46
|
||||||
2400:a860:6::/48
|
2400:a860:8::/47
|
||||||
2400:a980::/29
|
2400:a980::/29
|
||||||
2400:ae00:1981::/48
|
2400:ae00:1981::/48
|
||||||
2400:b200::/32
|
2400:b200::/32
|
||||||
@@ -108,6 +111,7 @@
|
|||||||
2401:1160::/32
|
2401:1160::/32
|
||||||
2401:1200::/48
|
2401:1200::/48
|
||||||
2401:1320::/32
|
2401:1320::/32
|
||||||
|
2401:18ef:1000::/44
|
||||||
2401:1d40::/32
|
2401:1d40::/32
|
||||||
2401:2780::/32
|
2401:2780::/32
|
||||||
2401:2a00:f000::/43
|
2401:2a00:f000::/43
|
||||||
@@ -155,6 +159,7 @@
|
|||||||
2401:9a00:10::/46
|
2401:9a00:10::/46
|
||||||
2401:9a00::/44
|
2401:9a00::/44
|
||||||
2401:a140:1::/48
|
2401:a140:1::/48
|
||||||
|
2401:a540::/32
|
||||||
2401:b180::/32
|
2401:b180::/32
|
||||||
2401:b400:11::/48
|
2401:b400:11::/48
|
||||||
2401:b400:14::/48
|
2401:b400:14::/48
|
||||||
@@ -164,9 +169,6 @@
|
|||||||
2401:b400::/45
|
2401:b400::/45
|
||||||
2401:b680::/32
|
2401:b680::/32
|
||||||
2401:be00::/32
|
2401:be00::/32
|
||||||
2401:c020:14::/48
|
|
||||||
2401:c020:6::/48
|
|
||||||
2401:c020:8::/47
|
|
||||||
2401:ca00::/32
|
2401:ca00::/32
|
||||||
2401:cb80::/32
|
2401:cb80::/32
|
||||||
2401:cc00::/32
|
2401:cc00::/32
|
||||||
@@ -183,12 +185,10 @@
|
|||||||
2401:f860:100::/40
|
2401:f860:100::/40
|
||||||
2401:f860:88::/48
|
2401:f860:88::/48
|
||||||
2401:f860:90::/48
|
2401:f860:90::/48
|
||||||
2401:f860:92::/47
|
2401:f860:92::/48
|
||||||
2401:f860:94::/48
|
2401:f860:94::/48
|
||||||
2401:f860:97::/48
|
2401:f860:97::/48
|
||||||
2401:fa00:40::/48
|
|
||||||
2402:1440::/32
|
2402:1440::/32
|
||||||
2402:18a0::/32
|
|
||||||
2402:2000::/32
|
2402:2000::/32
|
||||||
2402:34e0::/32
|
2402:34e0::/32
|
||||||
2402:36e0::/44
|
2402:36e0::/44
|
||||||
@@ -219,6 +219,7 @@
|
|||||||
2402:6f40::/48
|
2402:6f40::/48
|
||||||
2402:6fc0::/48
|
2402:6fc0::/48
|
||||||
2402:7040::/32
|
2402:7040::/32
|
||||||
|
2402:7060::/32
|
||||||
2402:7d80:240::/48
|
2402:7d80:240::/48
|
||||||
2402:7d80:8888::/48
|
2402:7d80:8888::/48
|
||||||
2402:7d80::/48
|
2402:7d80::/48
|
||||||
@@ -252,6 +253,7 @@
|
|||||||
2402:f140:ff04::/48
|
2402:f140:ff04::/48
|
||||||
2402:f140:ff10::/46
|
2402:f140:ff10::/46
|
||||||
2402:f140:ff14::/48
|
2402:f140:ff14::/48
|
||||||
|
2402:f140:ff20::/46
|
||||||
2402:f140:ff24::/48
|
2402:f140:ff24::/48
|
||||||
2402:f8c0::/42
|
2402:f8c0::/42
|
||||||
2403:1b80::/48
|
2403:1b80::/48
|
||||||
@@ -308,12 +310,11 @@
|
|||||||
2404:2280:123::/48
|
2404:2280:123::/48
|
||||||
2404:2280:125::/48
|
2404:2280:125::/48
|
||||||
2404:2280:126::/47
|
2404:2280:126::/47
|
||||||
2404:2280:128::/46
|
2404:2280:128::/47
|
||||||
2404:2280:12e::/48
|
2404:2280:12e::/48
|
||||||
2404:2280:130::/48
|
2404:2280:130::/48
|
||||||
2404:2280:134::/48
|
2404:2280:134::/48
|
||||||
2404:2280:136::/47
|
2404:2280:136::/47
|
||||||
2404:2280:138::/48
|
|
||||||
2404:2280:13b::/48
|
2404:2280:13b::/48
|
||||||
2404:2280:13c::/47
|
2404:2280:13c::/47
|
||||||
2404:2280:142::/48
|
2404:2280:142::/48
|
||||||
@@ -342,7 +343,6 @@
|
|||||||
2404:2280:19e::/48
|
2404:2280:19e::/48
|
||||||
2404:2280:1a4::/46
|
2404:2280:1a4::/46
|
||||||
2404:2280:1a8::/47
|
2404:2280:1a8::/47
|
||||||
2404:2280:1b0::/48
|
|
||||||
2404:2280:1b2::/48
|
2404:2280:1b2::/48
|
||||||
2404:2280:1b4::/46
|
2404:2280:1b4::/46
|
||||||
2404:2280:1b8::/47
|
2404:2280:1b8::/47
|
||||||
@@ -366,7 +366,6 @@
|
|||||||
2404:2280:1ee::/48
|
2404:2280:1ee::/48
|
||||||
2404:2280:1f0::/45
|
2404:2280:1f0::/45
|
||||||
2404:2280:1f8::/46
|
2404:2280:1f8::/46
|
||||||
2404:2280:1fe::/48
|
|
||||||
2404:2280:201::/48
|
2404:2280:201::/48
|
||||||
2404:2280:202::/47
|
2404:2280:202::/47
|
||||||
2404:2280:205::/48
|
2404:2280:205::/48
|
||||||
@@ -381,6 +380,7 @@
|
|||||||
2404:2280:21d::/48
|
2404:2280:21d::/48
|
||||||
2404:2280:21e::/48
|
2404:2280:21e::/48
|
||||||
2404:2280:221::/48
|
2404:2280:221::/48
|
||||||
|
2404:2280:225::/48
|
||||||
2404:2280:226::/47
|
2404:2280:226::/47
|
||||||
2404:2280:259::/48
|
2404:2280:259::/48
|
||||||
2404:2280:25a::/47
|
2404:2280:25a::/47
|
||||||
@@ -388,10 +388,7 @@
|
|||||||
2404:2280:265::/48
|
2404:2280:265::/48
|
||||||
2404:2280:266::/47
|
2404:2280:266::/47
|
||||||
2404:2280:268::/45
|
2404:2280:268::/45
|
||||||
2404:2280:270::/45
|
2404:2280:270::/44
|
||||||
2404:2280:278::/47
|
|
||||||
2404:2280:27b::/48
|
|
||||||
2404:2280:27c::/46
|
|
||||||
2404:2280:282::/47
|
2404:2280:282::/47
|
||||||
2404:2280:284::/47
|
2404:2280:284::/47
|
||||||
2404:2280:288::/46
|
2404:2280:288::/46
|
||||||
@@ -425,19 +422,18 @@
|
|||||||
2404:2280:2dc::/47
|
2404:2280:2dc::/47
|
||||||
2404:2280:2df::/48
|
2404:2280:2df::/48
|
||||||
2404:2280:2f1::/48
|
2404:2280:2f1::/48
|
||||||
2404:2280:2f2::/48
|
2404:2280:2f2::/47
|
||||||
2404:2280:2f6::/47
|
2404:2280:2f4::/46
|
||||||
2404:2280:2f8::/47
|
2404:2280:2f8::/46
|
||||||
2404:2280:2fb::/48
|
|
||||||
2404:2280:2fc::/48
|
2404:2280:2fc::/48
|
||||||
2404:2280:303::/48
|
2404:2280:303::/48
|
||||||
2404:2280:304::/46
|
2404:2280:304::/46
|
||||||
2404:2280:308::/46
|
2404:2280:308::/45
|
||||||
2404:2280:30c::/47
|
2404:2280:310::/47
|
||||||
2404:2280:30e::/48
|
|
||||||
2404:2280:313::/48
|
2404:2280:313::/48
|
||||||
2404:2280:314::/48
|
2404:2280:314::/48
|
||||||
2404:2280:316::/47
|
2404:2280:316::/47
|
||||||
|
2404:2280:31a::/48
|
||||||
2404:3700::/48
|
2404:3700::/48
|
||||||
2404:4dc0::/32
|
2404:4dc0::/32
|
||||||
2404:6380:1000::/48
|
2404:6380:1000::/48
|
||||||
@@ -525,7 +521,6 @@
|
|||||||
2406:280::/32
|
2406:280::/32
|
||||||
2406:3340::/32
|
2406:3340::/32
|
||||||
2406:3640:1::/48
|
2406:3640:1::/48
|
||||||
2406:4440:f000::/44
|
|
||||||
2406:4d00::/48
|
2406:4d00::/48
|
||||||
2406:52c0::/32
|
2406:52c0::/32
|
||||||
2406:5340:6666::/48
|
2406:5340:6666::/48
|
||||||
@@ -539,6 +534,7 @@
|
|||||||
2406:840:1800::/48
|
2406:840:1800::/48
|
||||||
2406:840:180::/48
|
2406:840:180::/48
|
||||||
2406:840:1::/48
|
2406:840:1::/48
|
||||||
|
2406:840:200::/48
|
||||||
2406:840:20::/48
|
2406:840:20::/48
|
||||||
2406:840:2380::/48
|
2406:840:2380::/48
|
||||||
2406:840:2800::/48
|
2406:840:2800::/48
|
||||||
@@ -546,7 +542,7 @@
|
|||||||
2406:840:2::/48
|
2406:840:2::/48
|
||||||
2406:840:2e0::/48
|
2406:840:2e0::/48
|
||||||
2406:840:3800::/48
|
2406:840:3800::/48
|
||||||
2406:840:380::/48
|
2406:840:380::/47
|
||||||
2406:840:3c2::/48
|
2406:840:3c2::/48
|
||||||
2406:840:3e0::/48
|
2406:840:3e0::/48
|
||||||
2406:840:4100::/47
|
2406:840:4100::/47
|
||||||
@@ -577,19 +573,24 @@
|
|||||||
2406:840:860::/48
|
2406:840:860::/48
|
||||||
2406:840:880::/46
|
2406:840:880::/46
|
||||||
2406:840:90::/48
|
2406:840:90::/48
|
||||||
|
2406:840:9110::/47
|
||||||
|
2406:840:9112::/48
|
||||||
2406:840:9178::/48
|
2406:840:9178::/48
|
||||||
2406:840:9200::/40
|
2406:840:9200::/40
|
||||||
|
2406:840:9680::/44
|
||||||
2406:840:9700::/40
|
2406:840:9700::/40
|
||||||
2406:840:9804::/46
|
2406:840:9804::/46
|
||||||
2406:840:981a::/48
|
2406:840:981a::/48
|
||||||
2406:840:981c::/46
|
2406:840:981c::/46
|
||||||
2406:840:9962::/47
|
2406:840:9962::/48
|
||||||
2406:840:9964::/48
|
2406:840:9964::/48
|
||||||
2406:840:9966::/47
|
2406:840:9966::/47
|
||||||
2406:840:996c::/48
|
2406:840:996c::/48
|
||||||
2406:840:9970::/44
|
2406:840:9977::/48
|
||||||
|
2406:840:a00::/48
|
||||||
2406:840:a10::/47
|
2406:840:a10::/47
|
||||||
2406:840:a31::/48
|
2406:840:a31::/48
|
||||||
|
2406:840:a32::/48
|
||||||
2406:840:c02::/48
|
2406:840:c02::/48
|
||||||
2406:840:c60::/48
|
2406:840:c60::/48
|
||||||
2406:840:cb8::/48
|
2406:840:cb8::/48
|
||||||
@@ -606,12 +607,12 @@
|
|||||||
2406:840:e330::/44
|
2406:840:e330::/44
|
||||||
2406:840:e57e::/48
|
2406:840:e57e::/48
|
||||||
2406:840:e600::/44
|
2406:840:e600::/44
|
||||||
|
2406:840:e620::/47
|
||||||
2406:840:e80f::/48
|
2406:840:e80f::/48
|
||||||
2406:840:eb00::/46
|
2406:840:eb00::/46
|
||||||
2406:840:eb04::/47
|
2406:840:eb04::/47
|
||||||
2406:840:eb07::/48
|
2406:840:eb07::/48
|
||||||
2406:840:eb08::/48
|
2406:840:eb08::/48
|
||||||
2406:840:eb0b::/48
|
|
||||||
2406:840:eb0f::/48
|
2406:840:eb0f::/48
|
||||||
2406:840:eb80::/42
|
2406:840:eb80::/42
|
||||||
2406:840:ee40::/47
|
2406:840:ee40::/47
|
||||||
@@ -624,7 +625,7 @@
|
|||||||
2406:840:f401::/48
|
2406:840:f401::/48
|
||||||
2406:840:f402::/48
|
2406:840:f402::/48
|
||||||
2406:840:f44f::/48
|
2406:840:f44f::/48
|
||||||
2406:840:f680::/44
|
2406:840:f683::/48
|
||||||
2406:840:f889::/48
|
2406:840:f889::/48
|
||||||
2406:840:fa01::/48
|
2406:840:fa01::/48
|
||||||
2406:840:fa40::/48
|
2406:840:fa40::/48
|
||||||
@@ -667,7 +668,6 @@
|
|||||||
2406:840:fdb0::/48
|
2406:840:fdb0::/48
|
||||||
2406:840:fdc0::/48
|
2406:840:fdc0::/48
|
||||||
2406:840:fe50::/47
|
2406:840:fe50::/47
|
||||||
2406:840:fe73::/48
|
|
||||||
2406:840:fe90::/46
|
2406:840:fe90::/46
|
||||||
2406:840:fe94::/48
|
2406:840:fe94::/48
|
||||||
2406:840:fe96::/47
|
2406:840:fe96::/47
|
||||||
@@ -730,7 +730,6 @@
|
|||||||
2407:c080:6000::/36
|
2407:c080:6000::/36
|
||||||
2407:c080:8000::/36
|
2407:c080:8000::/36
|
||||||
2407:c080::/35
|
2407:c080::/35
|
||||||
2407:d9c0::/32
|
|
||||||
2408:4000::/22
|
2408:4000::/22
|
||||||
2408:8000:1000::/36
|
2408:8000:1000::/36
|
||||||
2408:8000:2000::/35
|
2408:8000:2000::/35
|
||||||
@@ -1274,6 +1273,7 @@
|
|||||||
2408:8a27:4000::/35
|
2408:8a27:4000::/35
|
||||||
2409:2000::/31
|
2409:2000::/31
|
||||||
2409:2002::/32
|
2409:2002::/32
|
||||||
|
2409:2003:10::/44
|
||||||
2409:2003::/47
|
2409:2003::/47
|
||||||
2409:27fa::/48
|
2409:27fa::/48
|
||||||
2409:27fa:f000::/48
|
2409:27fa:f000::/48
|
||||||
@@ -1281,9 +1281,7 @@
|
|||||||
2409:27fc::/48
|
2409:27fc::/48
|
||||||
2409:27fe::/33
|
2409:27fe::/33
|
||||||
2409:8000::/20
|
2409:8000::/20
|
||||||
240a:2000::/40
|
240a:2000::/24
|
||||||
240a:2001:1000::/36
|
|
||||||
240a:2001:100::/40
|
|
||||||
240a:4002:1b00::/40
|
240a:4002:1b00::/40
|
||||||
240a:4010:8000::/33
|
240a:4010:8000::/33
|
||||||
240a:4020:83a::/48
|
240a:4020:83a::/48
|
||||||
@@ -1379,7 +1377,20 @@
|
|||||||
240a:42f0::/29
|
240a:42f0::/29
|
||||||
240a:42f8::/30
|
240a:42f8::/30
|
||||||
240a:6001::/48
|
240a:6001::/48
|
||||||
240a:a000::/20
|
240a:a000::/29
|
||||||
|
240a:a008::/30
|
||||||
|
240a:a00c::/31
|
||||||
|
240a:a00e:100::/40
|
||||||
|
240a:a00e::/48
|
||||||
|
240a:a00f::/32
|
||||||
|
240a:a010::/28
|
||||||
|
240a:a020::/27
|
||||||
|
240a:a040::/26
|
||||||
|
240a:a080::/25
|
||||||
|
240a:a100::/24
|
||||||
|
240a:a200::/23
|
||||||
|
240a:a400::/22
|
||||||
|
240a:a800::/21
|
||||||
240a:c000::/20
|
240a:c000::/20
|
||||||
240b:e001::/32
|
240b:e001::/32
|
||||||
240b:e002::/31
|
240b:e002::/31
|
||||||
@@ -1390,11 +1401,25 @@
|
|||||||
240c:c000::/20
|
240c:c000::/20
|
||||||
240d:4000::/21
|
240d:4000::/21
|
||||||
240d:c000:f1e0::/47
|
240d:c000:f1e0::/47
|
||||||
|
240d:c000:f1e3::/48
|
||||||
|
240d:c000:f1e4::/47
|
||||||
240d:c000:f1ef::/48
|
240d:c000:f1ef::/48
|
||||||
240e::/20
|
240e::/20
|
||||||
|
2602:f2dc:9d::/48
|
||||||
|
2602:f32a:30::/44
|
||||||
2602:f46d:1::/48
|
2602:f46d:1::/48
|
||||||
|
2602:f486:f0::/48
|
||||||
|
2602:f919:fef::/48
|
||||||
|
2602:f92a:1300::/47
|
||||||
|
2602:f92a:1303::/48
|
||||||
|
2602:f92a:1305::/48
|
||||||
|
2602:f92a:1306::/48
|
||||||
|
2602:f92a:1310::/48
|
||||||
|
2602:f92a:1312::/48
|
||||||
|
2602:f92a:1320::/48
|
||||||
|
2602:f92a:1322::/48
|
||||||
2602:f92a:a460::/48
|
2602:f92a:a460::/48
|
||||||
2602:f92a:a462::/48
|
2602:f92a:a462::/47
|
||||||
2602:f92a:a468::/48
|
2602:f92a:a468::/48
|
||||||
2602:f92a:a46d::/48
|
2602:f92a:a46d::/48
|
||||||
2602:f92a:a474::/48
|
2602:f92a:a474::/48
|
||||||
@@ -1404,8 +1429,8 @@
|
|||||||
2602:f9f6:402::/48
|
2602:f9f6:402::/48
|
||||||
2602:f9f6:450::/48
|
2602:f9f6:450::/48
|
||||||
2602:fa02:36::/48
|
2602:fa02:36::/48
|
||||||
|
2602:fa02:58::/48
|
||||||
2602:fa02:d00::/40
|
2602:fa02:d00::/40
|
||||||
2602:faa8:702::/48
|
|
||||||
2602:faa8:708::/47
|
2602:faa8:708::/47
|
||||||
2602:faa8:70f::/48
|
2602:faa8:70f::/48
|
||||||
2602:fbda:600::/48
|
2602:fbda:600::/48
|
||||||
@@ -1425,8 +1450,7 @@
|
|||||||
2605:9d80:9042::/48
|
2605:9d80:9042::/48
|
||||||
2605:9d80:9071::/48
|
2605:9d80:9071::/48
|
||||||
2605:9d80:9092::/48
|
2605:9d80:9092::/48
|
||||||
2804:1e48:9002::/48
|
2a04:3e00::/29
|
||||||
2a04:3e00:1002::/48
|
|
||||||
2a04:f580:8010::/47
|
2a04:f580:8010::/47
|
||||||
2a04:f580:8090::/48
|
2a04:f580:8090::/48
|
||||||
2a04:f580:8210::/47
|
2a04:f580:8210::/47
|
||||||
@@ -1434,12 +1458,10 @@
|
|||||||
2a04:f580:9010::/48
|
2a04:f580:9010::/48
|
||||||
2a04:f580:9012::/47
|
2a04:f580:9012::/47
|
||||||
2a04:f580:9020::/48
|
2a04:f580:9020::/48
|
||||||
2a04:f580:9030::/48
|
|
||||||
2a04:f580:9040::/48
|
2a04:f580:9040::/48
|
||||||
2a04:f580:9050::/48
|
2a04:f580:9050::/48
|
||||||
2a04:f580:9060::/48
|
2a04:f580:9060::/48
|
||||||
2a04:f580:9070::/48
|
2a04:f580:9070::/48
|
||||||
2a04:f580:9080::/48
|
|
||||||
2a04:f580:9210::/48
|
2a04:f580:9210::/48
|
||||||
2a04:f580:9212::/47
|
2a04:f580:9212::/47
|
||||||
2a04:f580:9220::/48
|
2a04:f580:9220::/48
|
||||||
@@ -1457,9 +1479,8 @@
|
|||||||
2a06:9801:2ba::/48
|
2a06:9801:2ba::/48
|
||||||
2a06:9801:f95::/48
|
2a06:9801:f95::/48
|
||||||
2a06:9f81:4600::/44
|
2a06:9f81:4600::/44
|
||||||
2a06:9f81:4620::/44
|
2a06:9f81:4630::/44
|
||||||
2a06:9f81:4640::/43
|
2a06:9f81:4640::/44
|
||||||
2a06:9f81:4660::/44
|
|
||||||
2a06:a005:260::/43
|
2a06:a005:260::/43
|
||||||
2a06:a005:280::/43
|
2a06:a005:280::/43
|
||||||
2a06:a005:2a0::/44
|
2a06:a005:2a0::/44
|
||||||
@@ -1470,11 +1491,9 @@
|
|||||||
2a0a:d681:e000::/40
|
2a0a:d681:e000::/40
|
||||||
2a0a:d682:d000::/36
|
2a0a:d682:d000::/36
|
||||||
2a0a:d682:e000::/35
|
2a0a:d682:e000::/35
|
||||||
2a0a:d685:1e0::/47
|
2a0a:d685:1e0::/48
|
||||||
2a0a:d685:1fb::/48
|
|
||||||
2a0a:d685:1fd::/48
|
2a0a:d685:1fd::/48
|
||||||
2a0a:d685:1fe::/47
|
2a0a:d685:1ff::/48
|
||||||
2a0a:d685:200::/47
|
|
||||||
2a0a:d685:300::/40
|
2a0a:d685:300::/40
|
||||||
2a0a:d687:f001::/48
|
2a0a:d687:f001::/48
|
||||||
2a0a:d687:f004::/47
|
2a0a:d687:f004::/47
|
||||||
@@ -1483,68 +1502,95 @@
|
|||||||
2a0b:2542:300::/40
|
2a0b:2542:300::/40
|
||||||
2a0b:4340:97::/48
|
2a0b:4340:97::/48
|
||||||
2a0b:4e07:230::/44
|
2a0b:4e07:230::/44
|
||||||
|
2a0b:a304::/30
|
||||||
2a0c:b641:571::/48
|
2a0c:b641:571::/48
|
||||||
2a0c:b641:573::/48
|
2a0c:b641:573::/48
|
||||||
2a0c:e641::/32
|
2a0c:e641::/32
|
||||||
2a0d:2681::/32
|
2a0d:2681::/32
|
||||||
|
2a0d:2901::/32
|
||||||
|
2a0d:88c4::/30
|
||||||
2a0d:c7c7:400::/38
|
2a0d:c7c7:400::/38
|
||||||
2a0d:d941::/36
|
2a0d:d941::/36
|
||||||
|
2a0e:4001:3000::/40
|
||||||
2a0e:4001:9000::/36
|
2a0e:4001:9000::/36
|
||||||
2a0e:4005:ff20::/48
|
2a0e:4005:ff20::/48
|
||||||
|
2a0e:4005:ffd0::/48
|
||||||
2a0e:4005:ffdd::/48
|
2a0e:4005:ffdd::/48
|
||||||
|
2a0e:4007:1::/48
|
||||||
|
2a0e:4007:2::/47
|
||||||
|
2a0e:4007:4::/48
|
||||||
|
2a0e:4007:6::/47
|
||||||
2a0e:aa06:400::/44
|
2a0e:aa06:400::/44
|
||||||
2a0e:aa06:440::/48
|
2a0e:aa06:440::/48
|
||||||
2a0e:aa06:450::/44
|
2a0e:aa06:450::/44
|
||||||
2a0e:aa06:490::/44
|
2a0e:aa06:490::/44
|
||||||
|
2a0e:aa07:f0dc::/48
|
||||||
|
2a0e:aa07:f0df::/48
|
||||||
2a0e:b107:14a0::/44
|
2a0e:b107:14a0::/44
|
||||||
2a0e:b107:1522::/48
|
2a0e:b107:1522::/48
|
||||||
2a0e:b107:1f0::/47
|
2a0e:b107:1f0::/47
|
||||||
|
2a0e:b107:2440::/44
|
||||||
2a0e:b107:740::/44
|
2a0e:b107:740::/44
|
||||||
2a0e:b107:da0::/44
|
2a0e:b107:da0::/44
|
||||||
2a0f:1cc5:110::/44
|
2a0f:1cc5:10::/46
|
||||||
2a0f:1cc5:130::/44
|
2a0f:1cc5:130::/44
|
||||||
2a0f:1cc5:140::/42
|
2a0f:1cc5:140::/44
|
||||||
2a0f:1cc5:14::/46
|
|
||||||
2a0f:1cc5:1600::/44
|
2a0f:1cc5:1600::/44
|
||||||
|
2a0f:1cc5:170::/44
|
||||||
2a0f:1cc5:1c01::/48
|
2a0f:1cc5:1c01::/48
|
||||||
2a0f:1cc5:1c02::/48
|
2a0f:1cc5:1c02::/48
|
||||||
2a0f:1cc5:1c30::/48
|
2a0f:1cc5:1c20::/48
|
||||||
2a0f:1cc5:2000::/40
|
2a0f:1cc5:2000::/40
|
||||||
2a0f:1cc5:2510::/44
|
2a0f:1cc5:2550::/48
|
||||||
2a0f:1cc5:2520::/44
|
|
||||||
2a0f:1cc5:2600::/41
|
2a0f:1cc5:2600::/41
|
||||||
2a0f:1cc5:2680::/42
|
2a0f:1cc5:2680::/42
|
||||||
2a0f:1cc5:2d01::/48
|
2a0f:1cc5:2d01::/48
|
||||||
2a0f:1cc5:3203::/48
|
2a0f:1cc5:3203::/48
|
||||||
|
2a0f:1cc5:3210::/44
|
||||||
2a0f:1cc5:3222::/48
|
2a0f:1cc5:3222::/48
|
||||||
2a0f:1cc5:3700::/43
|
2a0f:1cc5:3700::/43
|
||||||
|
2a0f:1cc5:3720::/48
|
||||||
2a0f:1cc5:4300::/40
|
2a0f:1cc5:4300::/40
|
||||||
2a0f:1cc5:4508::/45
|
2a0f:1cc5:4508::/45
|
||||||
2a0f:1cc5:4510::/45
|
2a0f:1cc5:4510::/44
|
||||||
2a0f:1cc5:451c::/46
|
2a0f:1cc5:4520::/46
|
||||||
|
2a0f:1cc5:4560::/44
|
||||||
2a0f:1cc5:45ff::/48
|
2a0f:1cc5:45ff::/48
|
||||||
2a0f:1cc5:4600::/39
|
2a0f:1cc5:4600::/39
|
||||||
2a0f:1cc5:49f0::/48
|
2a0f:1cc5:49f0::/48
|
||||||
|
2a0f:1cc5:57fb::/48
|
||||||
|
2a0f:1cc5:57fc::/47
|
||||||
|
2a0f:1cc5:57ff::/48
|
||||||
2a0f:1cc5:600::/47
|
2a0f:1cc5:600::/47
|
||||||
2a0f:1cc5:603::/48
|
2a0f:1cc5:603::/48
|
||||||
|
2a0f:1cc5:620::/48
|
||||||
2a0f:1cc5:642::/48
|
2a0f:1cc5:642::/48
|
||||||
2a0f:1cc5:644::/48
|
2a0f:1cc5:644::/48
|
||||||
2a0f:1cc5:662::/48
|
2a0f:1cc5:661::/48
|
||||||
2a0f:1cc5:6a0::/47
|
2a0f:1cc5:6a0::/47
|
||||||
|
2a0f:1cc5:d00::/48
|
||||||
2a0f:1cc5:f00::/46
|
2a0f:1cc5:f00::/46
|
||||||
2a0f:1cc5:f05::/48
|
2a0f:1cc5:f05::/48
|
||||||
2a0f:1cc5:f06::/47
|
2a0f:1cc5:f06::/47
|
||||||
2a0f:1cc5:f08::/47
|
2a0f:1cc5:f08::/47
|
||||||
|
2a0f:1cc5:f10::/48
|
||||||
|
2a0f:1cc5:f12::/47
|
||||||
2a0f:1cc5:fff::/48
|
2a0f:1cc5:fff::/48
|
||||||
2a0f:1cc6:b110::/47
|
2a0f:1cc6:b110::/48
|
||||||
2a0f:1cc6:b210::/48
|
2a0f:1cc6:b210::/47
|
||||||
2a0f:1cc6:b212::/48
|
2a0f:1cc6:b212::/48
|
||||||
2a0f:1cc6:b240::/43
|
2a0f:1cc6:b240::/43
|
||||||
|
2a0f:1cc6:b271::/48
|
||||||
|
2a0f:2384::/30
|
||||||
2a0f:2706::/32
|
2a0f:2706::/32
|
||||||
2a0f:6280:1400::/43
|
2a0f:4684::/30
|
||||||
2a0f:6280:1440::/42
|
2a0f:6280:1400::/41
|
||||||
2a0f:6280:1480::/44
|
2a0f:6280:1480::/44
|
||||||
2a0f:6281::/32
|
2a0f:6280:14a0::/44
|
||||||
|
2a0f:6280:7000::/38
|
||||||
|
2a0f:6280:7400::/39
|
||||||
|
2a0f:6280:7800::/39
|
||||||
|
2a0f:6284:4c00::/44
|
||||||
2a0f:6284:4c20::/44
|
2a0f:6284:4c20::/44
|
||||||
2a0f:6284:4c30::/48
|
2a0f:6284:4c30::/48
|
||||||
2a0f:6284:4c40::/43
|
2a0f:6284:4c40::/43
|
||||||
@@ -1552,64 +1598,61 @@
|
|||||||
2a0f:6284:4c80::/43
|
2a0f:6284:4c80::/43
|
||||||
2a0f:6284:4ca0::/44
|
2a0f:6284:4ca0::/44
|
||||||
2a0f:6284:4cc0::/43
|
2a0f:6284:4cc0::/43
|
||||||
|
2a0f:7304::/30
|
||||||
2a0f:85c1:bfe::/48
|
2a0f:85c1:bfe::/48
|
||||||
2a0f:9400:6110::/48
|
2a0f:9400:6110::/48
|
||||||
2a0f:9fc0::/29
|
2a0f:a704::/30
|
||||||
2a0f:a140::/29
|
|
||||||
2a10:ccc0:cc1::/48
|
2a10:ccc0:cc1::/48
|
||||||
2a10:ccc0:cc2::/48
|
2a10:ccc0:cc2::/48
|
||||||
2a10:ccc0:ccc::/48
|
2a10:ccc0:ccc::/48
|
||||||
2a10:fa81:d00::/40
|
2a10:fa81:d00::/40
|
||||||
2a10:fa86:4000::/36
|
|
||||||
2a10:fa86::/34
|
2a10:fa86::/34
|
||||||
2a10:fa86:c000::/34
|
2a10:fa86:c000::/34
|
||||||
2a12:3fc6:2::/48
|
2a12:3fc6:4::/48
|
||||||
2a12:3fc6::/47
|
2a12:3fc6::/46
|
||||||
2a12:cb40:1::/48
|
2a12:cb40:1::/48
|
||||||
2a12:cb40:2::/48
|
2a12:cb40:2::/48
|
||||||
2a12:cb41:1200::/44
|
2a12:cb41:1200::/44
|
||||||
2a12:cb41:1300::/44
|
2a12:cb41:1300::/44
|
||||||
2a12:cb41:13f0::/44
|
2a12:cb41:13f0::/44
|
||||||
2a12:cb41:600::/44
|
2a12:cb41:600::/44
|
||||||
|
2a12:cb46:6000::/38
|
||||||
2a12:cb46::/36
|
2a12:cb46::/36
|
||||||
2a12:cb47:ffff::/48
|
2a12:cb47:ffff::/48
|
||||||
2a13:1801:180::/43
|
2a13:1801:180::/43
|
||||||
2a13:1801:200::/44
|
2a13:1801:200::/44
|
||||||
2a13:1802::/43
|
2a13:1802::/43
|
||||||
2a13:8c87::/32
|
2a13:9500:194::/48
|
||||||
2a13:9500:194::/47
|
|
||||||
2a13:a5c3:f000::/40
|
2a13:a5c3:f000::/40
|
||||||
2a13:a5c3:ff50::/44
|
2a13:a5c3:ff50::/44
|
||||||
2a13:a5c5::/48
|
2a13:a5c5::/48
|
||||||
2a13:aac4:f000::/44
|
2a13:aac4:f000::/44
|
||||||
2a13:b487:1200::/42
|
2a13:b487:1200::/44
|
||||||
2a13:c8c3:e803::/48
|
2a13:b487:1220::/43
|
||||||
2a13:e5c0:ee02::/48
|
2a13:e5c0:ee02::/48
|
||||||
2a14:4380::/29
|
|
||||||
2a14:5f00::/29
|
2a14:5f00::/29
|
||||||
2a14:67c1:b500::/40
|
2a14:67c1:b500::/40
|
||||||
2a14:67c2:519::/48
|
|
||||||
2a14:67c2:520::/48
|
2a14:67c2:520::/48
|
||||||
2a14:67c3:1100::/47
|
2a14:67c3:1100::/47
|
||||||
2a14:67c3:190::/47
|
2a14:67c3:190::/47
|
||||||
2a14:67c3:192::/48
|
2a14:67c3:192::/48
|
||||||
2a14:67c3:30::/44
|
2a14:67c3:30::/44
|
||||||
|
2a14:67c3:8800::/44
|
||||||
2a14:7580:740::/44
|
2a14:7580:740::/44
|
||||||
2a14:7580:d10::/44
|
2a14:7580:d00::/43
|
||||||
2a14:7580:d20::/46
|
2a14:7580:d20::/46
|
||||||
|
2a14:7580:d41::/48
|
||||||
|
2a14:7580:d42::/47
|
||||||
|
2a14:7580:ff64::/48
|
||||||
2a14:7580:ffee::/48
|
2a14:7580:ffee::/48
|
||||||
2a14:7580:fff3::/48
|
2a14:7580:fff3::/48
|
||||||
2a14:7580:fffa::/48
|
|
||||||
2a14:7581:3810::/48
|
2a14:7581:3810::/48
|
||||||
2a14:7581:3814::/48
|
2a14:7581:fe1::/48
|
||||||
2a14:7581:3818::/48
|
2a14:7583:e900::/48
|
||||||
2a14:7582:7000::/36
|
|
||||||
2a14:7583:efe7::/48
|
2a14:7583:efe7::/48
|
||||||
2a14:7583:efef::/48
|
|
||||||
2a14:7583:f411::/48
|
2a14:7583:f411::/48
|
||||||
2a14:7583:f4f0::/48
|
2a14:7583:f4f0::/48
|
||||||
2a14:7583:f4f4::/48
|
2a14:7583:f4f4::/48
|
||||||
2a14:7583:f4fe::/48
|
|
||||||
2a14:7583:f701::/48
|
2a14:7583:f701::/48
|
||||||
2a14:7583:f703::/48
|
2a14:7583:f703::/48
|
||||||
2a14:7583:f704::/47
|
2a14:7583:f704::/47
|
||||||
@@ -1620,18 +1663,17 @@
|
|||||||
2a14:7583:f744::/48
|
2a14:7583:f744::/48
|
||||||
2a14:7583:f764::/48
|
2a14:7583:f764::/48
|
||||||
2a14:7586:6103::/48
|
2a14:7586:6103::/48
|
||||||
2a14:7586:6104::/47
|
2a14:7586:6104::/48
|
||||||
2a14:7586:6106::/48
|
2a14:7586:6106::/47
|
||||||
2a14:7586:6108::/48
|
2a14:7586:6108::/48
|
||||||
2a14:7586:6110::/48
|
2a14:7586:6110::/48
|
||||||
|
2a14:7586:6113::/48
|
||||||
|
2a14:7586:6115::/48
|
||||||
2a14:7586:6300::/44
|
2a14:7586:6300::/44
|
||||||
2a14:ae00:50::/44
|
|
||||||
2c0f:f7a8:8011::/48
|
2c0f:f7a8:8011::/48
|
||||||
2c0f:f7a8:8050::/48
|
2c0f:f7a8:8050::/48
|
||||||
2c0f:f7a8:805f::/48
|
2c0f:f7a8:805f::/48
|
||||||
2c0f:f7a8:8150::/48
|
2c0f:f7a8:8150::/48
|
||||||
2c0f:f7a8:815f::/48
|
2c0f:f7a8:815f::/48
|
||||||
2c0f:f7a8:8211::/48
|
2c0f:f7a8:8211::/48
|
||||||
2c0f:f7a8:9020::/48
|
|
||||||
2c0f:f7a8:9041::/48
|
2c0f:f7a8:9041::/48
|
||||||
2c0f:f7a8:9220::/48
|
|
||||||
@@ -4,6 +4,9 @@
|
|||||||
1000giri.net
|
1000giri.net
|
||||||
10beasts.net
|
10beasts.net
|
||||||
10musume.com
|
10musume.com
|
||||||
|
123av.com
|
||||||
|
123av.me
|
||||||
|
123av.org
|
||||||
12bet.com
|
12bet.com
|
||||||
12vpn.com
|
12vpn.com
|
||||||
12vpn.net
|
12vpn.net
|
||||||
@@ -56,6 +59,7 @@
|
|||||||
6parker.com
|
6parker.com
|
||||||
6parknews.com
|
6parknews.com
|
||||||
7capture.com
|
7capture.com
|
||||||
|
7x24hrs.com
|
||||||
8-d.com
|
8-d.com
|
||||||
85cc.us
|
85cc.us
|
||||||
881903.com
|
881903.com
|
||||||
@@ -128,6 +132,7 @@ agoogleaday.com
|
|||||||
agro.hk
|
agro.hk
|
||||||
ai.dev
|
ai.dev
|
||||||
ai.studio
|
ai.studio
|
||||||
|
aidc.com.tw
|
||||||
aihub.top
|
aihub.top
|
||||||
aiosearch.com
|
aiosearch.com
|
||||||
aiph.net
|
aiph.net
|
||||||
@@ -213,19 +218,15 @@ aoxvpn.com
|
|||||||
apartmentratings.com
|
apartmentratings.com
|
||||||
apartments.com
|
apartments.com
|
||||||
apat1989.org
|
apat1989.org
|
||||||
api-gl.lbkrs.com
|
|
||||||
api-secure.recaptcha.net
|
api-secure.recaptcha.net
|
||||||
api-verify.recaptcha.net
|
api-verify.recaptcha.net
|
||||||
api.ai
|
api.ai
|
||||||
api.futunn.com
|
|
||||||
api.lbkrs.com
|
|
||||||
api.moomoobull.com
|
api.moomoobull.com
|
||||||
api.palworldgame.com
|
api.palworldgame.com
|
||||||
api.pureapk.com
|
api.pureapk.com
|
||||||
api.recaptcha.net
|
api.recaptcha.net
|
||||||
api.shuaiapi.com
|
api.shuaiapi.com
|
||||||
api.steampowered.com
|
api.steampowered.com
|
||||||
api5.futunn.com
|
|
||||||
apiary.io
|
apiary.io
|
||||||
apigee.com
|
apigee.com
|
||||||
apk.support
|
apk.support
|
||||||
@@ -530,6 +531,7 @@ bloomberg.de
|
|||||||
bloombergview.com
|
bloombergview.com
|
||||||
bloomfortune.com
|
bloomfortune.com
|
||||||
blubrry.com
|
blubrry.com
|
||||||
|
blue-plus.net
|
||||||
bmdru.com
|
bmdru.com
|
||||||
bnbstatic.com
|
bnbstatic.com
|
||||||
bnext.com.tw
|
bnext.com.tw
|
||||||
@@ -552,6 +554,7 @@ bowenpress.com
|
|||||||
boxpn.com
|
boxpn.com
|
||||||
boxun.com
|
boxun.com
|
||||||
boxun.tv
|
boxun.tv
|
||||||
|
boylove.cc
|
||||||
boysmaster.com
|
boysmaster.com
|
||||||
br.st
|
br.st
|
||||||
braumeister.org
|
braumeister.org
|
||||||
@@ -612,6 +615,7 @@ byrut.org
|
|||||||
c-est-simple.com
|
c-est-simple.com
|
||||||
c-span.org
|
c-span.org
|
||||||
c-spanvideo.org
|
c-spanvideo.org
|
||||||
|
c.go-mpulse.net
|
||||||
c.mi.com
|
c.mi.com
|
||||||
c2cx.com
|
c2cx.com
|
||||||
c3pool.com
|
c3pool.com
|
||||||
@@ -627,6 +631,7 @@ camfrog.com
|
|||||||
campaign-archive.com
|
campaign-archive.com
|
||||||
campaignforuyghurs.org
|
campaignforuyghurs.org
|
||||||
cams.com
|
cams.com
|
||||||
|
cangku.moe
|
||||||
canva.com
|
canva.com
|
||||||
canyu.org
|
canyu.org
|
||||||
caobian.info
|
caobian.info
|
||||||
@@ -669,7 +674,6 @@ cdjp.org
|
|||||||
cdn-images.mailchimp.com
|
cdn-images.mailchimp.com
|
||||||
cdn-telegram.org
|
cdn-telegram.org
|
||||||
cdn.arstechnica.net
|
cdn.arstechnica.net
|
||||||
cdn.futustatic.com
|
|
||||||
cdn.jwplayer.com
|
cdn.jwplayer.com
|
||||||
cdn.printfriendly.com
|
cdn.printfriendly.com
|
||||||
cdn.seatguru.com
|
cdn.seatguru.com
|
||||||
@@ -757,6 +761,7 @@ chinesedemocracy.com
|
|||||||
chinesegay.org
|
chinesegay.org
|
||||||
chinesen.de
|
chinesen.de
|
||||||
chinesenews.net.au
|
chinesenews.net.au
|
||||||
|
chineseposters.net
|
||||||
chineseradioseattle.com
|
chineseradioseattle.com
|
||||||
chineseupress.com
|
chineseupress.com
|
||||||
chingcheong.com
|
chingcheong.com
|
||||||
@@ -819,7 +824,6 @@ cn.fmnnow.com
|
|||||||
cn.sandscotaicentral.com
|
cn.sandscotaicentral.com
|
||||||
cn.shafaqna.com
|
cn.shafaqna.com
|
||||||
cn.theaustralian.com.au
|
cn.theaustralian.com.au
|
||||||
cn.uptodown.com
|
|
||||||
cna.com.tw
|
cna.com.tw
|
||||||
cnbbnews.wordpress.com
|
cnbbnews.wordpress.com
|
||||||
cnbeta.com.tw
|
cnbeta.com.tw
|
||||||
@@ -856,6 +860,7 @@ comparitech.com
|
|||||||
compileheart.com
|
compileheart.com
|
||||||
connect.facebook.net
|
connect.facebook.net
|
||||||
conoha.jp
|
conoha.jp
|
||||||
|
console.typesafe.ai
|
||||||
contests.twilio.com
|
contests.twilio.com
|
||||||
cool18.com
|
cool18.com
|
||||||
coolaler.com
|
coolaler.com
|
||||||
@@ -871,6 +876,7 @@ counter.social
|
|||||||
coursehero.com
|
coursehero.com
|
||||||
covenantswatch.org.tw
|
covenantswatch.org.tw
|
||||||
coze.com
|
coze.com
|
||||||
|
cpc.com.tw
|
||||||
cpj.org
|
cpj.org
|
||||||
cpu-monkey.com
|
cpu-monkey.com
|
||||||
cq99.us
|
cq99.us
|
||||||
@@ -893,6 +899,7 @@ crrev.com
|
|||||||
crucial.com
|
crucial.com
|
||||||
crunchyroll.com
|
crunchyroll.com
|
||||||
cruxpool.com
|
cruxpool.com
|
||||||
|
csc.com.tw
|
||||||
csdparty.com
|
csdparty.com
|
||||||
csis.org
|
csis.org
|
||||||
csmonitor.com
|
csmonitor.com
|
||||||
@@ -900,6 +907,7 @@ css.pixnet.in
|
|||||||
csuchen.de
|
csuchen.de
|
||||||
csw.org.uk
|
csw.org.uk
|
||||||
ct.org.tw
|
ct.org.tw
|
||||||
|
ctee.com.tw
|
||||||
ctinets.com
|
ctinets.com
|
||||||
ctinews.com
|
ctinews.com
|
||||||
ctinsider.com
|
ctinsider.com
|
||||||
@@ -981,6 +989,7 @@ deviantart.net
|
|||||||
devio.us
|
devio.us
|
||||||
devpn.com
|
devpn.com
|
||||||
devv.ai
|
devv.ai
|
||||||
|
dh.net
|
||||||
diaoyuislands.org
|
diaoyuislands.org
|
||||||
digiland.tw
|
digiland.tw
|
||||||
digisfera.com
|
digisfera.com
|
||||||
@@ -1047,7 +1056,6 @@ dougscripts.com
|
|||||||
doujincafe.com
|
doujincafe.com
|
||||||
dowjones.io
|
dowjones.io
|
||||||
download.dappcdn.com
|
download.dappcdn.com
|
||||||
download.futunn.com
|
|
||||||
dpool.top
|
dpool.top
|
||||||
dpp.org.tw
|
dpp.org.tw
|
||||||
dpr.info
|
dpr.info
|
||||||
@@ -1168,6 +1176,7 @@ everipedia.org
|
|||||||
evschool.net
|
evschool.net
|
||||||
exchristian.hk
|
exchristian.hk
|
||||||
exhentai.org
|
exhentai.org
|
||||||
|
eximbank.com.tw
|
||||||
exmo.com
|
exmo.com
|
||||||
exmormon.org
|
exmormon.org
|
||||||
expatshield.com
|
expatshield.com
|
||||||
@@ -1397,6 +1406,7 @@ futuremessage.org
|
|||||||
futustatic.com
|
futustatic.com
|
||||||
fututrade.com
|
fututrade.com
|
||||||
fututrustee.com
|
fututrustee.com
|
||||||
|
fuyin116.com
|
||||||
fw.cm
|
fw.cm
|
||||||
fxcm-chinese.com
|
fxcm-chinese.com
|
||||||
fxnetworks.com
|
fxnetworks.com
|
||||||
@@ -1406,6 +1416,7 @@ g.ai
|
|||||||
g.co
|
g.co
|
||||||
g0v.social
|
g0v.social
|
||||||
g6hentai.com
|
g6hentai.com
|
||||||
|
ga.jspm.io
|
||||||
gab.com
|
gab.com
|
||||||
gabocorp.com
|
gabocorp.com
|
||||||
gagaoolala.com
|
gagaoolala.com
|
||||||
@@ -1819,7 +1830,9 @@ haiwaikan.com
|
|||||||
hakkatv.org.tw
|
hakkatv.org.tw
|
||||||
halktv.com.tr
|
halktv.com.tr
|
||||||
hanime.tv
|
hanime.tv
|
||||||
|
hanime1.com
|
||||||
hanime1.me
|
hanime1.me
|
||||||
|
hanimeone.me
|
||||||
hardsextube.com
|
hardsextube.com
|
||||||
hautelook.com
|
hautelook.com
|
||||||
hautelookcdn.com
|
hautelookcdn.com
|
||||||
@@ -1841,6 +1854,8 @@ help.byspotify.com
|
|||||||
helpeachpeople.com
|
helpeachpeople.com
|
||||||
helpster.de
|
helpster.de
|
||||||
hembed.com
|
hembed.com
|
||||||
|
hentai.tv
|
||||||
|
hentaiclub.net
|
||||||
heqinglian.net
|
heqinglian.net
|
||||||
heritage.org
|
heritage.org
|
||||||
herokuapp.com
|
herokuapp.com
|
||||||
@@ -1883,6 +1898,7 @@ hkcnews.com
|
|||||||
hkcoc.com
|
hkcoc.com
|
||||||
hkcoc.weather.com.hk
|
hkcoc.weather.com.hk
|
||||||
hkdc.us
|
hkdc.us
|
||||||
|
hkej.com
|
||||||
hket.com
|
hket.com
|
||||||
hkfaa.com
|
hkfaa.com
|
||||||
hkgalden.com
|
hkgalden.com
|
||||||
@@ -1985,6 +2001,7 @@ iam.soy
|
|||||||
iask.ca
|
iask.ca
|
||||||
iavian.net
|
iavian.net
|
||||||
ibvpn.com
|
ibvpn.com
|
||||||
|
icdf.org.tw
|
||||||
icedrive.net
|
icedrive.net
|
||||||
icij.org
|
icij.org
|
||||||
icl-fi.org
|
icl-fi.org
|
||||||
@@ -2042,6 +2059,7 @@ indianarrative.com
|
|||||||
indiandefensenews.in
|
indiandefensenews.in
|
||||||
indiatoday.in
|
indiatoday.in
|
||||||
indiemerch.com
|
indiemerch.com
|
||||||
|
indsr.org.tw
|
||||||
inews-api.tvb.com
|
inews-api.tvb.com
|
||||||
info-graf.fr
|
info-graf.fr
|
||||||
infosec.exchange
|
infosec.exchange
|
||||||
@@ -2068,6 +2086,7 @@ investigating.wordpress.com
|
|||||||
investing.com
|
investing.com
|
||||||
invidio.us
|
invidio.us
|
||||||
inxian.com
|
inxian.com
|
||||||
|
ipac.global
|
||||||
ipdefenseforum.com
|
ipdefenseforum.com
|
||||||
ipfire.org
|
ipfire.org
|
||||||
ipfs.4everland.io
|
ipfs.4everland.io
|
||||||
@@ -2126,9 +2145,11 @@ japantimes.co.jp
|
|||||||
jav321.com
|
jav321.com
|
||||||
javakiba.org
|
javakiba.org
|
||||||
javbus.com
|
javbus.com
|
||||||
|
javchu.com
|
||||||
javdb.com
|
javdb.com
|
||||||
javfinder.ai
|
javfinder.ai
|
||||||
javfor.me
|
javfor.me
|
||||||
|
javfree.me
|
||||||
javhub.net
|
javhub.net
|
||||||
javhuge.com
|
javhuge.com
|
||||||
javlibrary.com
|
javlibrary.com
|
||||||
@@ -2150,6 +2171,7 @@ jintian.net
|
|||||||
jinx.com
|
jinx.com
|
||||||
jitouch.com
|
jitouch.com
|
||||||
jkb.cc
|
jkb.cc
|
||||||
|
jkforum.net
|
||||||
jma.go.jp
|
jma.go.jp
|
||||||
jmsc.hku.hk
|
jmsc.hku.hk
|
||||||
jmscult.com
|
jmscult.com
|
||||||
@@ -2197,9 +2219,11 @@ kex.com
|
|||||||
keycdn.com
|
keycdn.com
|
||||||
kfor.com
|
kfor.com
|
||||||
khatrimaza.org
|
khatrimaza.org
|
||||||
|
khc.edu.tw
|
||||||
kichiku-doujinko.com
|
kichiku-doujinko.com
|
||||||
kik.com
|
kik.com
|
||||||
killwall.com
|
killwall.com
|
||||||
|
kimootoko.net
|
||||||
kindle4rss.com
|
kindle4rss.com
|
||||||
kindleren.com
|
kindleren.com
|
||||||
kingdomsalvation.org
|
kingdomsalvation.org
|
||||||
@@ -2242,6 +2266,7 @@ lala.im
|
|||||||
lama.com.tw
|
lama.com.tw
|
||||||
lamayeshe.com
|
lamayeshe.com
|
||||||
lamnia.co.uk
|
lamnia.co.uk
|
||||||
|
landbank.com.tw
|
||||||
landofhope.tv
|
landofhope.tv
|
||||||
lantern.io
|
lantern.io
|
||||||
laogai.org
|
laogai.org
|
||||||
@@ -2305,6 +2330,7 @@ linkedin.com
|
|||||||
linktr.ee
|
linktr.ee
|
||||||
linux.do
|
linux.do
|
||||||
linux.org.hk
|
linux.org.hk
|
||||||
|
linux.sb
|
||||||
liquiditytp.com
|
liquiditytp.com
|
||||||
liquidvpn.com
|
liquidvpn.com
|
||||||
listennotes.com
|
listennotes.com
|
||||||
@@ -2359,7 +2385,6 @@ lvv2.com
|
|||||||
lyfhk.net
|
lyfhk.net
|
||||||
lzjscript.com
|
lzjscript.com
|
||||||
lzmtnews.org
|
lzmtnews.org
|
||||||
m.hkgalden.com
|
|
||||||
m.me
|
m.me
|
||||||
m.moegirl.org
|
m.moegirl.org
|
||||||
macgamestore.com
|
macgamestore.com
|
||||||
@@ -2395,6 +2420,7 @@ mastodon.social
|
|||||||
mastodon.xyz
|
mastodon.xyz
|
||||||
matainja.com
|
matainja.com
|
||||||
material.io
|
material.io
|
||||||
|
matichon.co.th
|
||||||
matome-plus.com
|
matome-plus.com
|
||||||
matome-plus.net
|
matome-plus.net
|
||||||
matrix.org
|
matrix.org
|
||||||
@@ -2438,7 +2464,9 @@ meridian-trust.org
|
|||||||
meripet.com
|
meripet.com
|
||||||
merit-times.com.tw
|
merit-times.com.tw
|
||||||
messenger.com
|
messenger.com
|
||||||
|
meta.ai
|
||||||
meta.com
|
meta.com
|
||||||
|
metaaivm.com
|
||||||
metafilter.com
|
metafilter.com
|
||||||
metamask.io
|
metamask.io
|
||||||
metart.com
|
metart.com
|
||||||
@@ -2478,13 +2506,17 @@ mingshengbao.com
|
|||||||
minhhue.net
|
minhhue.net
|
||||||
miningpoolhub.com
|
miningpoolhub.com
|
||||||
ministrybooks.org
|
ministrybooks.org
|
||||||
|
minkch.com
|
||||||
minzhuzhongguo.org
|
minzhuzhongguo.org
|
||||||
miraheze.org
|
miraheze.org
|
||||||
|
mirdc.org.tw
|
||||||
miroguide.com
|
miroguide.com
|
||||||
mirror.xyz
|
mirror.xyz
|
||||||
mirrorbooks.com
|
mirrorbooks.com
|
||||||
mirrormedia.mg
|
mirrormedia.mg
|
||||||
|
missav.ai
|
||||||
missav.com
|
missav.com
|
||||||
|
missav.live
|
||||||
missav.ws
|
missav.ws
|
||||||
mistral.ai
|
mistral.ai
|
||||||
mitbbs.com
|
mitbbs.com
|
||||||
@@ -2508,6 +2540,7 @@ moby.to
|
|||||||
mod.io
|
mod.io
|
||||||
modernchinastudies.org
|
modernchinastudies.org
|
||||||
moeerolibrary.com
|
moeerolibrary.com
|
||||||
|
moeli-desu.com
|
||||||
moeshare.cc
|
moeshare.cc
|
||||||
mog.com
|
mog.com
|
||||||
mohu.club
|
mohu.club
|
||||||
@@ -2535,6 +2568,7 @@ mos.ru
|
|||||||
mosavi.io
|
mosavi.io
|
||||||
motherless.com
|
motherless.com
|
||||||
movements.org
|
movements.org
|
||||||
|
movie.eroterest.net
|
||||||
moviefap.com
|
moviefap.com
|
||||||
mpettis.com
|
mpettis.com
|
||||||
mpfinance.com
|
mpfinance.com
|
||||||
@@ -2548,6 +2582,7 @@ mthruf.com
|
|||||||
mubi.com
|
mubi.com
|
||||||
mullvad.net
|
mullvad.net
|
||||||
multiply.com
|
multiply.com
|
||||||
|
muse.ai
|
||||||
music.amazon.com
|
music.amazon.com
|
||||||
musixmatch.com
|
musixmatch.com
|
||||||
muzi.com
|
muzi.com
|
||||||
@@ -2586,6 +2621,7 @@ national-lottery.co.uk
|
|||||||
nationalawakening.org
|
nationalawakening.org
|
||||||
nationalinterest.org
|
nationalinterest.org
|
||||||
nationalreview.com
|
nationalreview.com
|
||||||
|
nationthailand.com
|
||||||
nationwide.com
|
nationwide.com
|
||||||
naughtyamerica.com
|
naughtyamerica.com
|
||||||
naver.com
|
naver.com
|
||||||
@@ -2597,6 +2633,7 @@ nbyy.tv
|
|||||||
nchrd.org
|
nchrd.org
|
||||||
ncn.org
|
ncn.org
|
||||||
ndi.org
|
ndi.org
|
||||||
|
ned.org
|
||||||
nekoslovakia.net
|
nekoslovakia.net
|
||||||
neo-miracle.com
|
neo-miracle.com
|
||||||
neodb.social
|
neodb.social
|
||||||
@@ -2665,6 +2702,9 @@ nitter.net
|
|||||||
niu.moe
|
niu.moe
|
||||||
niusnews.com
|
niusnews.com
|
||||||
njactb.org
|
njactb.org
|
||||||
|
njav.com
|
||||||
|
njav.tv
|
||||||
|
njavtv.com
|
||||||
nlfreevpn.com
|
nlfreevpn.com
|
||||||
nmsl.website
|
nmsl.website
|
||||||
nnews.eu
|
nnews.eu
|
||||||
@@ -2677,6 +2717,7 @@ nordstromimage.com
|
|||||||
nordstromrack.com
|
nordstromrack.com
|
||||||
nordvpn.com
|
nordvpn.com
|
||||||
nos.nl
|
nos.nl
|
||||||
|
note.com
|
||||||
notepad-plus-plus.org
|
notepad-plus-plus.org
|
||||||
nottinghampost.com
|
nottinghampost.com
|
||||||
now.com
|
now.com
|
||||||
@@ -2687,6 +2728,7 @@ npnt.me
|
|||||||
npsboost.com
|
npsboost.com
|
||||||
nradio.me
|
nradio.me
|
||||||
nrk.no
|
nrk.no
|
||||||
|
nstc.org.tw
|
||||||
ntd.tv
|
ntd.tv
|
||||||
ntdtv.com
|
ntdtv.com
|
||||||
ntdtv.com.tw
|
ntdtv.com.tw
|
||||||
@@ -2768,12 +2810,8 @@ ooni.org
|
|||||||
open.firstory.me
|
open.firstory.me
|
||||||
openai.com
|
openai.com
|
||||||
openapi-quote.longbridge.cn
|
openapi-quote.longbridge.cn
|
||||||
openapi-quote.longbridge.com
|
|
||||||
openapi-trade.longbridge.cn
|
openapi-trade.longbridge.cn
|
||||||
openapi-trade.longbridge.com
|
|
||||||
openapi.futunn.com
|
|
||||||
openapi.longbridge.cn
|
openapi.longbridge.cn
|
||||||
openapi.longbridge.com
|
|
||||||
openart.ai
|
openart.ai
|
||||||
opencritic.com
|
opencritic.com
|
||||||
opendemocracy.net
|
opendemocracy.net
|
||||||
@@ -2920,6 +2958,7 @@ plexvpn.pro
|
|||||||
plurk.com
|
plurk.com
|
||||||
plus.codes
|
plus.codes
|
||||||
pmatehunter.com
|
pmatehunter.com
|
||||||
|
po-kaki-to.com
|
||||||
po2b.com
|
po2b.com
|
||||||
podbean.com
|
podbean.com
|
||||||
podcast.co
|
podcast.co
|
||||||
@@ -2929,6 +2968,7 @@ poe.com
|
|||||||
points-media.com
|
points-media.com
|
||||||
pokerstars.com
|
pokerstars.com
|
||||||
pokerstars.net
|
pokerstars.net
|
||||||
|
poland.tw
|
||||||
politicalchina.org
|
politicalchina.org
|
||||||
poloniex.com
|
poloniex.com
|
||||||
polymarket.com
|
polymarket.com
|
||||||
@@ -3024,14 +3064,15 @@ qianglie.com
|
|||||||
qiangwaikan.com
|
qiangwaikan.com
|
||||||
qiangyou.org
|
qiangyou.org
|
||||||
qianmo.tw
|
qianmo.tw
|
||||||
|
qingse.one
|
||||||
qiwen.lu
|
qiwen.lu
|
||||||
qmp4.com
|
qmp4.com
|
||||||
|
qobuz.com
|
||||||
qoos.com
|
qoos.com
|
||||||
qq.co.za
|
qq.co.za
|
||||||
qstatus.com
|
qstatus.com
|
||||||
qtcard.futunn.com
|
|
||||||
qtcardfthk.futufin.com
|
|
||||||
qtrac.eu
|
qtrac.eu
|
||||||
|
quakemachinex.com
|
||||||
questvisual.com
|
questvisual.com
|
||||||
quitccp.org
|
quitccp.org
|
||||||
quiz.directory
|
quiz.directory
|
||||||
@@ -3122,15 +3163,18 @@ rlwlw.com
|
|||||||
rmbl.ws
|
rmbl.ws
|
||||||
roblox.com
|
roblox.com
|
||||||
robustnessiskey.com
|
robustnessiskey.com
|
||||||
|
roc-taiwan.org
|
||||||
rocket-inc.net
|
rocket-inc.net
|
||||||
rocket.chat
|
rocket.chat
|
||||||
rocksdb.org
|
rocksdb.org
|
||||||
|
rocmgov.org
|
||||||
rojo.com
|
rojo.com
|
||||||
rolfoundation.org
|
rolfoundation.org
|
||||||
rolia.net
|
rolia.net
|
||||||
rolsociety.org
|
rolsociety.org
|
||||||
ronjoneswriter.com
|
ronjoneswriter.com
|
||||||
rou.video
|
rou.video
|
||||||
|
roushuwo.com
|
||||||
rsdlmonitor.com
|
rsdlmonitor.com
|
||||||
rsf-chinese.org
|
rsf-chinese.org
|
||||||
rsf.org
|
rsf.org
|
||||||
@@ -3264,6 +3308,7 @@ simpleswap.io
|
|||||||
simplex.chat
|
simplex.chat
|
||||||
sina.com.hk
|
sina.com.hk
|
||||||
sinchew.com.my
|
sinchew.com.my
|
||||||
|
sing-box.sagernet.org
|
||||||
singaporepools.com.sg
|
singaporepools.com.sg
|
||||||
singlelogin.se
|
singlelogin.se
|
||||||
singtao.com
|
singtao.com
|
||||||
@@ -3433,7 +3478,7 @@ supchina.com
|
|||||||
superpages.com
|
superpages.com
|
||||||
supervpn.net
|
supervpn.net
|
||||||
superzooi.com
|
superzooi.com
|
||||||
support.futunn.com
|
supjav.com
|
||||||
supremecourt.gov
|
supremecourt.gov
|
||||||
suprememastertv.com
|
suprememastertv.com
|
||||||
surfeasy.com
|
surfeasy.com
|
||||||
@@ -3462,10 +3507,12 @@ taa-usa.org
|
|||||||
taaze.tw
|
taaze.tw
|
||||||
taedp.org.tw
|
taedp.org.tw
|
||||||
tagwalk.com
|
tagwalk.com
|
||||||
|
taiav.com
|
||||||
tails.net
|
tails.net
|
||||||
taipeisociety.org
|
taipeisociety.org
|
||||||
taipeitimes.com
|
taipeitimes.com
|
||||||
taisounds.com
|
taisounds.com
|
||||||
|
taiwanembassy.org
|
||||||
taiwanhot.net
|
taiwanhot.net
|
||||||
taiwanjustice.net
|
taiwanjustice.net
|
||||||
taiwanncf.org.tw
|
taiwanncf.org.tw
|
||||||
@@ -3518,6 +3565,7 @@ tew.org
|
|||||||
textnow.com
|
textnow.com
|
||||||
textnow.me
|
textnow.me
|
||||||
tfc-taiwan.org.tw
|
tfc-taiwan.org.tw
|
||||||
|
tfd.org.tw
|
||||||
tfhub.dev
|
tfhub.dev
|
||||||
tfiflve.com
|
tfiflve.com
|
||||||
tg-me.com
|
tg-me.com
|
||||||
@@ -3694,8 +3742,6 @@ totalvpn.com
|
|||||||
tou.tv
|
tou.tv
|
||||||
tpi.org.tw
|
tpi.org.tw
|
||||||
tracfone.com
|
tracfone.com
|
||||||
trade.futunn.com
|
|
||||||
trade.longportapp.com
|
|
||||||
tradeup.com
|
tradeup.com
|
||||||
tradingview.com
|
tradingview.com
|
||||||
translate.goog
|
translate.goog
|
||||||
@@ -3713,6 +3759,7 @@ tryai.dev
|
|||||||
tryheart.jp
|
tryheart.jp
|
||||||
tsdr.uspto.gov
|
tsdr.uspto.gov
|
||||||
tt1069.com
|
tt1069.com
|
||||||
|
ttl.com.tw
|
||||||
tttan.com
|
tttan.com
|
||||||
ttv.com.tw
|
ttv.com.tw
|
||||||
ttvnw.net
|
ttvnw.net
|
||||||
@@ -3765,6 +3812,7 @@ tweetwally.com
|
|||||||
tweez.net
|
tweez.net
|
||||||
twelve.today
|
twelve.today
|
||||||
twerkingbutt.com
|
twerkingbutt.com
|
||||||
|
twfhcsec.com.tw
|
||||||
twftp.org
|
twftp.org
|
||||||
twgov.tw
|
twgov.tw
|
||||||
twgreatdaily.com
|
twgreatdaily.com
|
||||||
@@ -3807,6 +3855,7 @@ twt.tl
|
|||||||
twtkr.com
|
twtkr.com
|
||||||
twttr.com
|
twttr.com
|
||||||
tx.me
|
tx.me
|
||||||
|
tybio.com.tw
|
||||||
tycool.com
|
tycool.com
|
||||||
typepad.com
|
typepad.com
|
||||||
typeset.io
|
typeset.io
|
||||||
@@ -3902,6 +3951,7 @@ valeursactuelles.com
|
|||||||
vansky.com
|
vansky.com
|
||||||
vaticannews.va
|
vaticannews.va
|
||||||
vatn.org
|
vatn.org
|
||||||
|
vava8.com
|
||||||
vcf-online.org
|
vcf-online.org
|
||||||
vcfbuilder.org
|
vcfbuilder.org
|
||||||
veed.io
|
veed.io
|
||||||
@@ -3995,6 +4045,7 @@ vpsxb.net
|
|||||||
vrchat.com
|
vrchat.com
|
||||||
vrporn.com
|
vrporn.com
|
||||||
vrsmash.com
|
vrsmash.com
|
||||||
|
vscc.org.tw
|
||||||
vtunnel.com
|
vtunnel.com
|
||||||
vultryhw.com
|
vultryhw.com
|
||||||
w-pool.com
|
w-pool.com
|
||||||
@@ -4003,6 +4054,7 @@ waffle1999.com
|
|||||||
wainao.me
|
wainao.me
|
||||||
walletconnect.com
|
walletconnect.com
|
||||||
walletconnect.org
|
walletconnect.org
|
||||||
|
wallhaven.cc
|
||||||
wallmama.com
|
wallmama.com
|
||||||
wallpapercasa.com
|
wallpapercasa.com
|
||||||
wallsttv.com
|
wallsttv.com
|
||||||
@@ -4149,6 +4201,7 @@ write.as
|
|||||||
writesonic.com
|
writesonic.com
|
||||||
wsj.com
|
wsj.com
|
||||||
wsj.net
|
wsj.net
|
||||||
|
wtfpass.com
|
||||||
wufafangwen.com
|
wufafangwen.com
|
||||||
wufi.org.tw
|
wufi.org.tw
|
||||||
wujieliulan.com
|
wujieliulan.com
|
||||||
@@ -4251,6 +4304,7 @@ xvideos-cdn.com
|
|||||||
xvideos.com
|
xvideos.com
|
||||||
xvideos.es
|
xvideos.es
|
||||||
xvinlink.com
|
xvinlink.com
|
||||||
|
xx.net
|
||||||
xxx.com
|
xxx.com
|
||||||
xxx.xxx
|
xxx.xxx
|
||||||
xxxx.com.au
|
xxxx.com.au
|
||||||
@@ -4374,6 +4428,7 @@ zootool.com
|
|||||||
zophar.net
|
zophar.net
|
||||||
zorrovpn.com
|
zorrovpn.com
|
||||||
zozotown.com
|
zozotown.com
|
||||||
|
zozovideo.com
|
||||||
zpn.im
|
zpn.im
|
||||||
zspeeder.me
|
zspeeder.me
|
||||||
zuo.la
|
zuo.la
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-passwall2
|
PKG_NAME:=luci-app-passwall2
|
||||||
PKG_VERSION:=26.10.20
|
PKG_VERSION:=26.10.29
|
||||||
PKG_RELEASE:=154
|
PKG_RELEASE:=155
|
||||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS:= \
|
PKG_CONFIG_DEPENDS:= \
|
||||||
|
|||||||
@@ -276,9 +276,9 @@ end
|
|||||||
|
|
||||||
function UrlEncode(szText)
|
function UrlEncode(szText)
|
||||||
if type(szText) ~= "string" then return "" end
|
if type(szText) ~= "string" then return "" end
|
||||||
return szText:gsub("([^%w%-_%.%~])", function(c)
|
return (szText:gsub("([^%w%-_%.%~])", function(c)
|
||||||
return string.format("%%%02X", string.byte(c))
|
return string.format("%%%02X", string.byte(c))
|
||||||
end)
|
end))
|
||||||
end
|
end
|
||||||
|
|
||||||
function UrlDecode(szText)
|
function UrlDecode(szText)
|
||||||
@@ -1413,12 +1413,14 @@ function to_download_progress(app_name, task_id, total_size)
|
|||||||
|
|
||||||
total_size = tonumber(total_size) or 0
|
total_size = tonumber(total_size) or 0
|
||||||
local tmp_file = "/tmp/" .. app_name .. "_download." .. task_id
|
local tmp_file = "/tmp/" .. app_name .. "_download." .. task_id
|
||||||
local downloaded = tonumber(fs.stat(tmp_file, "size")) or 0
|
local downloaded
|
||||||
if app_name == appname then
|
if app_name == appname then
|
||||||
downloaded = 0
|
downloaded = 0
|
||||||
for part = 1, 5 do
|
for part = 1, 5 do
|
||||||
downloaded = downloaded + (tonumber(fs.stat(tmp_file .. part, "size")) or 0)
|
downloaded = downloaded + (tonumber((fs.stat(tmp_file .. part, "size"))) or 0)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
downloaded = tonumber((fs.stat(tmp_file, "size"))) or 0
|
||||||
end
|
end
|
||||||
local percent
|
local percent
|
||||||
if total_size > 0 then
|
if total_size > 0 then
|
||||||
|
|||||||
@@ -261,6 +261,17 @@ local com = self.com
|
|||||||
detail.textContent = installingNotice;
|
detail.textContent = installingNotice;
|
||||||
// Read the tiny result file even if rpcd restart invalidates the session.
|
// Read the tiny result file even if rpcd restart invalidates the session.
|
||||||
var pending = false, finished = false;
|
var pending = false, finished = false;
|
||||||
|
function finishInstall(code) {
|
||||||
|
if (finished) return;
|
||||||
|
finished = true;
|
||||||
|
clearInterval(timer);
|
||||||
|
removePageNotice(appname);
|
||||||
|
if (code) onRequestError(btn, updateFailedText);
|
||||||
|
else {
|
||||||
|
window.onbeforeunload = undefined;
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
var timer = setInterval(function() {
|
var timer = setInterval(function() {
|
||||||
if (pending) return;
|
if (pending) return;
|
||||||
pending = true;
|
pending = true;
|
||||||
@@ -273,28 +284,29 @@ local com = self.com
|
|||||||
if (finished) return;
|
if (finished) return;
|
||||||
var json;
|
var json;
|
||||||
try { json = JSON.parse(xhr.responseText); } catch (e) { return; }
|
try { json = JSON.parse(xhr.responseText); } catch (e) { return; }
|
||||||
if (typeof json.code !== 'number') return;
|
if (!json || typeof json.code !== 'number') return;
|
||||||
finished = true;
|
finishInstall(json.code);
|
||||||
clearInterval(timer);
|
|
||||||
removePageNotice(appname);
|
|
||||||
if (json.code) onRequestError(btn, updateFailedText);
|
|
||||||
else {
|
|
||||||
window.onbeforeunload = undefined;
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
XHR.post(url, {token: tokenStr, task: 'install', id: id,
|
// Legacy LuCI has no static XHR.post(), and its instance callback has no JSON argument.
|
||||||
force: appInfoList[appname].has_update ? '0' : '1',
|
var request = new XMLHttpRequest();
|
||||||
languages: appInfoList[appname].languages || ''}, function(x, json) {
|
request.open('POST', url, true);
|
||||||
if (!finished && json && json.code) {
|
request.timeout = 300000;
|
||||||
finished = true;
|
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
clearInterval(timer);
|
request.onerror = request.ontimeout = function() { finishInstall(1); };
|
||||||
removePageNotice(appname);
|
request.onload = function() {
|
||||||
onRequestError(btn, updateFailedText);
|
if (finished) return;
|
||||||
|
var json;
|
||||||
|
try { json = JSON.parse(request.responseText); } catch (e) {}
|
||||||
|
if (request.status < 200 || request.status >= 300 || !json ||
|
||||||
|
typeof json.code !== 'number' || json.code) {
|
||||||
|
finishInstall(1);
|
||||||
}
|
}
|
||||||
}, 300);
|
};
|
||||||
|
request.send('token=' + encodeURIComponent(tokenStr) + '&task=install&id=' + encodeURIComponent(id) +
|
||||||
|
'&force=' + (appInfoList[appname].has_update ? '0' : '1') +
|
||||||
|
'&languages=' + encodeURIComponent(appInfoList[appname].languages || ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
//]]>
|
//]]>
|
||||||
|
|||||||
@@ -298,89 +298,36 @@ table td, .table .td {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-dropdown {
|
.pw-group-select {
|
||||||
position: relative;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 2px;
|
|
||||||
width: 180px;
|
width: 180px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
font-size: 13px;
|
flex: 0 0 180px;
|
||||||
background: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-display {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-display:hover {
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-list {
|
|
||||||
position: absolute;
|
|
||||||
top: calc(100% + 2px);
|
|
||||||
left: -1px;
|
|
||||||
width: calc(100% + 2px);
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 2px;
|
|
||||||
border-top: none;
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.15);
|
|
||||||
background: #fff;
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
max-height: 200px;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
z-index: 100;
|
|
||||||
box-sizing: border-box;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item {
|
|
||||||
padding: 4px 8px;
|
|
||||||
line-height: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item.selected {
|
|
||||||
background-color: #1e90ff;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.create-item-input::placeholder {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item.custom-input input {
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 3px;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 20px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow-down-small {
|
.pw-group-select > .cbi-dropdown,
|
||||||
width: 0;
|
.pw-group-select > .cbi-input-text,
|
||||||
height: 0;
|
.pw-group-select > .cbi-input-select {
|
||||||
border-left: 4px solid transparent;
|
width: 100% !important;
|
||||||
border-right: 4px solid transparent;
|
min-width: 0 !important;
|
||||||
border-top: 5px solid #555;
|
max-width: 100% !important;
|
||||||
display: inline-block;
|
height: 28px !important;
|
||||||
vertical-align: middle;
|
min-height: 28px !important;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pw-group-select > .cbi-dropdown > ul:not(.dropdown) > li,
|
||||||
|
.pw-group-select > .cbi-dropdown > .open {
|
||||||
|
height: 26px;
|
||||||
|
min-height: 0;
|
||||||
|
line-height: 26px;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -1072,97 +1019,103 @@ table td, .table .td {
|
|||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
//Pop-up logic
|
//Pop-up logic
|
||||||
|
|
||||||
// Custom group dropdown list events
|
function normalize_group_name(value, groups) {
|
||||||
function dropdown_list_fun(div_id) {
|
const name = value.trim();
|
||||||
const dropdown = document.getElementById(div_id);
|
return groups.find(group => group.toLowerCase() === name.toLowerCase()) || name;
|
||||||
if (!dropdown) return;
|
}
|
||||||
|
|
||||||
const display = dropdown.querySelector(".selected-display");
|
function init_group_dropdown(div_id) {
|
||||||
const displayText = display.querySelector(".text");
|
const container = document.getElementById(div_id);
|
||||||
const list = dropdown.querySelector(".dropdown-list");
|
if (!container || container._group_ready || container._group_loading) return;
|
||||||
const hidden = dropdown.querySelector('input[type="hidden"]');
|
const tabs = document.querySelector("#node_list .cbi-tabmenu");
|
||||||
const input = dropdown.querySelector(".create-item-input");
|
if (!tabs) {
|
||||||
|
setTimeout(() => init_group_dropdown(div_id), 50);
|
||||||
display.addEventListener("click", function() {
|
return;
|
||||||
list.style.display = list.style.display === "none" ? "block" : "none";
|
|
||||||
input.value = "";
|
|
||||||
//input.focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
function selectItem(li) {
|
|
||||||
list.querySelectorAll(".dropdown-item").forEach(function(el){
|
|
||||||
el.classList.remove("selected");
|
|
||||||
});
|
|
||||||
li.classList.add("selected");
|
|
||||||
hidden.value = li.dataset.value;
|
|
||||||
displayText.textContent = li.dataset.value || "<%:default%>";
|
|
||||||
list.style.display = "none";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list.addEventListener("click", function(e){
|
const choices = { "default": "<%:default%>" };
|
||||||
const li = e.target.closest(".dropdown-item");
|
const groups = ["default"];
|
||||||
if (!li || li.classList.contains("custom-input")) return;
|
tabs.querySelectorAll("li[group_name]").forEach(function(tab) {
|
||||||
selectItem(li);
|
const group = tab.getAttribute("group_name");
|
||||||
});
|
if (group !== "default" && !groups.includes(group)) {
|
||||||
|
choices[group] = group;
|
||||||
input.addEventListener("keydown", function(e){
|
groups.push(group);
|
||||||
const isEnter = e.key === "Enter" || e.keyCode === 13;
|
|
||||||
if (!isEnter) return;
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const val = input.value.trim();
|
|
||||||
if (!val) return;
|
|
||||||
|
|
||||||
if (val.toLowerCase() === "default") {
|
|
||||||
const emptyLi = Array.from(list.querySelectorAll(".dropdown-item"))
|
|
||||||
.find(function(el){ return !el.dataset.value; });
|
|
||||||
if (emptyLi) selectItem(emptyLi);
|
|
||||||
input.value = "";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
let li = Array.from(list.querySelectorAll(".dropdown-item")).find(function(el){
|
const input = container.querySelector("input");
|
||||||
return el.dataset.value && el.dataset.value.toLowerCase() === val.toLowerCase();
|
<% if api.is_js_luci() then -%>
|
||||||
|
container._group_loading = true;
|
||||||
|
L.require("ui").then(function(ui) {
|
||||||
|
const widget = new ui.Dropdown("default", choices, {
|
||||||
|
id: input.id,
|
||||||
|
name: input.name,
|
||||||
|
multiple: false,
|
||||||
|
optional: false,
|
||||||
|
create: true,
|
||||||
|
sort: groups,
|
||||||
|
custom_placeholder: "-- <%:custom%> --"
|
||||||
});
|
});
|
||||||
if (!li) {
|
const dropdown = widget.render();
|
||||||
li = document.createElement("li");
|
// Normalize before LuCI handles Enter and replaces its single custom item.
|
||||||
li.className = "dropdown-item";
|
dropdown.addEventListener("keydown", function(e) {
|
||||||
li.dataset.value = val;
|
if (!e.target.classList.contains("create-item-input") ||
|
||||||
li.textContent = val;
|
(e.key !== "Enter" && e.keyCode !== 13)) return;
|
||||||
list.insertBefore(li, input.parentNode);
|
if (e.isComposing) {
|
||||||
}
|
e.stopPropagation();
|
||||||
|
return;
|
||||||
input.value = "";
|
}
|
||||||
selectItem(li);
|
const values = Array.from(dropdown.querySelectorAll("ul.dropdown > li[data-value]:not([unselectable])"), li => li.dataset.value);
|
||||||
});
|
e.target.value = normalize_group_name(e.target.value, values);
|
||||||
// Read group names from tab
|
if (!e.target.value) {
|
||||||
function InsertGroup(list, input) {
|
e.preventDefault();
|
||||||
const tabs = document.querySelectorAll(".cbi-tabmenu li");
|
e.stopPropagation();
|
||||||
if (!tabs.length) {
|
}
|
||||||
setTimeout(() => InsertGroup(list, input), 50);
|
}, true);
|
||||||
return;
|
const customInput = dropdown.querySelector(".create-item-input");
|
||||||
}
|
// The custom input row must not shadow a group named "-".
|
||||||
|
customInput.parentNode.removeAttribute("data-value");
|
||||||
tabs.forEach(function(li){
|
customInput.setAttribute("inputmode", "text");
|
||||||
const group = li.id.split('.').pop();
|
customInput.setAttribute("enterkeyhint", "done");
|
||||||
if(group === "default") return;
|
dropdown.addEventListener("cbi-dropdown-change", function() {
|
||||||
if(Array.from(list.querySelectorAll(".dropdown-item")).some(el => el.dataset.value === group)) return;
|
customInput.value = "";
|
||||||
const newLi = document.createElement("li");
|
|
||||||
newLi.className = "dropdown-item";
|
|
||||||
newLi.dataset.value = group;
|
|
||||||
newLi.textContent = group;
|
|
||||||
list.insertBefore(newLi, input.parentNode);
|
|
||||||
});
|
});
|
||||||
}
|
container.replaceChild(dropdown, input);
|
||||||
InsertGroup(list, input);
|
container._group_widget = widget;
|
||||||
|
container._group_ready = true;
|
||||||
// Automatically collapses when clicking on the outside.
|
container._group_loading = false;
|
||||||
document.addEventListener("click", function(e) {
|
}).catch(function(error) {
|
||||||
if (!dropdown.contains(e.target)) {
|
container._group_loading = false;
|
||||||
list.style.display = "none";
|
console.error("Group dropdown init failed:", error);
|
||||||
|
alert("<%:Error%>");
|
||||||
|
});
|
||||||
|
<% else -%>
|
||||||
|
input.disabled = false;
|
||||||
|
input.addEventListener("blur", function() {
|
||||||
|
input.value = normalize_group_name(input.value, groups) || "default";
|
||||||
|
});
|
||||||
|
input.addEventListener("keydown", function(e) {
|
||||||
|
if ((e.key === "Enter" || e.keyCode === 13) && !e.isComposing) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
input.blur();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
cbi_combobox_init(input.id, choices, "<%:default%>", "-- <%:custom%> --");
|
||||||
|
container._group_ready = true;
|
||||||
|
<% end -%>
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_group_value(div_id) {
|
||||||
|
const container = document.getElementById(div_id);
|
||||||
|
return (container._group_widget ? container._group_widget.getValue() : container.querySelector("input").value) || "default";
|
||||||
|
}
|
||||||
|
|
||||||
|
function close_group_dropdown(div_id) {
|
||||||
|
const container = document.getElementById(div_id);
|
||||||
|
const dropdown = container.querySelector(".cbi-dropdown[open]");
|
||||||
|
if (dropdown) dropdown.dispatchEvent(new CustomEvent("cbi-dropdown-close"));
|
||||||
|
const input = container.querySelector(".create-item-input");
|
||||||
|
if (input) input.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBg(el) {
|
function getBg(el) {
|
||||||
@@ -1182,20 +1135,18 @@ table td, .table .td {
|
|||||||
const addLinkDiv = document.getElementById("add_link_div");
|
const addLinkDiv = document.getElementById("add_link_div");
|
||||||
addLinkDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
addLinkDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
||||||
addLinkDiv.style.display = "block";
|
addLinkDiv.style.display = "block";
|
||||||
if (!addLinkDiv._dropdown_inited) {
|
init_group_dropdown("addlink_group_custom");
|
||||||
addLinkDiv._dropdown_inited = true;
|
|
||||||
dropdown_list_fun("addlink_group_custom");
|
|
||||||
}
|
|
||||||
document.getElementById("nodes_link").focus();
|
document.getElementById("nodes_link").focus();
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
|
close_group_dropdown("addlink_group_custom");
|
||||||
document.getElementById('modal-mask').style.display = 'none';
|
document.getElementById('modal-mask').style.display = 'none';
|
||||||
document.getElementById("add_link_div").style.display = "none";
|
document.getElementById("add_link_div").style.display = "none";
|
||||||
document.body.classList.remove('modal-open');
|
document.body.classList.remove('modal-open');
|
||||||
},
|
},
|
||||||
add_node() {
|
add_node() {
|
||||||
let nodes_link = document.getElementById("nodes_link").value;
|
let nodes_link = document.getElementById("nodes_link").value;
|
||||||
const group = (document.querySelector('#addlink_group_custom input[type="hidden"]')?.value || "default");
|
const group = get_group_value("addlink_group_custom");
|
||||||
nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").replace(/<[^>]*>/g, '').trim();
|
nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").replace(/<[^>]*>/g, '').trim();
|
||||||
if (nodes_link != "") {
|
if (nodes_link != "") {
|
||||||
nodes_link = decodeIfBase64(nodes_link);
|
nodes_link = decodeIfBase64(nodes_link);
|
||||||
@@ -1274,23 +1225,21 @@ table td, .table .td {
|
|||||||
const reassignGroupDiv = document.getElementById("reassign_group_div");
|
const reassignGroupDiv = document.getElementById("reassign_group_div");
|
||||||
reassignGroupDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
reassignGroupDiv.style.background = getBg(document.querySelector('.cbi-section')) || getBg(document.body) || '';
|
||||||
reassignGroupDiv.style.display = "block";
|
reassignGroupDiv.style.display = "block";
|
||||||
if (!reassignGroupDiv._dropdown_inited) {
|
init_group_dropdown("reassign_group_custom");
|
||||||
reassignGroupDiv._dropdown_inited = true;
|
|
||||||
dropdown_list_fun("reassign_group_custom");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
alert("<%:You no select nodes !%>");
|
alert("<%:You no select nodes !%>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
|
close_group_dropdown("reassign_group_custom");
|
||||||
document.getElementById('modal-mask').style.display = 'none';
|
document.getElementById('modal-mask').style.display = 'none';
|
||||||
document.getElementById("reassign_group_div").style.display = "none";
|
document.getElementById("reassign_group_div").style.display = "none";
|
||||||
document.body.classList.remove('modal-open');
|
document.body.classList.remove('modal-open');
|
||||||
},
|
},
|
||||||
action() {
|
action() {
|
||||||
const ids = [];
|
const ids = [];
|
||||||
const group = (document.querySelector('#reassign_group_custom input[type="hidden"]')?.value || "default");
|
const group = get_group_value("reassign_group_custom");
|
||||||
const visibleContainer = document.querySelector('#cbi-passwall2-nodes > .cbi-tabcontainer[style*="display:block"], #cbi-passwall2-nodes > .cbi-tabcontainer[style*="display: block"]');
|
const visibleContainer = document.querySelector('#cbi-passwall2-nodes > .cbi-tabcontainer[style*="display:block"], #cbi-passwall2-nodes > .cbi-tabcontainer[style*="display: block"]');
|
||||||
if (!visibleContainer) return;
|
if (!visibleContainer) return;
|
||||||
const doms = visibleContainer.getElementsByClassName("nodes_select");
|
const doms = visibleContainer.getElementsByClassName("nodes_select");
|
||||||
@@ -1740,19 +1689,9 @@ table td, .table .td {
|
|||||||
</div>
|
</div>
|
||||||
<div class="value-custom">
|
<div class="value-custom">
|
||||||
<div class="value-field-custom">
|
<div class="value-field-custom">
|
||||||
<label class="value-title-custom" for="addlink_group_custom"><%:Group Name%></label>
|
<label class="value-title-custom" for="addlink_group"><%:Group Name%></label>
|
||||||
<div id="addlink_group_custom" class="custom-dropdown">
|
<div id="addlink_group_custom" class="pw-group-select">
|
||||||
<div class="selected-display">
|
<input id="addlink_group" name="addlink_group" class="cbi-input-text" type="text" value="default" disabled>
|
||||||
<span class="text"><%:default%></span>
|
|
||||||
<span class="arrow-down-small"></span>
|
|
||||||
</div>
|
|
||||||
<ul class="dropdown-list" style="display:none;">
|
|
||||||
<li class="dropdown-item selected" data-value=""><%:default%></li>
|
|
||||||
<li class="dropdown-item custom-input">
|
|
||||||
<input type="text" placeholder="-- <%:custom%> --" class="create-item-input" inputmode="text" enterkeyhint="done">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<input type="hidden" name="addlink_group" value="">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1768,19 +1707,9 @@ table td, .table .td {
|
|||||||
<h3><%:Reassign Node Group%></h3>
|
<h3><%:Reassign Node Group%></h3>
|
||||||
<div class="value-custom">
|
<div class="value-custom">
|
||||||
<div class="value-field-custom">
|
<div class="value-field-custom">
|
||||||
<label class="value-title-custom" for="reassign_group_custom"><%:Group Name%></label>
|
<label class="value-title-custom" for="to_group"><%:Group Name%></label>
|
||||||
<div id="reassign_group_custom" class="custom-dropdown">
|
<div id="reassign_group_custom" class="pw-group-select">
|
||||||
<div class="selected-display">
|
<input id="to_group" name="to_group" class="cbi-input-text" type="text" value="default" disabled>
|
||||||
<span class="text"><%:default%></span>
|
|
||||||
<span class="arrow-down-small"></span>
|
|
||||||
</div>
|
|
||||||
<ul class="dropdown-list" style="display:none;">
|
|
||||||
<li class="dropdown-item selected" data-value=""><%:default%></li>
|
|
||||||
<li class="dropdown-item custom-input">
|
|
||||||
<input type="text" placeholder="-- <%:custom%> --" class="create-item-input" inputmode="text" enterkeyhint="done">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<input type="hidden" name="to_group" value="">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+2
-2
@@ -5,8 +5,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=mihomo
|
PKG_NAME:=mihomo
|
||||||
PKG_VERSION:=1.19.32
|
PKG_VERSION:=1.19.33
|
||||||
PKG_RELEASE:=35
|
PKG_RELEASE:=36
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://codeload.github.com/metacubex/mihomo/tar.gz/v$(PKG_VERSION)?
|
PKG_SOURCE_URL:=https://codeload.github.com/metacubex/mihomo/tar.gz/v$(PKG_VERSION)?
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=minigate
|
PKG_NAME:=minigate
|
||||||
PKG_VERSION:=2026.10.28
|
PKG_VERSION:=2026.10.28-2
|
||||||
PKG_RELEASE:=8
|
PKG_RELEASE:=9
|
||||||
PKG_LICENSE:=MIT
|
PKG_LICENSE:=MIT
|
||||||
PKG_MAINTAINER:=MiniGate
|
PKG_MAINTAINER:=MiniGate
|
||||||
|
|
||||||
|
|||||||
+22
-15
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
一个类似 Lucky 的轻量级 OpenWrt 应用,提供四大核心功能:DDNS、SSL 证书、反向代理、登录防护。
|
一个类似 Lucky 的轻量级 OpenWrt 应用,提供四大核心功能:DDNS、SSL 证书、反向代理、登录防护。
|
||||||
|
|
||||||
当前版本:**v2026.10.28**。界面名称为 **MiniGate**,仓库名及 OpenWrt 内部包名均为 **`minigate`**。
|
当前版本:**v2026.10.28-2**。界面名称为 **MiniGate**,仓库名及 OpenWrt 内部包名均为 **`minigate`**。
|
||||||
|
|
||||||
> OpenWrt 用户请从 [Releases](https://github.com/tpxcer/minigate/releases/latest) 下载 `minigate_2026.10.28_all.ipk`。不要把 GitHub 自动生成的 `Source code (zip)` / `Source code (tar.gz)` 当安装包上传到 LuCI。
|
> OpenWrt 用户请从 [Releases](https://github.com/tpxcer/minigate/releases/latest) 下载 `minigate_2026.10.28-2_all.ipk`。不要把 GitHub 自动生成的 `Source code (zip)` / `Source code (tar.gz)` 当安装包上传到 LuCI。
|
||||||
|
|
||||||
## 项目定位
|
## 项目定位
|
||||||
|
|
||||||
@@ -102,20 +102,20 @@ MiniGate 面向需要自托管轻量网关能力的 OpenWrt / ImmortalWrt 用户
|
|||||||
|
|
||||||
从 [Releases](https://github.com/tpxcer/minigate/releases/latest) 下载:
|
从 [Releases](https://github.com/tpxcer/minigate/releases/latest) 下载:
|
||||||
|
|
||||||
`minigate_2026.10.28_all.ipk`
|
`minigate_2026.10.28-2_all.ipk`
|
||||||
|
|
||||||
**通过 LuCI 界面安装:**
|
**通过 LuCI 界面安装:**
|
||||||
1. 打开 LuCI → **系统** → **软件包**
|
1. 打开 LuCI → **系统** → **软件包**
|
||||||
2. 点击 **上传软件包**
|
2. 点击 **上传软件包**
|
||||||
3. 选择 `minigate_2026.10.28_all.ipk`,点击安装
|
3. 选择 `minigate_2026.10.28-2_all.ipk`,点击安装
|
||||||
|
|
||||||
**通过命令行安装:**
|
**通过命令行安装:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /tmp
|
cd /tmp
|
||||||
wget -O minigate_2026.10.28_all.ipk https://github.com/tpxcer/minigate/releases/download/v2026.10.28/minigate_2026.10.28_all.ipk
|
wget -O minigate_2026.10.28-2_all.ipk https://github.com/tpxcer/minigate/releases/download/v2026.10.28-2/minigate_2026.10.28-2_all.ipk
|
||||||
opkg update
|
opkg update
|
||||||
opkg install /tmp/minigate_2026.10.28_all.ipk
|
opkg install /tmp/minigate_2026.10.28-2_all.ipk
|
||||||
rm -f /tmp/luci-indexcache /tmp/luci-modulecache 2>/dev/null
|
rm -f /tmp/luci-indexcache /tmp/luci-modulecache 2>/dev/null
|
||||||
/etc/init.d/uhttpd restart
|
/etc/init.d/uhttpd restart
|
||||||
/etc/init.d/minigate restart
|
/etc/init.d/minigate restart
|
||||||
@@ -134,7 +134,7 @@ Release 用的 `.ipk` 请用仓库脚本生成,避免生成 Debian 风格 ar
|
|||||||
脚本会输出:
|
脚本会输出:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
dist/minigate_2026.10.28_all.ipk
|
dist/minigate_2026.10.28-2_all.ipk
|
||||||
```
|
```
|
||||||
|
|
||||||
该文件外层是 OpenWrt/ImmortalWrt 24.10 兼容的 `tar.gz`,内部成员顺序为 `debian-binary`、`control.tar.gz`、`data.tar.gz`。
|
该文件外层是 OpenWrt/ImmortalWrt 24.10 兼容的 `tar.gz`,内部成员顺序为 `debian-binary`、`control.tar.gz`、`data.tar.gz`。
|
||||||
@@ -162,7 +162,7 @@ wget -qO- https://raw.githubusercontent.com/tpxcer/minigate/main/scripts/install
|
|||||||
需要指定并核对具体版本时,执行:
|
需要指定并核对具体版本时,执行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
d="$(mktemp -d /tmp/minigate.XXXXXX)" && cd "$d" && wget -q https://github.com/tpxcer/minigate/releases/download/v2026.10.28/minigate-v2026.10.28-src.tar.gz && wget -q https://github.com/tpxcer/minigate/releases/download/v2026.10.28/SHA256SUMS && grep 'minigate-v2026.10.28-src.tar.gz$' SHA256SUMS | sha256sum -c - && tar xzf minigate-v2026.10.28-src.tar.gz && sh install.sh && /etc/init.d/uhttpd restart && /etc/init.d/minigate restart
|
d="$(mktemp -d /tmp/minigate.XXXXXX)" && cd "$d" && wget -q https://github.com/tpxcer/minigate/releases/download/v2026.10.28-2/minigate-v2026.10.28-2-src.tar.gz && wget -q https://github.com/tpxcer/minigate/releases/download/v2026.10.28-2/SHA256SUMS && grep 'minigate-v2026.10.28-2-src.tar.gz$' SHA256SUMS | sha256sum -c - && tar xzf minigate-v2026.10.28-2-src.tar.gz && sh install.sh && /etc/init.d/uhttpd restart && /etc/init.d/minigate restart
|
||||||
```
|
```
|
||||||
|
|
||||||
其中 `minigate.XXXXXX` 是临时目录模板,系统会自动把六个 `X` 替换为随机字符,避免与已有目录重名。该命令会校验源码包的 SHA-256、保留现有 minigate 配置并重启 LuCI 与 minigate 服务。
|
其中 `minigate.XXXXXX` 是临时目录模板,系统会自动把六个 `X` 替换为随机字符,避免与已有目录重名。该命令会校验源码包的 SHA-256、保留现有 minigate 配置并重启 LuCI 与 minigate 服务。
|
||||||
@@ -177,14 +177,14 @@ ssh root@192.168.1.1
|
|||||||
|
|
||||||
# 2. 在路由器上直接下载 Release 源码包
|
# 2. 在路由器上直接下载 Release 源码包
|
||||||
cd /tmp
|
cd /tmp
|
||||||
wget -O minigate-src.tar.gz https://github.com/tpxcer/minigate/releases/download/v2026.10.28/minigate-v2026.10.28-src.tar.gz
|
wget -O minigate-src.tar.gz https://github.com/tpxcer/minigate/releases/download/v2026.10.28-2/minigate-v2026.10.28-2-src.tar.gz
|
||||||
wget -O minigate-SHA256SUMS https://github.com/tpxcer/minigate/releases/download/v2026.10.28/SHA256SUMS
|
wget -O minigate-SHA256SUMS https://github.com/tpxcer/minigate/releases/download/v2026.10.28-2/SHA256SUMS
|
||||||
awk '$2 == "minigate-v2026.10.28-src.tar.gz" {print $1 " minigate-src.tar.gz"}' minigate-SHA256SUMS | sha256sum -c - || exit 1
|
awk '$2 == "minigate-v2026.10.28-2-src.tar.gz" {print $1 " minigate-src.tar.gz"}' minigate-SHA256SUMS | sha256sum -c - || exit 1
|
||||||
|
|
||||||
# 3. 解压到独立目录并安装
|
# 3. 解压到独立目录并安装
|
||||||
mkdir -p /tmp/minigate-v2026.10.28
|
mkdir -p /tmp/minigate-v2026.10.28-2
|
||||||
tar xzf minigate-src.tar.gz -C /tmp/minigate-v2026.10.28
|
tar xzf minigate-src.tar.gz -C /tmp/minigate-v2026.10.28-2
|
||||||
cd /tmp/minigate-v2026.10.28
|
cd /tmp/minigate-v2026.10.28-2
|
||||||
sh install.sh
|
sh install.sh
|
||||||
|
|
||||||
# 4. 启动服务
|
# 4. 启动服务
|
||||||
@@ -234,7 +234,7 @@ SSH 登录后执行上方「方法 2」的一条命令,保留原有配置并
|
|||||||
### IPK 升级
|
### IPK 升级
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
opkg install --force-reinstall /tmp/minigate_2026.10.28_all.ipk
|
opkg install --force-reinstall /tmp/minigate_2026.10.28-2_all.ipk
|
||||||
rm -f /tmp/luci-indexcache /tmp/luci-modulecache 2>/dev/null
|
rm -f /tmp/luci-indexcache /tmp/luci-modulecache 2>/dev/null
|
||||||
/etc/init.d/minigate restart
|
/etc/init.d/minigate restart
|
||||||
```
|
```
|
||||||
@@ -425,6 +425,13 @@ minigate/
|
|||||||
|
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
### v2026.10.28-2
|
||||||
|
- 修复 v2026.10.28 引入的登录防护回归:达到失败阈值时,封禁地址被修复防火墙的读取过程清空,日志显示「封禁 失败」,新的攻击来源不会被封禁(已有封禁不受影响)。升级后会立即恢复正常封禁
|
||||||
|
|
||||||
|
### v2026.10.28-1
|
||||||
|
- 「公网访问范围」的地区选择改为收起式:收起时只显示已选地区标签和数量,展开后按华北、东北、华东、华中、华南、西南、西北、港澳台分组对齐排列,支持按地区名或大区名搜索、一键清空、点标签上的 × 移除
|
||||||
|
- 修复 v2026.10.28 中关闭「限制公网访问地区」后保存反向代理页会提示未选择地区、导致整页无法保存的问题
|
||||||
|
|
||||||
### v2026.10.28
|
### v2026.10.28
|
||||||
- 修复:通配符主域名停用或删除后,其子域名会退回成 443 端口的明文 HTTP 站点,并可能让 Nginx 因两个默认站点无法加载;现在子域名随主域名一起停用,并可单独停用
|
- 修复:通配符主域名停用或删除后,其子域名会退回成 443 端口的明文 HTTP 站点,并可能让 Nginx 因两个默认站点无法加载;现在子域名随主域名一起停用,并可单独停用
|
||||||
- 修复:同一端口同时有 HTTP 和 HTTPS 规则时生成无法加载的配置;冲突规则会被跳过并在总览提示
|
- 修复:同一端口同时有 HTTP 和 HTTPS 规则时生成无法加载的配置;冲突规则会被跳过并在总览提示
|
||||||
|
|||||||
@@ -219,12 +219,24 @@ if regions_file then
|
|||||||
regions_file:close()
|
regions_file:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 34 个地区按大区分组,收起时只显示已选地区,展开后可搜索(模板 minigate/region_select)
|
||||||
|
local REGION_GROUPS = {"华北", "东北", "华东", "华中", "华南", "西南", "西北", "港澳台"}
|
||||||
|
local function region_group(code)
|
||||||
|
local prefix = tonumber(code:sub(1, 2)) or 99
|
||||||
|
if prefix < 20 then return 1 elseif prefix < 30 then return 2 elseif prefix < 40 then return 3
|
||||||
|
elseif prefix < 44 then return 4 elseif prefix < 50 then return 5 elseif prefix < 60 then return 6
|
||||||
|
elseif prefix < 70 then return 7 end
|
||||||
|
return 8
|
||||||
|
end
|
||||||
|
|
||||||
o = s:option(MultiValue, "access_regions", "允许的省级地区", "勾选允许访问的地区,可多选。关闭地区限制即恢复所有地区访问。")
|
o = s:option(MultiValue, "access_regions", "允许的省级地区", "勾选允许访问的地区,可多选。关闭地区限制即恢复所有地区访问。")
|
||||||
o.widget = "checkbox"
|
o.widget = "checkbox"
|
||||||
o.size = 6
|
o.template = "minigate/region_select"
|
||||||
o.default = "510000"
|
o.default = "510000"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
o:depends("access_enabled", "1")
|
o:depends("access_enabled", "1")
|
||||||
|
o.groups = {}
|
||||||
|
for i, name in ipairs(REGION_GROUPS) do o.groups[i] = {name, {}} end
|
||||||
-- 旧版本以 list 保存;统一转成以空格分隔的字符串供复选框回显
|
-- 旧版本以 list 保存;统一转成以空格分隔的字符串供复选框回显
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
local value = m.uci:get("minigate", section, "access_regions")
|
local value = m.uci:get("minigate", section, "access_regions")
|
||||||
@@ -235,6 +247,8 @@ local valid_regions = {}
|
|||||||
for _, region in ipairs(access_regions) do
|
for _, region in ipairs(access_regions) do
|
||||||
o:value(region[1], region[2])
|
o:value(region[1], region[2])
|
||||||
valid_regions[region[1]] = true
|
valid_regions[region[1]] = true
|
||||||
|
local group = o.groups[region_group(region[1])][2]
|
||||||
|
group[#group + 1] = region[1]
|
||||||
end
|
end
|
||||||
o.validate = function(self, value, section)
|
o.validate = function(self, value, section)
|
||||||
local values = {}
|
local values = {}
|
||||||
@@ -247,7 +261,13 @@ o.validate = function(self, value, section)
|
|||||||
for _, code in ipairs(values) do
|
for _, code in ipairs(values) do
|
||||||
if not valid_regions[code] then return nil, "请从列表中选择有效的省级地区" end
|
if not valid_regions[code] then return nil, "请从列表中选择有效的省级地区" end
|
||||||
end
|
end
|
||||||
return value
|
return table.concat(values, " ")
|
||||||
|
end
|
||||||
|
-- 关闭地区限制时这个字段被隐藏、不会提交;LuCI 不在服务端判断依赖,
|
||||||
|
-- 不跳过会把「未提交」当成未选择而报错,导致整页无法保存。
|
||||||
|
o.parse = function(self, section, novld)
|
||||||
|
if self.map:formvalue("cbid.minigate." .. section .. ".access_enabled") ~= "1" then return end
|
||||||
|
return MultiValue.parse(self, section, novld)
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
<%+cbi/valueheader%>
|
||||||
|
<%
|
||||||
|
local selected = {}
|
||||||
|
for code in tostring(self:cfgvalue(section) or self.default or ""):gmatch("%S+") do selected[code] = true end
|
||||||
|
local names = {}
|
||||||
|
for i, key in ipairs(self.keylist) do names[key] = self.vallist[i] end
|
||||||
|
%>
|
||||||
|
<div class="mgx-region" id="<%=cbid%>.region">
|
||||||
|
<div class="mgx-region-field" role="button" tabindex="0" aria-expanded="false" aria-controls="<%=cbid%>.panel">
|
||||||
|
<span class="mgx-region-chips"></span>
|
||||||
|
<span class="mgx-region-count mgx-muted"></span>
|
||||||
|
<span class="mgx-region-arrow mgx-muted" aria-hidden="true">▾</span>
|
||||||
|
</div>
|
||||||
|
<div class="mgx-region-panel" id="<%=cbid%>.panel" hidden="hidden">
|
||||||
|
<div class="mgx-region-tools">
|
||||||
|
<input type="text" class="cbi-input-text mgx-region-search" placeholder="搜索地区,如 川、重庆、西南" aria-label="搜索地区" />
|
||||||
|
<button type="button" class="cbi-button mgx-region-clear">清空</button>
|
||||||
|
</div>
|
||||||
|
<% for _, group in ipairs(self.groups) do if #group[2] > 0 then %>
|
||||||
|
<div class="mgx-region-group" data-group="<%=pcdata(group[1])%>">
|
||||||
|
<div class="mgx-region-gname"><%=pcdata(group[1])%></div>
|
||||||
|
<div class="mgx-region-items">
|
||||||
|
<% for _, code in ipairs(group[2]) do %>
|
||||||
|
<label data-name="<%=pcdata(names[code])%>"><input type="checkbox" class="cbi-input-checkbox" name="<%=cbid%>" value="<%=code%>"<% if selected[code] then %> checked="checked"<% end %> /> <%=pcdata(names[code])%></label>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end end %>
|
||||||
|
<div class="mgx-region-empty mgx-muted" hidden="hidden">没有匹配的地区</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function(){
|
||||||
|
var root=document.getElementById('<%=cbid%>.region');
|
||||||
|
if(!root)return;
|
||||||
|
var field=root.querySelector('.mgx-region-field'),panel=root.querySelector('.mgx-region-panel');
|
||||||
|
var chips=root.querySelector('.mgx-region-chips'),count=root.querySelector('.mgx-region-count');
|
||||||
|
var boxes=root.querySelectorAll('input[type=checkbox]');
|
||||||
|
function render(){
|
||||||
|
chips.textContent='';
|
||||||
|
var n=0;
|
||||||
|
for(var i=0;i<boxes.length;i++){
|
||||||
|
if(!boxes[i].checked)continue;
|
||||||
|
n++;
|
||||||
|
var chip=document.createElement('span'),remove=document.createElement('button');
|
||||||
|
chip.className='mgx-region-chip';
|
||||||
|
chip.appendChild(document.createTextNode(boxes[i].parentNode.getAttribute('data-name')));
|
||||||
|
remove.type='button';
|
||||||
|
remove.className='mgx-region-remove';
|
||||||
|
remove.setAttribute('aria-label','移除'+boxes[i].parentNode.getAttribute('data-name'));
|
||||||
|
remove.textContent='×';
|
||||||
|
remove.onclick=(function(box){return function(e){e.stopPropagation();box.checked=false;render();};})(boxes[i]);
|
||||||
|
chip.appendChild(remove);
|
||||||
|
chips.appendChild(chip);
|
||||||
|
}
|
||||||
|
if(!n){
|
||||||
|
var hint=document.createElement('span');
|
||||||
|
hint.className='mgx-err';
|
||||||
|
hint.textContent='请至少选择一个地区';
|
||||||
|
chips.appendChild(hint);
|
||||||
|
}
|
||||||
|
count.textContent='已选 '+n+' 个';
|
||||||
|
}
|
||||||
|
function toggle(open){
|
||||||
|
if(open===undefined)open=panel.hidden;
|
||||||
|
panel.hidden=!open;
|
||||||
|
field.setAttribute('aria-expanded',open?'true':'false');
|
||||||
|
if(open)root.querySelector('.mgx-region-search').focus();
|
||||||
|
}
|
||||||
|
field.onclick=function(){toggle();};
|
||||||
|
field.onkeydown=function(e){if(e.key==='Enter'||e.key===' '){e.preventDefault();toggle();}};
|
||||||
|
for(var i=0;i<boxes.length;i++)boxes[i].onchange=render;
|
||||||
|
root.querySelector('.mgx-region-clear').onclick=function(){for(var i=0;i<boxes.length;i++)boxes[i].checked=false;render();};
|
||||||
|
// 按地区名或大区名筛选;回车不提交整页表单
|
||||||
|
var search=root.querySelector('.mgx-region-search');
|
||||||
|
search.onkeydown=function(e){if(e.key==='Enter')e.preventDefault();};
|
||||||
|
search.oninput=function(){
|
||||||
|
var q=search.value.replace(/\s+/g,''),groups=root.querySelectorAll('.mgx-region-group'),shown=0;
|
||||||
|
for(var g=0;g<groups.length;g++){
|
||||||
|
var labels=groups[g].querySelectorAll('label'),any=false,inGroup=!q||groups[g].getAttribute('data-group').indexOf(q)>=0;
|
||||||
|
for(var l=0;l<labels.length;l++){
|
||||||
|
var hit=inGroup||labels[l].getAttribute('data-name').indexOf(q)>=0;
|
||||||
|
labels[l].hidden=!hit;
|
||||||
|
if(hit)any=true;
|
||||||
|
}
|
||||||
|
groups[g].hidden=!any;
|
||||||
|
if(any)shown++;
|
||||||
|
}
|
||||||
|
root.querySelector('.mgx-region-empty').hidden=shown>0;
|
||||||
|
};
|
||||||
|
render();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<%+cbi/valuefooter%>
|
||||||
@@ -21,6 +21,25 @@
|
|||||||
.mgx-actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:10px}
|
.mgx-actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:10px}
|
||||||
.mgx-sync{margin-top:4px;font-size:12px!important;padding:2px 10px!important}
|
.mgx-sync{margin-top:4px;font-size:12px!important;padding:2px 10px!important}
|
||||||
.mgx-sync-result{margin-left:8px;font-size:12px}
|
.mgx-sync-result{margin-left:8px;font-size:12px}
|
||||||
|
.mgx-region{max-width:720px}
|
||||||
|
.mgx-region [hidden]{display:none!important}
|
||||||
|
.mgx-region-field{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:34px;padding:5px 8px;border:1px solid var(--mgx-border);border-radius:6px;background:var(--mgx-control);color:var(--mgx-text);cursor:pointer;box-sizing:border-box}
|
||||||
|
.mgx-region-field:focus{outline:2px solid var(--mgx-info);outline-offset:1px}
|
||||||
|
.mgx-region-chips{display:contents}
|
||||||
|
.mgx-region-chip{display:inline-flex;align-items:center;gap:2px;padding:1px 4px 1px 8px;border-radius:4px;background:rgba(25,113,194,.14);color:var(--mgx-info);font-size:12px;line-height:20px}
|
||||||
|
.mgx-region-remove{min-width:0!important;height:20px!important;margin:0!important;padding:0 4px!important;border:0!important;background:transparent!important;color:inherit!important;font-size:14px!important;line-height:20px!important;cursor:pointer;box-shadow:none!important}
|
||||||
|
.mgx-region-count{margin-left:auto;font-size:12px;white-space:nowrap}
|
||||||
|
.mgx-region-arrow{font-size:12px}
|
||||||
|
.mgx-region-panel{margin-top:6px;padding:8px 12px;border:1px solid var(--mgx-border);border-radius:6px;background:var(--mgx-surface)}
|
||||||
|
.mgx-region-tools{display:flex;gap:8px;align-items:center;margin-bottom:4px}
|
||||||
|
.mgx-region-search{flex:1;min-width:0}
|
||||||
|
.mgx-region-group{display:grid;grid-template-columns:4em minmax(0,1fr);gap:4px 10px;padding:6px 0;border-top:1px solid var(--mgx-border)}
|
||||||
|
.mgx-region-gname{padding-top:2px;color:var(--mgx-muted);font-size:12px}
|
||||||
|
.mgx-region-items{display:grid;grid-template-columns:repeat(auto-fill,minmax(9.5em,1fr));gap:4px 12px}
|
||||||
|
.mgx-region-items label{display:flex;align-items:center;gap:6px;margin:0;color:var(--mgx-text);font-size:13px;white-space:nowrap;cursor:pointer}
|
||||||
|
.mgx-region-items input{margin:0}
|
||||||
|
.mgx-region-empty{padding:8px 0;font-size:12px}
|
||||||
|
@media(max-width:640px){.mgx-region-group{grid-template-columns:minmax(0,1fr)}.mgx-region-items{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||||
@keyframes mgx-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
|
@keyframes mgx-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
|
||||||
.mgx-spin{display:inline-block;margin-right:8px;animation:mgx-spin 1s linear infinite}
|
.mgx-spin{display:inline-block;margin-right:8px;animation:mgx-spin 1s linear infinite}
|
||||||
</style>
|
</style>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
## 地区选择整理
|
||||||
|
|
||||||
|
「反向代理 → 高级设置:公网访问范围」中的地区选择改为收起式控件。原来 34 个复选框依次排开,看起来比较凌乱。
|
||||||
|
|
||||||
|
- 收起时只显示已选地区的标签和已选数量,例如「四川省 ×」「已选 1 个」。点标签上的 × 就能移除对应地区。
|
||||||
|
- 展开后,地区按华北、东北、华东、华中、华南、西南、西北、港澳台分组,各组对齐排列;手机上自动改为两列。
|
||||||
|
- 支持按地区名或大区名搜索,例如输入「川」「重庆」「西南」;也可以一键清空。全部清空时会提示至少选择一个地区。
|
||||||
|
- 复选框仍是 LuCI 原生表单字段,提交和保存方式不变;同时兼容旧版保存为列表的配置。
|
||||||
|
|
||||||
|
## 修复
|
||||||
|
|
||||||
|
修复 v2026.10.28 的一个问题:关闭「限制公网访问地区」后,保存反向代理页会提示未选择地区,导致整页无法保存。原因是地区字段隐藏后不会提交,LuCI 把“未提交”当成“没有选择”。现在只在开启地区限制时检查地区选择,关闭限制时保留原有选择。
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
- 本地完整测试全部通过,无跳过。新增测试覆盖三类内容:
|
||||||
|
- 用真实页面数据渲染地区模板:34 个原生复选框、8 个分组、已选状态;
|
||||||
|
- 兼容旧版的列表格式;
|
||||||
|
- 关闭地区限制时不再阻止保存。
|
||||||
|
- 在浏览器中检查了深色、浅色和 375px 手机宽度下的显示,以及展开、搜索、勾选、移除标签、清空和表单提交,均正常,页面没有横向溢出。
|
||||||
|
- 浏览器检查用的是模拟的 LuCI 页面外框,FanchmWrt 主题下的实际效果需安装后确认。
|
||||||
|
- 本次不自动更新路由器。
|
||||||
|
|
||||||
|
## 安装包
|
||||||
|
|
||||||
|
- opkg 安装包:`minigate_2026.10.28-1_all.ipk`。
|
||||||
|
- 源码安装包:`minigate-v2026.10.28-1-src.tar.gz`。
|
||||||
|
- 兼容旧更新器:`luci-app-minigate-v2026.10.28-1-src.tar.gz`。
|
||||||
|
- 使用随附的 `SHA256SUMS` 校验文件完整性。
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
## 修复登录防护无法封禁新 IP
|
||||||
|
|
||||||
|
修复 v2026.10.28 引入的回归:从 v2026.10.28 起,登录失败次数达到阈值后,登录防护封禁的是一个空地址。日志里显示 `封禁 失败:防火墙未接受该地址`,攻击来源的失败次数一直累加,却不会被封禁。
|
||||||
|
|
||||||
|
- 原因:修复防火墙时会读取持久化的封禁文件,读取循环里的 `ip` 变量没有声明为局部变量。shell 的 `local` 是动态作用域,读到文件末尾时把调用方准备封禁的地址清空了。
|
||||||
|
- 修复:把读取循环中的变量改为局部变量。新增的回归测试分别覆盖防火墙集合完好和重载后为空两种情况,确认达到阈值后封禁的是正确地址、写入封禁文件并清除失败计数。
|
||||||
|
- 升级前已生效的封禁不受影响,升级后新的攻击来源恢复正常封禁。
|
||||||
|
|
||||||
|
## 说明
|
||||||
|
|
||||||
|
「公网访问范围」只限制 MiniGate 反代的网站,不会把 IP 加入封禁列表。登录防护页面的封禁列表来自 SSH 和 LuCI 登录失败,不区分地区。SSH 端口对公网开放时,各地的爆破来源都会出现在这个列表里。
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
- 本地完整测试全部通过,无跳过;CI 在 Ubuntu(dash)下运行同一套测试。
|
||||||
|
- 新的回归测试在修复前失败,修复后通过;同一场景也已在 dash 下单独复验。
|
||||||
|
- 本次不自动更新路由器。
|
||||||
|
|
||||||
|
## 安装包
|
||||||
|
|
||||||
|
- opkg 安装包:`minigate_2026.10.28-2_all.ipk`。
|
||||||
|
- 源码安装包:`minigate-v2026.10.28-2-src.tar.gz`。
|
||||||
|
- 兼容旧更新器:`luci-app-minigate-v2026.10.28-2-src.tar.gz`。
|
||||||
|
- 使用随附的 `SHA256SUMS` 校验文件完整性。
|
||||||
@@ -208,7 +208,8 @@ ensure_nft() {
|
|||||||
|
|
||||||
# 防火墙重载后,随包的集合会重新出现但内容为空;持久化文件里仍有未过期封禁时恢复
|
# 防火墙重载后,随包的集合会重新出现但内容为空;持久化文件里仍有未过期封禁时恢复
|
||||||
sets_lost_bans() {
|
sets_lost_bans() {
|
||||||
local now set
|
# ip/exp 必须是局部变量:shell 的 local 是动态作用域,读到文件末尾会清空调用方的 ip
|
||||||
|
local now set ip exp
|
||||||
now=$(date +%s)
|
now=$(date +%s)
|
||||||
for set in "$SET4" "$SET6"; do
|
for set in "$SET4" "$SET6"; do
|
||||||
nft list set $TABLE $set 2>/dev/null | grep -q 'elements' && continue
|
nft list set $TABLE $set 2>/dev/null | grep -q 'elements' && continue
|
||||||
@@ -255,7 +256,7 @@ restore_bans() {
|
|||||||
local now=$(date +%s)
|
local now=$(date +%s)
|
||||||
local tmp="${BANS_FILE}.tmp"
|
local tmp="${BANS_FILE}.tmp"
|
||||||
> "$tmp"
|
> "$tmp"
|
||||||
local count=0
|
local count=0 ip exp
|
||||||
while read -r ip exp; do
|
while read -r ip exp; do
|
||||||
[ -z "$ip" ] && continue
|
[ -z "$ip" ] && continue
|
||||||
case "$exp" in ''|*[!0-9]*) continue ;; esac
|
case "$exp" in ''|*[!0-9]*) continue ;; esac
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
export PATH
|
export PATH
|
||||||
|
|
||||||
CURRENT_VERSION="2026.10.28"
|
CURRENT_VERSION="2026.10.28-2"
|
||||||
REPOSITORY="tpxcer/minigate"
|
REPOSITORY="tpxcer/minigate"
|
||||||
API_URL="https://api.github.com/repos/${REPOSITORY}/releases/latest"
|
API_URL="https://api.github.com/repos/${REPOSITORY}/releases/latest"
|
||||||
DOWNLOAD_ROOT="https://github.com/${REPOSITORY}/releases/download"
|
DOWNLOAD_ROOT="https://github.com/${REPOSITORY}/releases/download"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ ROOT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
|||||||
OUT_DIR="${1:-$ROOT_DIR/dist}"
|
OUT_DIR="${1:-$ROOT_DIR/dist}"
|
||||||
|
|
||||||
PKG_NAME="minigate"
|
PKG_NAME="minigate"
|
||||||
PKG_VERSION="2026.10.28"
|
PKG_VERSION="2026.10.28-2"
|
||||||
PKG_ARCH="all"
|
PKG_ARCH="all"
|
||||||
PKG_FILE="${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}.ipk"
|
PKG_FILE="${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}.ipk"
|
||||||
DEPS="libc, luci-base, luci-compat, nginx-ssl, nginx-mod-stream, openssl-util, wget, curl, jsonfilter, coreutils-stat, nftables"
|
DEPS="libc, luci-base, luci-compat, nginx-ssl, nginx-mod-stream, openssl-util, wget, curl, jsonfilter, coreutils-stat, nftables"
|
||||||
|
|||||||
@@ -178,3 +178,38 @@ test('upgrades stop the old login guard tree before running the previous init sc
|
|||||||
assert.ok(treeStop > 0 && treeStop < initStop, 'installer must stop the login guard tree before the old init script');
|
assert.ok(treeStop > 0 && treeStop < initStop, 'installer must stop the login guard tree before the old init script');
|
||||||
assert.match(installer, /stop_process_tree\(\) \{[\s\S]*pgrep -P "\$1"/);
|
assert.match(installer, /stop_process_tree\(\) \{[\s\S]*pgrep -P "\$1"/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 回归:v2026.10.28 中修复防火墙时读取 bans.txt 的循环变量覆盖了调用方的 ip,
|
||||||
|
// 达到阈值后用空地址封禁,日志出现「封禁 失败」,攻击者再也不会被封。
|
||||||
|
test('reaching the threshold bans the attacking address even when other bans are persisted', () => {
|
||||||
|
for (const setsEmpty of [false, true]) {
|
||||||
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'minigate-lg-threshold-'));
|
||||||
|
const dataDir = path.join(dir, 'data');
|
||||||
|
const calls = path.join(dir, 'nft.log');
|
||||||
|
fs.mkdirSync(dataDir);
|
||||||
|
fs.writeFileSync(path.join(dataDir, 'bans.txt'), '111.170.34.182 9999999999\n185.246.128.170 9999999999\n');
|
||||||
|
const result = spawnSync('/bin/sh', ['-c', `
|
||||||
|
logger() { :; }
|
||||||
|
uci() { case "$3" in minigate.login_guard.threshold) echo 3 ;; *) return 1 ;; esac; }
|
||||||
|
nft() {
|
||||||
|
printf '%s\\n' "$*" >> ${JSON.stringify(calls)}
|
||||||
|
case "$*" in
|
||||||
|
'list set inet fw4 login_banned_v4'|'list set inet fw4 login_banned_v6') [ ${setsEmpty ? 1 : 0} = 1 ] || echo 'elements = { 111.170.34.182 }' ;;
|
||||||
|
'list chain inet fw4 input') echo '@login_banned_v4 @login_banned_v6' ;;
|
||||||
|
esac
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
export MINIGATE_LG_LIBRARY_ONLY=1 MINIGATE_LG_DATA_DIR=${JSON.stringify(dataDir)}
|
||||||
|
export MINIGATE_LG_RUN_DIR=${JSON.stringify(path.join(dir, 'run'))} MINIGATE_LG_LOG=${JSON.stringify(path.join(dir, 'lg.log'))}
|
||||||
|
. ${JSON.stringify(script)}
|
||||||
|
for i in 1 2 3; do handle_failure 139.162.161.162; done
|
||||||
|
`], { encoding: 'utf8' });
|
||||||
|
assert.equal(result.status, 0, result.stderr);
|
||||||
|
const log = fs.readFileSync(path.join(dir, 'lg.log'), 'utf8');
|
||||||
|
assert.match(fs.readFileSync(calls, 'utf8'), /add element inet fw4 login_banned_v4 \{ 139\.162\.161\.162 timeout 43200s \}/, `setsEmpty=${setsEmpty}`);
|
||||||
|
assert.match(log, /BAN 139\.162\.161\.162 12小时(达到 3 次失败)/);
|
||||||
|
assert.doesNotMatch(log, /封禁 +失败/);
|
||||||
|
assert.match(fs.readFileSync(path.join(dataDir, 'bans.txt'), 'utf8'), /^139\.162\.161\.162 \d+$/m);
|
||||||
|
assert.equal(fs.existsSync(path.join(dir, 'run/counters/139.162.161.162')), false, 'counter is cleared after a ban');
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
const { test } = require('node:test');
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const { spawnSync } = require('node:child_process');
|
||||||
|
|
||||||
|
const lua = process.env.MINIGATE_TEST_LUA;
|
||||||
|
const root = path.resolve(__dirname, '..');
|
||||||
|
const template = path.join(root, 'luasrc/view/minigate/region_select.htm');
|
||||||
|
const proxyPage = path.join(root, 'luasrc/model/cbi/minigate/proxy.lua');
|
||||||
|
const regions = path.join(root, 'root/usr/lib/minigate/geo/regions.txt');
|
||||||
|
|
||||||
|
// 最小的 LuCI 模板解释器:只支持本模板用到的 <% %>、<%= %> 和 <%+ %>(include 输出占位)
|
||||||
|
const renderer = `
|
||||||
|
local function compile(src)
|
||||||
|
local code, pos = {"local _o = {}\\nlocal function _w(v) _o[#_o + 1] = tostring(v) end\\n"}, 1
|
||||||
|
while true do
|
||||||
|
local s, e = src:find("<%", pos, true)
|
||||||
|
local text = src:sub(pos, (s or 0) - 1)
|
||||||
|
if s == nil then text = src:sub(pos) end
|
||||||
|
code[#code + 1] = "_w(" .. string.format("%q", text) .. ")\\n"
|
||||||
|
if not s then break end
|
||||||
|
local close = assert(src:find("%>", e + 1, true), "unclosed tag")
|
||||||
|
local body = src:sub(e + 1, close - 1)
|
||||||
|
local mode = body:sub(1, 1)
|
||||||
|
if mode == "=" then
|
||||||
|
code[#code + 1] = "_w(" .. body:sub(2) .. ")\\n"
|
||||||
|
elseif mode == "+" then
|
||||||
|
code[#code + 1] = "_w('<!--include " .. body:sub(2):gsub("%s", "") .. "-->')\\n"
|
||||||
|
else
|
||||||
|
code[#code + 1] = body .. "\\n"
|
||||||
|
end
|
||||||
|
pos = close + 2
|
||||||
|
end
|
||||||
|
code[#code + 1] = "return table.concat(_o)"
|
||||||
|
return table.concat(code)
|
||||||
|
end
|
||||||
|
|
||||||
|
function render_template(file, scope)
|
||||||
|
local f = assert(io.open(file)); local src = f:read("*a"); f:close()
|
||||||
|
local fn = assert(loadstring(compile(src), file))
|
||||||
|
setfenv(fn, setmetatable(scope, {__index = _G}))
|
||||||
|
return fn()
|
||||||
|
end
|
||||||
|
|
||||||
|
function pcdata(v)
|
||||||
|
return (tostring(v or ""):gsub("[&<>\\"']", {["&"]="&", ["<"]="<", [">"]=">", ['"']=""", ["'"]="'"}))
|
||||||
|
end
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 用 proxy.lua 生成真实的 option(分组、选项、cfgvalue),再渲染模板
|
||||||
|
const pageLoader = `
|
||||||
|
local options, stored = {}, nil
|
||||||
|
local function node()
|
||||||
|
local n = {}
|
||||||
|
function n:option(kind, name)
|
||||||
|
local o = {kind=kind, name=name, keylist={}, vallist={}}
|
||||||
|
function o:value(k, v) self.keylist[#self.keylist + 1] = k; self.vallist[#self.vallist + 1] = v or k end
|
||||||
|
function o:depends() end
|
||||||
|
options[name] = o
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
function Map()
|
||||||
|
local m = node()
|
||||||
|
m.uci = {get=function() return stored end}
|
||||||
|
function m:section() return node() end
|
||||||
|
return m
|
||||||
|
end
|
||||||
|
for _, name in ipairs({'Flag','Value','DynamicList','ListValue','DummyValue','MultiValue','NamedSection','TypedSection','SimpleSection'}) do _G[name] = name end
|
||||||
|
package.preload['luci.model.uci'] = function() return {cursor=function() return {foreach=function() end, get=function() return nil end} end} end
|
||||||
|
package.preload['luci.controller.minigate'] = function() return {ddns_state=function() return {} end} end
|
||||||
|
local real_open = io.open
|
||||||
|
io.open = function(file, mode)
|
||||||
|
if file == '/usr/lib/minigate/geo/regions.txt' then file = ${JSON.stringify(regions)} end
|
||||||
|
return real_open(file, mode)
|
||||||
|
end
|
||||||
|
assert(dofile(${JSON.stringify(proxyPage)}))
|
||||||
|
local o = options.access_regions
|
||||||
|
function render_regions(value)
|
||||||
|
stored = value
|
||||||
|
return render_template(${JSON.stringify(template)}, {self=o, section='global', cbid='cbid.minigate.global.access_regions'})
|
||||||
|
end
|
||||||
|
`;
|
||||||
|
|
||||||
|
function run(body) {
|
||||||
|
const result = spawnSync(lua, ['-'], { encoding: 'utf8', input: renderer + pageLoader + body });
|
||||||
|
assert.equal(result.status, 0, result.stderr || result.stdout);
|
||||||
|
return result.stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
test('region selector renders 34 native checkboxes grouped by region with saved choices checked', { skip: !lua }, () => {
|
||||||
|
const html = run(`io.write(render_regions({'510000', '500000'}))`);
|
||||||
|
const boxes = html.match(/<input type="checkbox" class="cbi-input-checkbox" name="cbid\.minigate\.global\.access_regions" value="\d{6}"[^>]*>/g) || [];
|
||||||
|
assert.equal(boxes.length, 34);
|
||||||
|
const checked = boxes.filter(box => box.includes('checked="checked"')).map(box => box.match(/value="(\d+)"/)[1]);
|
||||||
|
assert.deepEqual(checked.sort(), ['500000', '510000']);
|
||||||
|
const groups = [...html.matchAll(/data-group="([^"]+)"/g)].map(match => match[1]);
|
||||||
|
assert.deepEqual(groups, ['华北', '东北', '华东', '华中', '华南', '西南', '西北', '港澳台']);
|
||||||
|
const southwest = html.slice(html.indexOf('data-group="西南"'), html.indexOf('data-group="西北"'));
|
||||||
|
for (const name of ['重庆市', '四川省', '贵州省', '云南省', '西藏']) assert.ok(southwest.includes(`data-name="${name}"`), name);
|
||||||
|
assert.match(html, /^<!--include cbi\/valueheader-->/);
|
||||||
|
assert.match(html, /<!--include cbi\/valuefooter-->\s*$/);
|
||||||
|
assert.match(html, /id="cbid\.minigate\.global\.access_regions\.panel" hidden="hidden"/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('region selector accepts the old list format and falls back to the default region', { skip: !lua }, () => {
|
||||||
|
const out = run(`
|
||||||
|
local function checked(html) local n = 0; for _ in html:gmatch('checked="checked"') do n = n + 1 end; return n end
|
||||||
|
print(checked(render_regions('510000 500000 440000')), checked(render_regions(nil)), render_regions(nil):match('value="510000" checked') ~= nil)
|
||||||
|
`);
|
||||||
|
assert.equal(out.trim(), '3\t1\ttrue');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('region choices are saved as one string and a hidden field never blocks saving the page', { skip: !lua }, () => {
|
||||||
|
const out = run(`
|
||||||
|
local o = options.access_regions
|
||||||
|
print(o.validate(o, {'510000', '500000'}, 'global'), o.validate(o, '510000', 'global'))
|
||||||
|
print(o.validate(o, {'510000', '990000'}, 'global'), (select(2, o.validate(o, nil, 'global'))))
|
||||||
|
local parsed = 0
|
||||||
|
MultiValue = {parse=function() parsed = parsed + 1 end}
|
||||||
|
local form = {}
|
||||||
|
o.map = {formvalue=function(_, key) return form[key] end}
|
||||||
|
o.parse(o, 'global')
|
||||||
|
form['cbid.minigate.global.access_enabled'] = '1'
|
||||||
|
o.parse(o, 'global')
|
||||||
|
print(parsed)
|
||||||
|
`);
|
||||||
|
assert.equal(out.trim(), '510000 500000\t510000\nnil\t请选择至少一个允许的地区\n1');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('region selector script keeps the page form intact and styles follow the theme', () => {
|
||||||
|
const html = fs.readFileSync(template, 'utf8');
|
||||||
|
const style = fs.readFileSync(path.join(root, 'luasrc/view/minigate/style.htm'), 'utf8');
|
||||||
|
// 芯片的移除按钮、清空按钮都不能提交表单;搜索框回车不提交
|
||||||
|
assert.match(html, /remove\.type='button'/);
|
||||||
|
assert.match(html, /<button type="button" class="cbi-button mgx-region-clear">/);
|
||||||
|
assert.match(html, /search\.onkeydown=function\(e\)\{if\(e\.key==='Enter'\)e\.preventDefault\(\);\}/);
|
||||||
|
assert.match(style, /\.mgx-region-items\{display:grid;grid-template-columns:repeat\(auto-fill,minmax\(9\.5em,1fr\)\)/);
|
||||||
|
assert.match(style, /\.mgx-region \[hidden\]\{display:none!important\}/);
|
||||||
|
});
|
||||||
+2
-2
@@ -7,8 +7,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=upx
|
PKG_NAME:=upx
|
||||||
PKG_VERSION:=5.2.1
|
PKG_VERSION:=5.3.0
|
||||||
PKG_RELEASE:=4
|
PKG_RELEASE:=5
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-src.tar.xz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-src.tar.xz
|
||||||
PKG_SOURCE_URL:=https://github.com/upx/upx/releases/download/v$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://github.com/upx/upx/releases/download/v$(PKG_VERSION)
|
||||||
|
|||||||
Reference in new issue
Block a user