mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-26 18:12:51 +08:00
⛅ Sync 2026-09-22 23:24:55
This commit is contained in:
1 parent
de9cc9a6a9
commit
d45e210b8a
16 files changed
+173
-71
No files matched your search
@@ -12,7 +12,7 @@ LUCI_DEPENDS:=+luci-base +logd +jsonfilter
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_VERSION:=0.1.45
|
||||
PKG_RELEASE:=31
|
||||
PKG_RELEASE:=32
|
||||
|
||||
# Reproducible build: honor SOURCE_DATE_EPOCH from the build environment (set by docker-sdk.sh / CI).
|
||||
ifdef SOURCE_DATE_EPOCH
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/* Copyright 2025-2026 Lucas Albers <lucas.b.albers@gmail.com> */
|
||||
'require baseclass'; /* LuCI require() needs Class.isSubclass — plain return {} fails */
|
||||
'require fwlive.log as log';
|
||||
'require fwlive.hostname as hostname';
|
||||
|
||||
/**
|
||||
* Link-builder helpers for luci-app-fwlive.
|
||||
@@ -14,7 +15,7 @@
|
||||
* filterLink, addrFilterLink, ruleAdminPath, ruleAdminLink, ifaceLink
|
||||
*
|
||||
* No host element — all functions return DOM nodes or strings.
|
||||
* May require fwlive.log for formatCell.
|
||||
* May require fwlive.log for formatCell and fwlive.hostname for cache reads.
|
||||
*/
|
||||
|
||||
function luciUrl(path) {
|
||||
@@ -75,7 +76,14 @@ function filterLink(field, value, label, onFilterClick) {
|
||||
function addrFilterLink(field, ip, showHostnames, hostnameCache, onFilterClick) {
|
||||
if (!ip) return log.formatCell(ip);
|
||||
|
||||
const name = showHostnames && hostnameCache ? hostnameCache.get(ip) : null;
|
||||
let name = null;
|
||||
if (showHostnames && hostnameCache) {
|
||||
/* Display reads refresh recency so visible names remain warm in the LRU. */
|
||||
name =
|
||||
hostname && typeof hostname.lruGet === 'function'
|
||||
? hostname.lruGet(hostnameCache, ip)
|
||||
: hostnameCache.get(ip);
|
||||
}
|
||||
const display = name || ip;
|
||||
const title = name ? ip : _('Filter by %s').format(field);
|
||||
|
||||
|
||||
@@ -87,6 +87,11 @@ function labelWithZoneCandidates(label, st) {
|
||||
return children;
|
||||
}
|
||||
|
||||
function appendLoggingNotice(host, state) {
|
||||
if (!state.loggingNotice) return;
|
||||
host.appendChild(E('span', { 'class': 'fwlive-logging-notice' }, [state.loggingNotice]));
|
||||
}
|
||||
|
||||
function renderToolbar(host, state, callbacks) {
|
||||
host.innerHTML = '';
|
||||
const st = state.loggingStatus;
|
||||
@@ -107,6 +112,7 @@ function renderToolbar(host, state, callbacks) {
|
||||
)
|
||||
);
|
||||
host.appendChild(links.firewallZonesLink());
|
||||
appendLoggingNotice(host, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -116,6 +122,7 @@ function renderToolbar(host, state, callbacks) {
|
||||
_('WAN logging unavailable: missing kernel log modules')
|
||||
])
|
||||
);
|
||||
appendLoggingNotice(host, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -144,6 +151,7 @@ function renderToolbar(host, state, callbacks) {
|
||||
children
|
||||
)
|
||||
);
|
||||
appendLoggingNotice(host, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,6 +170,7 @@ function renderToolbar(host, state, callbacks) {
|
||||
[state.loggingBusy ? _('Enabling…') : _('Enable logging')]
|
||||
)
|
||||
);
|
||||
appendLoggingNotice(host, state);
|
||||
}
|
||||
|
||||
function buildConsentPanel(state, callbacks) {
|
||||
|
||||
@@ -77,6 +77,14 @@ function createScheduler(options) {
|
||||
const elapsed = bucketMs === null ? 0 : Math.max(0, timestamp - bucketMs);
|
||||
bucketMs = timestamp;
|
||||
bucket = Math.min(capacity, bucket + (elapsed * capacity) / 1000);
|
||||
/* A single batch can cost more than one second's budget. Once the
|
||||
* bucket is full, spend that full interval on one paint so a sustained
|
||||
* flood cannot freeze the table until the user changes a control. */
|
||||
if (cost > bucket && bucket >= capacity) {
|
||||
bucket = 0;
|
||||
floodSuppressed = true;
|
||||
return true;
|
||||
}
|
||||
floodSuppressed = cost > bucket;
|
||||
if (floodSuppressed) return false;
|
||||
bucket -= cost;
|
||||
|
||||
@@ -683,10 +683,15 @@ return view.extend({
|
||||
const status = await callFwliveLoggingStatus();
|
||||
if (this.viewDisposed) return;
|
||||
this.loggingStatus = status;
|
||||
this.loggingNotice = '';
|
||||
this.weakDevice = !!(this.loggingStatus && this.loggingStatus.weak_device === true);
|
||||
} catch (_e) {
|
||||
if (this.viewDisposed) return;
|
||||
this.loggingStatus = null;
|
||||
/* Keep last toolbar state. Do not clobber a toggle success/failure notice. */
|
||||
if (!this.loggingNotice)
|
||||
this.loggingNotice = _(
|
||||
'Could not refresh logging status; showing the last known state.'
|
||||
);
|
||||
}
|
||||
this.updateBackendUi();
|
||||
this.updateLoggingToolbarUi();
|
||||
@@ -712,6 +717,10 @@ return view.extend({
|
||||
|
||||
this.loggingNotice = opts.successNotice(res);
|
||||
if (opts.onSuccess) opts.onSuccess(res);
|
||||
if (this.loggingStatus && typeof opts.wanLog === 'boolean')
|
||||
this.loggingStatus = Object.assign({}, this.loggingStatus, {
|
||||
wan_log: opts.wanLog
|
||||
});
|
||||
await this.loadLoggingStatus();
|
||||
} catch (_e) {
|
||||
this.loggingNotice = opts.catchNotice();
|
||||
@@ -725,6 +734,7 @@ return view.extend({
|
||||
|
||||
async handleEnableLogging() {
|
||||
return this.runLoggingToggle({
|
||||
wanLog: true,
|
||||
call: () => callFwliveEnableLogging(),
|
||||
initialUi: () => {
|
||||
this.updateEmptyStateUi();
|
||||
@@ -752,6 +762,7 @@ return view.extend({
|
||||
|
||||
async handleDisableLogging() {
|
||||
return this.runLoggingToggle({
|
||||
wanLog: false,
|
||||
call: () => callFwliveDisableLogging(),
|
||||
initialUi: () => this.updateLoggingToolbarUi(),
|
||||
failureNotice: (res) => {
|
||||
@@ -1333,7 +1344,14 @@ return view.extend({
|
||||
this.summaryRowsShown = false;
|
||||
this.summaryData = null;
|
||||
this.updateSummaryUi();
|
||||
this.renderRows(true);
|
||||
if (this.tablePaused) {
|
||||
const empty = document.getElementById('fwlive-empty');
|
||||
if (empty) {
|
||||
const rows = this.filteredRows();
|
||||
empty.style.display = rows.length ? 'none' : 'block';
|
||||
}
|
||||
this.updateStatus();
|
||||
} else this.renderRows(true);
|
||||
},
|
||||
|
||||
onSummaryRowsToggle() {
|
||||
@@ -1469,8 +1487,10 @@ return view.extend({
|
||||
this.resolveGeneration = (this.resolveGeneration || 0) + 1;
|
||||
this.resolveInFlight = false;
|
||||
|
||||
if (this.showHostnames) this.resolveHostnamesForEntries(this.filteredRows());
|
||||
/* Paint the existing cache immediately; resolving only fills misses. */
|
||||
if (this.tablePaused) this.updateStatus();
|
||||
else this.renderRows(true);
|
||||
if (this.showHostnames) this.resolveHostnamesForEntries(this.filteredRows());
|
||||
},
|
||||
|
||||
onFetchModeChange(ev) {
|
||||
@@ -1646,7 +1666,7 @@ return view.extend({
|
||||
|
||||
for (let i = 0; i < ips.length && need.length < 32; i++) {
|
||||
const ip = ips[i];
|
||||
if (this.hostnameCache.has(ip)) continue;
|
||||
if (hostname.lruGet(this.hostnameCache, ip) !== undefined) continue;
|
||||
if (hostname.failIsHot(this.hostnameFailed, ip, now)) continue;
|
||||
need.push(ip);
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ msgstr "Connection lost — retrying…"
|
||||
msgid "Could not disable logging."
|
||||
msgstr "Protokollierung konnte nicht deaktiviert werden."
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||
msgid "Could not refresh logging status; showing the last known state."
|
||||
msgstr "Could not refresh logging status; showing the last known state."
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||
msgid "Could not enable logging."
|
||||
msgstr "Protokollierung konnte nicht aktiviert werden."
|
||||
|
||||
@@ -129,6 +129,10 @@ msgstr "Connection lost — retrying…"
|
||||
msgid "Could not disable logging."
|
||||
msgstr "Ðе ÑдалоÑÑ Ð¾ÑклÑÑиÑÑ Ð¶ÑÑналиÑование."
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||
msgid "Could not refresh logging status; showing the last known state."
|
||||
msgstr "Could not refresh logging status; showing the last known state."
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||
msgid "Could not enable logging."
|
||||
msgstr "Ðе ÑдалоÑÑ Ð²ÐºÐ»ÑÑиÑÑ Ð¶ÑÑналиÑование."
|
||||
|
||||
@@ -100,6 +100,10 @@ msgstr ""
|
||||
msgid "Could not disable logging."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||
msgid "Could not refresh logging status; showing the last known state."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||
msgid "Could not enable logging."
|
||||
msgstr ""
|
||||
|
||||
@@ -115,6 +115,10 @@ msgstr "Connection lost — retrying…"
|
||||
msgid "Could not disable logging."
|
||||
msgstr "æ æ³"
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||
msgid "Could not refresh logging status; showing the last known state."
|
||||
msgstr "Could not refresh logging status; showing the last known state."
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||
msgid "Could not enable logging."
|
||||
msgstr "æ æ³å¼å¯æ¥å¿è®°å½ã"
|
||||
|
||||
@@ -276,7 +276,8 @@ fwlive_adaptive_bucket_for_ms() {
|
||||
|
||||
# Args: requested_limit duration_ms prev_limit prev_bucket prev_warm
|
||||
# prev_completed_cs planning
|
||||
# Prints next limit.
|
||||
# Prints next limit. A full-sized cold sample may retain one upward probe
|
||||
# above the number of lines served; planning then holds that retained probe.
|
||||
fwlive_adaptive_compute_limit() {
|
||||
_req=$1
|
||||
_ms=$2
|
||||
@@ -343,7 +344,21 @@ fwlive_adaptive_compute_limit() {
|
||||
fi
|
||||
|
||||
case "$_bucket" in
|
||||
cold) _limit=$_max ;;
|
||||
cold)
|
||||
_base=$_prev_l
|
||||
[ "$_base" -lt 1 ] && _base=$_max
|
||||
if [ "$_planning" = 1 ]; then
|
||||
# Keep a cold probe at the limit that was actually retained.
|
||||
_limit=$_base
|
||||
elif [ "$_req" -ge "$_base" ]; then
|
||||
# A full-sized cold sample earns one doubling, not a jump
|
||||
# from the 250-line floor straight to the maximum.
|
||||
_limit=$((_base * 2))
|
||||
else
|
||||
# A short cold sample does not prove the larger request is safe.
|
||||
_limit=$_base
|
||||
fi
|
||||
;;
|
||||
cool)
|
||||
# A healthy cooldown probe may retain its raised limit for the
|
||||
# short probe window. Ordinary cool samples still use the fixed
|
||||
@@ -370,7 +385,10 @@ fwlive_adaptive_compute_limit() {
|
||||
hot) _limit=$FWLIVE_ADAPTIVE_HOT_FLOOR ;;
|
||||
esac
|
||||
|
||||
if [ "$_planning" = 1 ] || [ "$_bucket" != cold ] || \
|
||||
[ "$_prev_l" -lt 1 ] || [ "$_req" -lt "$_prev_l" ]; then
|
||||
[ "$_limit" -gt "$_req" ] && _limit=$_req
|
||||
fi
|
||||
[ "$_limit" -gt "$_max" ] && _limit=$_max
|
||||
[ "$_limit" -lt 1 ] && _limit=1
|
||||
printf '%s\n' "$_limit"
|
||||
|
||||
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=26.9.16
|
||||
PKG_RELEASE:=286
|
||||
PKG_RELEASE:=287
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -197,16 +197,19 @@ function exec_call(cmd)
|
||||
end
|
||||
|
||||
function base64Decode(text)
|
||||
if not text then return '' end
|
||||
local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+")
|
||||
if type(text) ~= "string" then return "" end
|
||||
local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+"):gsub("=+$", "")
|
||||
if encoded == "" then return text end
|
||||
if not encoded:match("^[A-Za-z0-9+/]*$") then return text end
|
||||
local mod4 = #encoded % 4
|
||||
encoded = encoded .. string.sub('====', mod4 + 1)
|
||||
local result = nixio.bin.b64decode(encoded)
|
||||
if result then
|
||||
return result:gsub("%z", "")
|
||||
else
|
||||
return text
|
||||
end
|
||||
if mod4 == 1 then return text end
|
||||
local padded = encoded .. string.rep("=", (4 - mod4) % 4)
|
||||
local result = nixio.bin.b64decode(padded)
|
||||
if not result then return text end
|
||||
-- Verify that the normalized input is canonical Base64.
|
||||
local reencoded = nixio.bin.b64encode(result):gsub("=+$", "")
|
||||
if reencoded ~= encoded then return text end
|
||||
return (result:gsub("%z", ""))
|
||||
end
|
||||
|
||||
function base64Encode(text)
|
||||
|
||||
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-xray
|
||||
PKG_VERSION:=3.7.2
|
||||
PKG_RELEASE:=9
|
||||
PKG_RELEASE:=10
|
||||
|
||||
PKG_LICENSE:=MPLv2
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -2,52 +2,70 @@
|
||||
|
||||
import { server_outbound } from "./outbound.mjs";
|
||||
|
||||
function manual_tproxy_redirect(v) {
|
||||
return sprintf("%s:%d", v["dest_addr"] || "", v["dest_port"] || 0);
|
||||
}
|
||||
|
||||
function manual_tproxy_outbound_tag(v, name) {
|
||||
return `manual_tproxy:${v[".name"]}@${name}`;
|
||||
}
|
||||
|
||||
function manual_tproxy_force_forward_tag(v, name, force_forward_key, server_key) {
|
||||
if (v[force_forward_key] !== "1" || v[server_key] == null) {
|
||||
return null;
|
||||
}
|
||||
return `manual_tproxy:${v[".name"]}@${name}@force_forward:${v[server_key]}`;
|
||||
}
|
||||
|
||||
function manual_tproxy_needs_dialer_proxy(v, force_forward_key, server_key) {
|
||||
if (v[force_forward_key] !== "1") {
|
||||
return true;
|
||||
}
|
||||
if (v[server_key] == null) {
|
||||
return true;
|
||||
}
|
||||
if (manual_tproxy_redirect(v) !== ":0") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function manual_tproxy_outbound(config, v, name, force_forward_key, server_key) {
|
||||
const force_forward_tag = manual_tproxy_force_forward_tag(v, name, force_forward_key, server_key);
|
||||
let result = [];
|
||||
if (force_forward_tag != null) {
|
||||
push(result, ...server_outbound(config[v[server_key]], force_forward_tag, config));
|
||||
}
|
||||
if (manual_tproxy_needs_dialer_proxy(v, force_forward_key, server_key)) {
|
||||
push(result, {
|
||||
protocol: "freedom",
|
||||
tag: manual_tproxy_outbound_tag(v, name),
|
||||
settings: {
|
||||
redirect: manual_tproxy_redirect(v),
|
||||
domainStrategy: "AsIs"
|
||||
},
|
||||
streamSettings: {
|
||||
sockOpt: {
|
||||
dialerProxy: force_forward_tag != null ? force_forward_tag : "direct"
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function manual_tproxy_rule_tag(v, name, force_forward_key, server_key) {
|
||||
if (manual_tproxy_needs_dialer_proxy(v, force_forward_key, server_key)) {
|
||||
return manual_tproxy_outbound_tag(v, name);
|
||||
}
|
||||
return manual_tproxy_force_forward_tag(v, name, force_forward_key, server_key);
|
||||
}
|
||||
|
||||
export function manual_tproxy_outbounds(config, manual_tproxy) {
|
||||
let result = [];
|
||||
for (let v in manual_tproxy) {
|
||||
let tcp_tag = "direct";
|
||||
if (v["force_forward_tcp"] === "1") {
|
||||
if (v["force_forward_server_tcp"] != null) {
|
||||
tcp_tag = `manual_tproxy:${v[".name"]}@tcp_outbound@force_forward:${v["force_forward_server_tcp"]}`;
|
||||
const force_forward_server_tcp = config[v["force_forward_server_tcp"]];
|
||||
push(result, ...server_outbound(force_forward_server_tcp, tcp_tag, config));
|
||||
}
|
||||
}
|
||||
push(result, {
|
||||
protocol: "freedom",
|
||||
tag: sprintf("manual_tproxy:%s@tcp_outbound", v[".name"]),
|
||||
settings: {
|
||||
redirect: sprintf("%s:%d", v["dest_addr"] || "", v["dest_port"] || 0),
|
||||
domainStrategy: "AsIs"
|
||||
},
|
||||
streamSettings: {
|
||||
sockOpt: {
|
||||
dialerProxy: tcp_tag
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let udp_tag = "direct";
|
||||
if (v["force_forward_udp"] === "1") {
|
||||
if (v["force_forward_server_udp"] != null) {
|
||||
udp_tag = `manual_tproxy:${v[".name"]}@udp_outbound@force_forward:${v["force_forward_server_udp"]}`;
|
||||
const force_forward_server_udp = config[v["force_forward_server_udp"]];
|
||||
push(result, ...server_outbound(force_forward_server_udp, udp_tag, config));
|
||||
}
|
||||
}
|
||||
push(result, {
|
||||
protocol: "freedom",
|
||||
tag: sprintf("manual_tproxy:%s@udp_outbound", v[".name"]),
|
||||
settings: {
|
||||
redirect: sprintf("%s:%d", v["dest_addr"] || "", v["dest_port"] || 0),
|
||||
domainStrategy: "AsIs"
|
||||
},
|
||||
streamSettings: {
|
||||
sockOpt: {
|
||||
dialerProxy: udp_tag
|
||||
}
|
||||
}
|
||||
});
|
||||
push(result, ...manual_tproxy_outbound(config, v, "tcp_outbound", "force_forward_tcp", "force_forward_server_tcp"));
|
||||
push(result, ...manual_tproxy_outbound(config, v, "udp_outbound", "force_forward_udp", "force_forward_server_udp"));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
@@ -55,11 +73,13 @@ export function manual_tproxy_outbounds(config, manual_tproxy) {
|
||||
export function manual_tproxy_outbound_tags(manual_tproxy) {
|
||||
let result = [];
|
||||
for (let v in manual_tproxy) {
|
||||
if (v["force_forward_tcp"] === "1") {
|
||||
push(result, `manual_tproxy:${v[".name"]}@tcp_outbound@force_forward:${v["force_forward_server_tcp"]}`);
|
||||
const tcp_tag = manual_tproxy_force_forward_tag(v, "tcp_outbound", "force_forward_tcp", "force_forward_server_tcp");
|
||||
if (tcp_tag != null) {
|
||||
push(result, tcp_tag);
|
||||
}
|
||||
if (v["force_forward_udp"] === "1") {
|
||||
push(result, `manual_tproxy:${v[".name"]}@udp_outbound@force_forward:${v["force_forward_server_udp"]}`);
|
||||
const udp_tag = manual_tproxy_force_forward_tag(v, "udp_outbound", "force_forward_udp", "force_forward_server_udp");
|
||||
if (udp_tag != null) {
|
||||
push(result, udp_tag);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -73,14 +93,14 @@ export function manual_tproxy_rules(manual_tproxy) {
|
||||
inboundTag: ["tproxy_tcp_inbound_v4", "tproxy_tcp_inbound_v6", "socks_inbound", "https_inbound", "http_inbound"],
|
||||
ip: [v["source_addr"]],
|
||||
port: v["source_port"],
|
||||
outboundTag: sprintf("manual_tproxy:%s@tcp_outbound", v[".name"])
|
||||
outboundTag: manual_tproxy_rule_tag(v, "tcp_outbound", "force_forward_tcp", "force_forward_server_tcp")
|
||||
});
|
||||
splice(result, 0, 0, {
|
||||
type: "field",
|
||||
inboundTag: ["tproxy_udp_inbound_v4", "tproxy_udp_inbound_v6"],
|
||||
ip: [v["source_addr"]],
|
||||
port: v["source_port"],
|
||||
outboundTag: sprintf("manual_tproxy:%s@udp_outbound", v[".name"])
|
||||
outboundTag: manual_tproxy_rule_tag(v, "udp_outbound", "force_forward_udp", "force_forward_server_udp")
|
||||
});
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
LUCI_TITLE:=Argon Theme
|
||||
LUCI_DEPENDS:=+USE_APK:wget-any +!USE_APK:wget +jsonfilter
|
||||
PKG_VERSION:=2.4.7
|
||||
PKG_RELEASE:=15
|
||||
PKG_RELEASE:=16
|
||||
|
||||
CONFIG_LUCI_CSSTIDY:=
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
body{background:#1e1e1e;color:#ccc}.spinning::before{filter:invert(1)}.login-page .login-container{background-color:rgba(0,0,0,var(--blur-opacity-dark));-webkit-backdrop-filter:blur(var(--blur-radius-dark));backdrop-filter:blur(var(--blur-radius-dark))}.login-page .login-container .login-form{background-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.login-page .login-container .login-form .brand{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group::before{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group input{background-color:transparent!important;color:#adb5bd;border-bottom:#adb5bd 1px solid!important;border-radius:0!important;border-top:none!important;border-left:none!important;border-right:none!important;box-shadow:none}.login-page .login-container .login-form .form-login .cbi-button-apply{background-color:#483d8b!important;background-color:var(--dark-primary)!important}.login-page .login-container .login-form .form-login .cbi-button-apply:focus,.login-page .login-container .login-form .form-login .cbi-button-apply:hover{opacity:.9}header::after{background-color:#1e1e1e!important}.main .main-left{background-color:#333!important;box-shadow:0 0 .5rem 0 rgba(0,0,0,.15)}.main .main-left .sidenav-header .brand{color:#ccc}.main .main-left .nav .slide .slide-menu .active a{color:#ccc}.main .main-left .nav .slide .slide-menu .active a::after{background-color:#ccc!important}.main .main-left .nav .slide .slide-menu .active::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .slide-menu li a{color:#ccc}.main .main-left .nav .slide .slide-menu li a:hover{background:0 0!important}.main .main-left .nav .slide .slide-menu li::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .menu.active{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left .nav .slide .menu.active a::after{background-color:#fff!important}.main .main-left .nav li a{color:#ccc!important}.main .main-left .nav li a:hover{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left::-webkit-scrollbar-thumb{background-color:#252526!important}.main .main-left::-webkit-scrollbar-track{background-color:#333}.main .main-right{background-color:#1e1e1e}h2{color:#ccc;background:#333}h3{color:#ccc;border-bottom:0;background:#333}h4{color:#8c6900}abbr{color:var(--dark-primary)!important}a:active,a:link,a:visited{color:#a5b2ff}input:-webkit-autofill{background-color:#3c3c3c!important}#channel_graph{background-color:transparent!important}.cbi-button-apply,.cbi-button-edit,.cbi-value-field .cbi-input-apply{color:#fff!important;background-color:#483d8b!important;background-color:var(--dark-primary)!important;border-color:#483d8b!important;border-color:var(--dark-primary)!important}.cbi-section em{color:#ccc}header.bg-primary{background-color:#1e1e1e!important}.cbi-map-descr{color:#ccc}.cbi-section{background:0 0;box-shadow:0 0 .5rem 0 rgba(0,0,0,.35)}.panel-title{color:#ccc;background-color:#333}div>.table>.tr:nth-of-type(2n),div>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{color:#ccc}fieldset>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{border-top:1px solid #252526}#conns>div>div,#membuff>div>div,#memfree>div>div,#memtotal>div>div,#swapfree>div>div,#swaptotal>div>div{background-color:var(--dark-primary)!important}#conns>div>div>div>small,#membuff>div>div>div>small,#memfree>div>div>div>small,#memtotal>div>div>div>small,#swapfree>div>div>div>small,#swaptotal>div>div>div>small{color:#ccc!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last{line-height:1.8em}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"]{border:1px solid #999!important;background-color:transparent!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"] div{background-color:#ba8b00!important}table>tbody>tr>th,table>tfoot>tr>th,table>thead>tr>th{background-color:#252526;border-bottom:#000 1px solid!important}.tr.cbi-section-table-titles.named::before,.tr[data-title]::before{background-color:#252526}#cbi-wireless>#wifi_assoclist_table>.tr:nth-child(2),.cbi-section-table-row::before,.tr>.td,.tr>.th,tr>td,tr>th{border-top:0}.cbi-rowstyle-2{background-color:#1e1e1e}.cbi-rowstyle-1{background-color:#252526}.cbi-rowstyle-2 .cbi-button-down,.cbi-rowstyle-2 .cbi-button-up,body:not(.Interfaces) .cbi-rowstyle-2:first-child{background-color:#666!important}.cbi-section>h3:first-child,.panel-title,h3{color:#ccc}h4{background-color:#1e1e1f}.cLine truncated
|
||||
body{background:#1e1e1e;color:#ccc}.spinning::before{filter:invert(1)}.login-page .login-container{background-color:rgba(0,0,0,var(--blur-opacity-dark));-webkit-backdrop-filter:blur(var(--blur-radius-dark));backdrop-filter:blur(var(--blur-radius-dark))}.login-page .login-container .login-form{background-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.login-page .login-container .login-form .brand{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group::before{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group input{background-color:transparent!important;color:#adb5bd;border-bottom:#adb5bd 1px solid!important;border-radius:0!important;border-top:none!important;border-left:none!important;border-right:none!important;box-shadow:none}.login-page .login-container .login-form .form-login .cbi-button-apply{background-color:#483d8b!important;background-color:var(--dark-primary)!important}.login-page .login-container .login-form .form-login .cbi-button-apply:focus,.login-page .login-container .login-form .form-login .cbi-button-apply:hover{opacity:.9}header::after{background-color:#1e1e1e!important}.main .main-left{background-color:#333!important;box-shadow:0 0 .5rem 0 rgba(0,0,0,.15)}.main .main-left .sidenav-header .brand{color:#ccc}.main .main-left .nav .slide .slide-menu .active a{color:#ccc}.main .main-left .nav .slide .slide-menu .active a::after{background-color:#ccc!important}.main .main-left .nav .slide .slide-menu .active::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .slide-menu li a{color:#ccc}.main .main-left .nav .slide .slide-menu li a:hover{background:0 0!important}.main .main-left .nav .slide .slide-menu li::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .menu.active{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left .nav .slide .menu.active a::after{background-color:#fff!important}.main .main-left .nav li a{color:#ccc!important}.main .main-left .nav li a:hover{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left::-webkit-scrollbar-thumb{background-color:#252526!important}.main .main-left::-webkit-scrollbar-track{background-color:#333}.main .main-right{background-color:#1e1e1e}h2{color:#ccc;background:#333}h3{color:#ccc;border-bottom:0;background:#333}h4{color:#8c6900}abbr{color:var(--dark-primary)!important}a:active,a:link,a:visited{color:#a5b2ff}input:-webkit-autofill{background-color:#3c3c3c!important}#channel_graph{background-color:transparent!important}.cbi-button-apply,.cbi-button-edit,.cbi-value-field .cbi-input-apply{color:#fff!important;background-color:#483d8b!important;background-color:var(--dark-primary)!important;border-color:#483d8b!important;border-color:var(--dark-primary)!important}.cbi-section em{color:#ccc}header.bg-primary{background-color:#1e1e1e!important}.cbi-map-descr{color:#ccc}.cbi-section{background:0 0;box-shadow:0 0 .5rem 0 rgba(0,0,0,.35)}.panel-title{color:#ccc;background-color:#333}div>.table>.tr:nth-of-type(2n),div>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{color:#ccc}fieldset>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{border-top:1px solid #252526}#conns>div>div,#membuff>div>div,#memfree>div>div,#memtotal>div>div,#swapfree>div>div,#swaptotal>div>div{background-color:var(--dark-primary)!important}#conns>div>div>div>small,#membuff>div>div>div>small,#memfree>div>div>div>small,#memtotal>div>div>div>small,#swapfree>div>div>div>small,#swaptotal>div>div>div>small{color:#ccc!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last{line-height:1.8em}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"]{border:1px solid #999!important;background-color:transparent!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"] div{background-color:#ba8b00!important}table>tbody>tr>th,table>tfoot>tr>th,table>thead>tr>th{background-color:#252526;border-bottom:#000 1px solid!important}.tr.cbi-section-table-titles.named::before,.tr[data-title]::before{background-color:#252526}#cbi-wireless>#wifi_assoclist_table>.tr:nth-child(2),.cbi-section-table-row::before,.tr>.td,.tr>.th,tr>td,tr>th{border-top:0}.cbi-rowstyle-2{background-color:#1e1e1e}.cbi-rowstyle-1{background-color:#252526}.cbi-rowstyle-2 .cbi-button-down,.cbi-rowstyle-2 .cbi-button-up,body:not(.Interfaces) .cbi-rowstyle-2:first-child{background-color:#666!important}.cbi-section>h3:first-child,.panel-title,h3{color:#ccc}h4{background-color:#1e1e1f}.cLine truncated
|
||||
Reference in new issue
Block a user