🌈 Sync 2026-10-12 17:49:17

This commit is contained in:
github-actions[bot] committed 2026-10-12 17:49:17 +08:00
1 parent c875320795
commit 8e0a32565f
22 files changed
+864 -798

No files matched your search

+2 -2
View File
@@ -11,8 +11,8 @@ PKG_ARCH_ISTOREENHANCE:=$(ARCH)
PKG_NAME:=istoreenhance
# use PKG_SOURCE_DATE instead of PKG_VERSION for compitable
PKG_SOURCE_DATE:=0.8.3
PKG_RELEASE:=12
PKG_SOURCE_DATE:=0.8.4
PKG_RELEASE:=13
ARCH_HEXCODE:=
ifeq ($(ARCH),x86_64)
ARCH_HEXCODE=8664
+2 -2
View File
@@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk
PKG_ARCH_KS_CLI:=$(ARCH)
PKG_NAME:=ks-cli
PKG_VERSION:=0.8.3
PKG_RELEASE:=1
PKG_VERSION:=0.8.4
PKG_RELEASE:=2
PKG_SOURCE:=ks-cli-binary-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/kspeeder/docker_kspeeder/releases/download/v$(PKG_VERSION)/
+1 -1
View File
@@ -1 +1 @@
both
snapshot
@@ -1 +1 @@
26.284.22796~1a36248
26.284.67820~acda1ad
+4 -2
View File
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2024-2025 Anya Lin <hukk1996@gmail.com>
# Copyright (C) 2024-2026 Anya Lin <hukk1996@gmail.com>
include $(TOPDIR)/rules.mk
@@ -29,6 +29,7 @@ define Package/luci-app-fchomo/conffiles
/etc/fchomo/geoip.dat
/etc/fchomo/geosite.dat
/etc/fchomo/asn.mmdb
/etc/fchomo/BundleMRS.7z
/etc/fchomo/cache.db
endef
@@ -50,7 +51,8 @@ fi
[ "$$REVISION" -ge 28158 -o "$$REVISION" -eq 0 ] || { 2>&1 echo "Minimum OpenWrt version required is 24.10."; exit 1; }
# https://archive.openwrt.org/releases/**/version.buildinfo
# r?????-?????????? 25.??.?-rc1
# r?????-?????????? 26.??.?-rc1
# r32353-9e9b05130c 25.12.0-rc1
# r28158-d276b4c91a 24.10.0-rc1
# r23069-e2701e0f33 23.05.0-rc1
+1 -1
View File
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-honk
PKG_VERSION:=1.1.4
PKG_RELEASE:=23
PKG_RELEASE:=24
LUCI_TITLE:=LuCI support for honk
LUCI_PKGARCH:=all
@@ -333,7 +333,7 @@ function ensureEditorStyles() {
'.honk-editor-toolbar { margin-bottom: 6px !important; margin-top: 0 !important; display: flex !important; align-items: center !important; justify-content: flex-start !important; }',
'.cm-format-btn { margin: 0 !important; cursor: pointer !important; }',
'.cbi-value:has(.CodeMirror) { align-items: flex-start !important; }',
'.cbi-value:has(.CodeMirror) > .cbi-value-title { padding-top: 5px !important; }',
'.cbi-value:has(.CodeMirror) > .cbi-value-title { padding-top: 5px !important; flex-grow: 0 !important; }',
'.cbi-value:has(.CodeMirror) .cbi-value-field { flex: 1 1 0% !important; min-width: 0 !important; width: auto !important; }',
'.CodeMirror {',
' border: 1px solid var(--border, var(--hairline, var(--border-color-medium, #ccc))) !important;',
@@ -4,7 +4,6 @@
local uci = require("luci.model.uci").cursor()
%>
<script type="text/javascript" src="<%=resource%>/cbi.js?v=git-18.193.28471-ee087a1"></script>
<script type="text/javascript">//<![CDATA[
var stxhr = new XHR();
+2 -2
View File
@@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for KSpeeder
LUCI_DEPENDS:=+istoreenhance +luci-lib-linkeaseauth +linkease-app-entry
LUCI_PKGARCH:=all
PKG_VERSION:=0.8.3
PKG_RELEASE:=5
PKG_VERSION:=0.8.4
PKG_RELEASE:=6
include $(TOPDIR)/feeds/luci/luci.mk
@@ -14,7 +14,9 @@ return view.extend({
load: function() {
return Promise.all([
uci.load('network'),
uci.load('openmptcprouter')
// only for the old copy of the mode below: the ACL doesn't
// give this config (VPS passwords and tokens) to non-root users
L.resolveDefault(uci.load('openmptcprouter'), null)
]);
},
@@ -2,7 +2,7 @@
"luci-app-mptcp": {
"description": "Grant UCI access for luci-app-mptcp",
"read": {
"uci": [ "openmptcprouter", "network", "mqvpn" ],
"uci": [ "network", "mqvpn" ],
"file": {
"/usr/lib/mptcpd": [ "list" ],
"/usr/share/bpf/scheduler": [ "list" ],
@@ -28,7 +28,7 @@
}
},
"write": {
"uci": [ "openmptcprouter", "network" ],
"uci": [ "network" ],
"ubus": {
"luci.mptcp": [
"set_settings",
+1 -1
View File
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.10.4
PKG_RELEASE:=328
PKG_RELEASE:=329
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
@@ -178,25 +178,27 @@ end
if not REMOTE_GROUP or REMOTE_GROUP == "nil" then
REMOTE_GROUP = "passwall_proxy"
if REMOTE_DNS then
REMOTE_DNS = REMOTE_DNS:gsub("#", ":")
end
sys.call('sed -i "/passwall/d" /etc/smartdns/custom.conf >/dev/null 2>&1')
end
if REMOTE_DNS then
REMOTE_DNS = REMOTE_DNS:gsub("#", ":")
end
sys.call('sed -i "/passwall/d" /etc/smartdns/custom.conf >/dev/null 2>&1')
local SANDBOX_GROUP = "passwall_" .. FLAG
local force_https_soa = api.uci_get_c("@global[0]", "force_https_soa") or 0
local proxy_server_name = "psw-proxy-server"
local listen_address = "[::]:" .. LISTEN_PORT .. (DNS_REDIRECT and "" or "@lo")
local local_domain = DNS_REDIRECT and api.uci_get("dhcp", "@dnsmasq[0]", "domain")
config_lines = {
tonumber(LISTEN_PORT) ~= 0 and "bind " .. listen_address or "",
tonumber(LISTEN_PORT) ~= 0 and "bind-tcp " .. listen_address or "",
tonumber(LISTEN_PORT) ~= 0 and ("bind " .. listen_address .. " -group " .. SANDBOX_GROUP) or "",
tonumber(LISTEN_PORT) ~= 0 and ("bind-tcp " .. listen_address .. " -group " .. SANDBOX_GROUP) or "",
(tonumber(LOCAL_PORT) ~= 0 and LOCAL_GROUP) and "bind [::]:" .. LOCAL_PORT .. "@lo -group " .. LOCAL_GROUP or "",
(tonumber(LOCAL_PORT) ~= 0 and LOCAL_GROUP) and "bind-tcp [::]:" .. LOCAL_PORT .. "@lo -group " .. LOCAL_GROUP or "",
tonumber(force_https_soa) == 1 and "force-qtype-SOA 65" or "force-qtype-SOA -,65",
"server 223.5.5.5 -bootstrap-dns",
-- Set the suffix before loading hosts/leases so initial records are expanded too.
(local_domain and local_domain ~= "") and "local-domain " .. local_domain or "",
DNS_REDIRECT and "hosts-file /tmp/hosts/*" or "",
is_file_nonzero("/etc/hosts") and "hosts-file /etc/hosts" or "",
DNS_MODE == "socks" and string.format("proxy-server socks5://%s -name %s", REMOTE_PROXY_SERVER, proxy_server_name) or ""
}
@@ -205,6 +207,10 @@ if DNS_REDIRECT then
local lease_file = api.uci_get("dhcp", "@dnsmasq[0]", "leasefile")
if not lease_file or lease_file == "" then lease_file = "/tmp/dhcp.leases" end
table.insert(config_lines, string.format("dnsmasq-lease-file %q", lease_file))
local odhcpd_lease = api.uci_get("dhcp", "odhcpd", "leasefile")
if odhcpd_lease and odhcpd_lease ~= "" then
table.insert(config_lines, string.format("odhcpd-lease-file %q", odhcpd_lease))
end
end
if DNS_MODE == "socks" then
for w in string.gmatch(REMOTE_DNS, '[^|]+') do
@@ -268,6 +274,9 @@ else
log(" - " .. DNS_MODE:gsub("^%l",string.upper) .. " " .. TUN_DNS .. " -> " .. REMOTE_GROUP)
end
-- Isolate PassWall domain rules within dedicated group to avoid polluting SmartDNS default group
table.insert(config_lines, "group-begin " .. SANDBOX_GROUP)
--设置默认 DNS 分组(托底组)
local DEFAULT_DNS_GROUP = (USE_DEFAULT_DNS == "direct" and LOCAL_GROUP) or
(USE_DEFAULT_DNS == "remote" and REMOTE_GROUP)
@@ -768,6 +777,8 @@ if IS_SHUNT_NODE and not only_global then
end
end
table.insert(config_lines, "group-end")
if #config_lines > 0 then
local f_out = io.open(TMP_CONF_FILE, "w")
for i = 1, #config_lines do
+2 -2
View File
@@ -10,8 +10,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-vantage
PKG_VERSION:=1.0.2
PKG_RELEASE:=8
PKG_VERSION:=1.0.3
PKG_RELEASE:=9
PKG_LICENSE:=GPL-3.0-or-later
LUCI_TITLE:=Vantage dashboard
@@ -63,6 +63,10 @@
--vt-b6: var(--vt-chart-4);
--vt-b60: var(--vt-text-2);
--vt-series-up: var(--vt-chart-1);
/* throughput directions: download keeps the uplink colour, upload
takes one that no band uses */
--vt-dir-dn: var(--vt-chart-1);
--vt-dir-up: var(--vt-chart-5);
--vt-mem: var(--vt-info);
--vt-hover: color-mix(in srgb, var(--vt-surface-2) 70%, var(--vt-surface-3));
--vt-av-l: 92%;
@@ -428,6 +432,13 @@ html[data-darkmode="true"] .vt-app {
display: flex; align-items: center; gap: 14px;
margin: 2px 0 14px;
}
header::after {
height:0 !important;
}
h2, h3{
background-color:transparent;
}
.vt-app .vt-orb {
position: relative; flex: none;
width: 38px; height: 38px; border-radius: 50%;
@@ -691,12 +702,14 @@ html[data-darkmode="true"] .vt-app {
.vt-app .vt-chart .vt-tile-title { flex-wrap: wrap; row-gap: 0; }
.vt-app .vt-chart-sub { font-size: 12px; font-weight: 500; color: var(--vt-text-3); }
.vt-app .vt-chart-sub::before { content: "·"; margin: 0 6px 0 0; }
.vt-app .vt-c-up { --vt-sc: var(--vt-series-up); }
.vt-app .vt-c-2g { --vt-sc: var(--vt-b2); }
.vt-app .vt-c-5g { --vt-sc: var(--vt-b5); }
.vt-app .vt-c-6g { --vt-sc: var(--vt-b6); }
.vt-app .vt-c-x { --vt-sc: var(--vt-text-3); }
.vt-app .vt-lg-key { width: 12px; height: 3px; border-radius: 2px; background: var(--vt-sc); flex: none; }
/* one colour per direction in every row (series, gradients, dots, keys) */
.vt-app .vt-chart, .vt-app .vt-chart .vt-k-dn { --vt-sc: var(--vt-dir-dn); }
.vt-app .vt-chart .vt-dir-up, .vt-app .vt-chart .vt-k-up { --vt-sc: var(--vt-dir-up); }
.vt-app .vt-arr { font-weight: 700; }
.vt-app .vt-arr-dn { color: color-mix(in oklab, var(--vt-dir-dn) 70%, var(--vt-text)); }
.vt-app .vt-arr-up { color: color-mix(in oklab, var(--vt-dir-up) 70%, var(--vt-text)); }
.vt-app .vt-dir-legend { font-size: 11.5px; gap: 4px 12px; }
.vt-app .vt-mult-wrap { position: relative; flex: 1; display: flex; flex-direction: column; min-height: 300px; border-radius: var(--vt-r-sm); outline-offset: 4px; }
.vt-app .vt-mults { flex: 1; display: grid; grid-auto-rows: minmax(100px, 1fr); }
@@ -706,9 +719,10 @@ html[data-darkmode="true"] .vt-app {
}
.vt-app .vt-mult:first-child { border-top: 0; padding-top: 2px; }
.vt-app .vt-mult-head { display: flex; flex-direction: column; justify-content: center; gap: 1px; min-width: 0; }
.vt-app .vt-mult-name { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; color: var(--vt-text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vt-app .vt-mult-now { font-size: 17px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; white-space: nowrap; }
.vt-app .vt-mult-now-up { font-size: 13px; font-weight: 650; line-height: 1.3; color: var(--vt-text-2); white-space: nowrap; }
.vt-app .vt-mult-name { font-size: 11.5px; font-weight: 600; color: var(--vt-text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vt-app .vt-mult-now { display: flex; align-items: center; gap: 6px; font-size: 17px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; white-space: nowrap; }
.vt-app .vt-mult-now b { font-weight: inherit; }
.vt-app .vt-mult-now-up { font-size: 13px; font-weight: 650; line-height: 1.3; color: var(--vt-text-2); }
.vt-app .vt-mult-stats { display: flex; flex-wrap: wrap; gap: 0 8px; font-size: 11px; color: var(--vt-text-3); white-space: nowrap; }
.vt-app .vt-mult-stats b { font-weight: 600; color: var(--vt-text-2); }
.vt-app .vt-mult-plot { position: relative; min-height: 72px; margin: 12px 0; --vt-sc: inherit; }
@@ -717,10 +731,6 @@ html[data-darkmode="true"] .vt-app {
.vt-app .vt-chart-vgrid { fill: none; stroke: var(--vt-chart-grid); stroke-width: 1; stroke-dasharray: 2 4; vector-effect: non-scaling-stroke; }
.vt-app .vt-series-line { fill: none; stroke: var(--vt-sc); stroke-width: 1.75; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.vt-app .vt-series-area { stroke: none; }
/* upload, below the line: the link's colour, quieter */
.vt-app .vt-series-line.vt-dir-up { stroke-opacity: .6; }
.vt-app .vt-series-area.vt-dir-up { opacity: .55; }
.vt-app .vt-mult-dot.vt-dir-up, .vt-app .vt-sk-dot.vt-dir-up { opacity: .7; }
.vt-app .vt-chart-mid { fill: none; stroke: color-mix(in oklab, var(--vt-chart-axis) 55%, transparent); stroke-width: 1; vector-effect: non-scaling-stroke; }
.vt-app .vt-mult-max {
position: absolute; right: 0; top: -3px; transform: translateY(-100%);
@@ -739,18 +749,17 @@ html[data-darkmode="true"] .vt-app {
.vt-app .vt-mult-wrap { cursor: crosshair; touch-action: pan-y; }
.vt-app .vt-cursor { position: absolute; top: 0; bottom: 0; width: 0; border-left: 1px solid color-mix(in oklab, var(--vt-text) 45%, transparent); pointer-events: none; }
.vt-app .vt-tip {
position: absolute; top: 4px; z-index: 4; transform: translateX(12px);
position: absolute; top: 4px; z-index: 4;
width: max-content; min-width: 180px; padding: 8px 10px 7px; border-radius: var(--vt-r);
background: var(--vt-surface); border: 1px solid var(--vt-line-2);
box-shadow: 0 10px 28px rgba(12, 14, 17, .16), 0 2px 6px rgba(12, 14, 17, .06);
font-size: 12px; pointer-events: none;
}
.vt-app .vt-tip-left { transform: translateX(calc(-100% - 12px)); }
.vt-app .vt-tip-time { display: flex; justify-content: space-between; gap: 12px; color: var(--vt-text-3); font-size: 11px; margin-bottom: 5px; padding-bottom: 5px; border-bottom: 1px solid var(--vt-line); }
.vt-app .vt-tip-row { display: grid; grid-template-columns: 12px auto auto minmax(0, 1fr); align-items: center; column-gap: 8px; line-height: 1.6; }
.vt-app .vt-tip-row b { font-weight: 700; color: var(--vt-text); white-space: nowrap; }
.vt-app .vt-tip-row .vt-tip-up { font-weight: 600; color: var(--vt-text-2); }
.vt-app .vt-tip-label { color: var(--vt-text-3); white-space: nowrap; text-align: right; }
.vt-app .vt-tip-link + .vt-tip-link { margin-top: 5px; }
.vt-app .vt-tip-label { color: var(--vt-text-3); font-size: 11px; white-space: nowrap; }
.vt-app .vt-tip-row { display: grid; grid-template-columns: 12px auto minmax(0, 1fr); align-items: center; column-gap: 8px; line-height: 1.6; color: var(--vt-text-2); }
.vt-app .vt-tip-row b { font-weight: 700; color: var(--vt-text); white-space: nowrap; text-align: right; }
/* ------------------------------------------------------------ 8. radios */
@@ -50,10 +50,13 @@ function hostapd(ifname, method) {
return L.resolveDefault(hostapdCalls[key](), null);
}
/* revalidated on every load (a 304 when unchanged): LuCI versions its own
scripts, not this sheet, so after an upgrade a browser could pair the
new view with a cached app.css */
var cssPromise = null;
function loadCss() {
if (cssPromise) return cssPromise;
cssPromise = fetch(L.resource('vantage/app.css')).then(function(r) { return r.ok ? r.text() : ''; }).then(function(text) {
cssPromise = fetch(L.resource('vantage/app.css'), { cache: 'no-cache' }).then(function(r) { return r.ok ? r.text() : ''; }).then(function(text) {
if (!text || !('adoptedStyleSheets' in document) || typeof CSSStyleSheet !== 'function') return;
var sheet = new CSSStyleSheet();
sheet.replaceSync(text);
@@ -158,14 +161,16 @@ function signalGlyph(sig) {
/* vertical fade for area fills: the series colour (--vt-sc) at the
chart fill opacity at the top, transparent at the baseline (flip: an
area hanging down from its baseline). Returns the paint reference for
the fill attribute. */
area hanging down from its baseline). cls goes on the gradient, which
takes --vt-sc from where it sits, not from the area using it. Returns
the paint reference for the fill attribute. */
var gradSeq = 0;
function fadeFill(svg, flip) {
function fadeFill(svg, flip, cls) {
var id = 'vt-fade-' + (++gradSeq);
var defs = document.createElementNS(SVGNS, 'defs');
var lg = document.createElementNS(SVGNS, 'linearGradient');
lg.setAttribute('id', id);
if (cls) lg.setAttribute('class', cls);
lg.setAttribute('x1', '0'); lg.setAttribute('y1', flip ? '1' : '0');
lg.setAttribute('x2', '0'); lg.setAttribute('y2', flip ? '0' : '1');
[ [ '0', 'vt-fade-top' ], [ '1', 'vt-fade-end' ] ].forEach(function(st) {
@@ -179,6 +184,11 @@ function fadeFill(svg, flip) {
return 'url(#' + id + ')';
}
/* throughput direction: the same colour in every row, the legend, the
readouts and the tooltip ('dn' download, 'up' upload) */
function dirKey(dir) { return E('span', { 'class': 'vt-lg-key vt-k-' + dir }); }
function dirArrow(dir) { return E('span', { 'class': 'vt-arr vt-arr-' + dir }, [ dir === 'up' ? '↑' : '↓' ]); }
function pos(el, xPct, yPct) {
el.style.left = Math.max(0, Math.min(100, xPct)).toFixed(2) + '%';
el.style.top = Math.max(0, Math.min(100, yPct)).toFixed(2) + '%';
@@ -1493,7 +1503,13 @@ return view.extend({
return this.foldable('chart', E('section', { 'class': 'vt-tile vt-chart', 'aria-label': _('Throughput') }, [
E('header', { 'class': 'vt-tile-head' }, [
E('h3', { 'class': 'vt-tile-title' }, [ icon('pulse'), E('span', {}, [ _('Throughput') ]), el.chartSub ]),
E('div', { 'class': 'vt-tile-extra' }, [ this.foldButton('chart', _('Show or hide the throughput chart')) ])
E('div', { 'class': 'vt-tile-extra' }, [
E('span', { 'class': 'vt-legend vt-dir-legend' }, [
E('span', { 'class': 'vt-legend-item' }, [ dirKey('dn'), E('span', {}, [ _('Download') ]) ]),
E('span', { 'class': 'vt-legend-item' }, [ dirKey('up'), E('span', {}, [ _('Upload') ]) ])
]),
this.foldButton('chart', _('Show or hide the throughput chart'))
])
]),
plot,
el.chartLive
@@ -1502,15 +1518,16 @@ return view.extend({
/* one small multiple per link: the uplink, then each radio. Download
(towards the clients) rises above the middle line, upload hangs
below it; each half has its own y scale (upload is often a hundredth
of download, and a busy uplink would flatten an idle radio), labelled
with its unit, on a shared time axis and crosshair. Columns of a
below it, each in its direction's colour; each half has its own y
scale (upload is often a hundredth of download, and a busy uplink
would flatten an idle radio), labelled with its unit, on a shared
time axis and crosshair. Columns of a
history point [ t, rx, tx ]: the uplink receives what clients
download, a radio sends it. */
chartSeries: function() {
var m = this.m;
var list = [ { key: 'uplink', label: m.uplink ? _('Uplink %s').format(m.uplink.dev) : _('Uplink'), cls: 'vt-c-up', dn: 1, up: 2 } ];
m.radios.forEach(function(r) { list.push({ key: r.id, label: _('%s radio').format(r.bandLabel), cls: 'vt-c-' + (r.band || 'x'), dn: 2, up: 1 }); });
var list = [ { key: 'uplink', label: m.uplink ? _('Uplink %s').format(m.uplink.dev) : _('Uplink'), dn: 1, up: 2 } ];
m.radios.forEach(function(r) { list.push({ key: r.id, label: _('%s radio').format(r.bandLabel), dn: 2, up: 1 }); });
return list;
},
@@ -1548,7 +1565,7 @@ return view.extend({
});
[ [ segD, false, '' ], [ segU, true, ' vt-dir-up' ] ].forEach(function(h) {
var area = svgPath(series.areaPath(h[0], M), 'vt-series-area' + h[2]);
area.setAttribute('fill', fadeFill(svg, h[1]));
area.setAttribute('fill', fadeFill(svg, h[1], h[2].trim()));
svg.appendChild(area);
svg.appendChild(svgPath(series.linePath(h[0]), 'vt-series-line' + h[2]));
});
@@ -1560,19 +1577,21 @@ return view.extend({
}
var dotD = E('span', { 'class': 'vt-mult-dot', 'hidden': 'hidden' }), dotU = E('span', { 'class': 'vt-mult-dot vt-dir-up', 'hidden': 'hidden' });
rows.push({ s: s, d: d, vd: vd, vu: vu, dotD: dotD, dotU: dotU });
return E('div', { 'class': 'vt-mult ' + s.cls }, [
return E('div', { 'class': 'vt-mult' }, [
E('div', { 'class': 'vt-mult-head' }, [
E('span', { 'class': 'vt-mult-name' }, [ E('span', { 'class': 'vt-lg-key' }), E('span', {}, [ s.label ]) ]),
E('b', { 'class': 'vt-mult-now vt-tn', 'title': _('Download') }, [ '↓ ', fresh && sd.now != null ? fmt.bits(last[s.dn]) : fmt.DASH ]),
E('b', { 'class': 'vt-mult-now-up vt-tn', 'title': _('Upload') }, [ '↑ ', fresh && su.now != null ? fmt.bits(last[s.up]) : fmt.DASH ]),
E('span', { 'class': 'vt-mult-name' }, [ s.label ]),
E('span', { 'class': 'vt-mult-now', 'title': _('Download') }, [ dirKey('dn'),
E('b', { 'class': 'vt-tn' }, [ dirArrow('dn'), ' ', fresh && sd.now != null ? fmt.bits(last[s.dn]) : fmt.DASH ]) ]),
E('span', { 'class': 'vt-mult-now vt-mult-now-up', 'title': _('Upload') }, [ dirKey('up'),
E('b', { 'class': 'vt-tn' }, [ dirArrow('up'), ' ', fresh && su.now != null ? fmt.bits(last[s.up]) : fmt.DASH ]) ]),
E('span', { 'class': 'vt-mult-stats vt-tn' }, sd.n > 1 ? [
E('span', {}, [ _('peak'), ' ', E('b', {}, [ '↓ ' + fmt.bitsShort(sd.peak) ]), ' ', E('b', {}, [ '↑ ' + fmt.bitsShort(su.peak) ]) ])
E('span', {}, [ _('peak'), ' ', E('b', {}, [ dirArrow('dn'), ' ' + fmt.bitsShort(sd.peak) ]), ' ', E('b', {}, [ dirArrow('up'), ' ' + fmt.bitsShort(su.peak) ]) ])
] : [ E('span', {}, [ _('measuring…') ]) ])
]),
E('div', { 'class': 'vt-mult-plot' }, [
svg,
sd.n ? E('span', { 'class': 'vt-mult-max vt-tn' }, [ '↓ ' + bitsLabel(vd) ]) : '',
sd.n ? E('span', { 'class': 'vt-mult-max vt-mult-max-up vt-tn' }, [ '↑ ' + bitsLabel(vu) ]) : '',
sd.n ? E('span', { 'class': 'vt-mult-max vt-tn' }, [ dirArrow('dn'), ' ' + bitsLabel(vd) ]) : '',
sd.n ? E('span', { 'class': 'vt-mult-max vt-mult-max-up vt-tn' }, [ dirArrow('up'), ' ' + bitsLabel(vu) ]) : '',
sd.n < 2 ? E('span', { 'class': 'vt-sk-note' }, [ _('collecting…') ]) : '',
tailDot(segD, ''),
tailDot(segU, ' vt-dir-up'),
@@ -1623,6 +1642,7 @@ return view.extend({
this.ui.hover = at.t != null ? { t: tp } : at;
el.chartCursor.hidden = false;
el.chartCursor.style.left = x.toFixed(2) + '%';
var said = [];
var tipRows = meta.rows.map(function(r) {
var j = series.nearest(r.d, tp), p = (j >= 0 && Math.abs(r.d[j][0] - tp) < POLL_S * 1000) ? r.d[j] : null;
var vd = p ? p[r.s.dn] : null, vu = p ? p[r.s.up] : null;
@@ -1630,16 +1650,23 @@ return view.extend({
r.dotU.hidden = vu == null;
if (vd != null) pos(r.dotD, x, (1 - Math.min(1, vd / r.vd)) * 50);
if (vu != null) pos(r.dotU, x, 50 + Math.min(1, vu / r.vu) * 50);
return E('div', { 'class': 'vt-tip-row ' + r.s.cls }, [ E('span', { 'class': 'vt-lg-key' }),
E('b', { 'class': 'vt-tn' }, [ '↓ ' + (vd == null ? fmt.DASH : fmt.bits(vd)) ]),
E('b', { 'class': 'vt-tn vt-tip-up' }, [ '↑ ' + (vu == null ? fmt.DASH : fmt.bits(vu)) ]),
E('span', { 'class': 'vt-tip-label' }, [ r.s.label ]) ]);
var bd = vd == null ? fmt.DASH : fmt.bits(vd), bu = vu == null ? fmt.DASH : fmt.bits(vu);
said.push(r.s.label + ': ↓ ' + bd + ' ↑ ' + bu);
return E('div', { 'class': 'vt-tip-link' }, [
E('div', { 'class': 'vt-tip-label' }, [ r.s.label ]),
E('div', { 'class': 'vt-tip-row' }, [ dirKey('dn'), E('span', {}, [ _('Download') ]), E('b', { 'class': 'vt-tn' }, [ bd ]) ]),
E('div', { 'class': 'vt-tip-row' }, [ dirKey('up'), E('span', {}, [ _('Upload') ]), E('b', { 'class': 'vt-tn' }, [ bu ]) ])
]);
});
dom.content(el.chartTip, [ E('div', { 'class': 'vt-tip-time vt-tn' }, [ new Date(tp).toLocaleTimeString(), E('span', {}, [ fmt.ago(Date.now() - tp) ]) ]) ].concat(tipRows));
el.chartTip.hidden = false;
el.chartTip.style.left = x.toFixed(2) + '%';
el.chartTip.classList.toggle('vt-tip-left', x > 55);
if (at.t != null) txt(el.chartLive, [ new Date(tp).toLocaleTimeString() ].concat(tipRows.map(function(r) { return r.textContent; })).join('; '));
/* beside the crosshair, on the side it fits; on a narrow chart it
may cover the readouts on the left but never leaves the tile */
var ow = el.chartOver.clientWidth, tw = el.chartTip.offsetWidth, px = x / 100 * ow, gap = 12;
var lx = px + gap + tw <= ow ? px + gap : px - gap - tw;
lx = Math.max(-el.chartOver.offsetLeft, Math.min(ow - tw, lx));
el.chartTip.style.left = lx.toFixed(0) + 'px';
if (at.t != null) txt(el.chartLive, [ new Date(tp).toLocaleTimeString() ].concat(said).join('; '));
},
chartHide: function() {
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -10,8 +10,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-theme-vantage
PKG_VERSION:=1.0.2
PKG_RELEASE:=15
PKG_VERSION:=1.0.3
PKG_RELEASE:=16
PKG_LICENSE:=GPL-3.0-or-later
LUCI_TITLE:=Vantage theme
+1 -1
View File
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=mihomo
PKG_VERSION:=1.19.32
PKG_RELEASE:=34
PKG_RELEASE:=35
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/metacubex/mihomo/tar.gz/v$(PKG_VERSION)?
+7
View File
@@ -0,0 +1,7 @@
# 核心替换 / Core Replacement
> 此 mihomo 核心并不是唯一的. 您也可以使用 Nikki 或其他包的 mihomo 核心.\
> 只要它们的 `PROVIDES` 字段为 **mihomo**, 且 `/usr/bin/mihomo` 有可用于执行的二进制文件或链接
> This mihomo core is not the only option. you can also use the mihomo core from Nikki or other packages.\
> provided that their `PROVIDES` field is set to **mihomo** and there is an executable binary or link at `/usr/bin/mihomo`.
+2 -1
View File
@@ -9,7 +9,7 @@ PKG_NAME:=natmapt
PKG_UPSTREAM_VERSION:=20260214
PKG_UPSTREAM_GITHASH:=
PKG_VERSION:=$(PKG_UPSTREAM_VERSION)$(if $(PKG_UPSTREAM_GITHASH),~$(call version_abbrev,$(PKG_UPSTREAM_GITHASH)))
PKG_RELEASE:=12
PKG_RELEASE:=13
SCRIPTS_VERSION:=0.2026.01.24
PKG_SOURCE_SUBDIR:=$(PKG_UPSTREAM_NAME)-$(PKG_UPSTREAM_VERSION)
@@ -45,6 +45,7 @@ define Package/natmapt
TITLE:=TCP/UDP port mapping tool for full cone NAT
URL:=https://github.com/heiher/natmap
DEPENDS:=+curl +jsonfilter +bash
PROVIDES:=natmap
endef
MAKE_FLAGS += REV_ID="$(PKG_VERSION)"