mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-02 11:03:56 +08:00
🛸 Sync 2026-10-18 10:48:36
This commit is contained in:
1 parent
61e7ec8357
commit
2a4fb97efd
21 files changed
+1217
-823
No files matched your search
@@ -11,8 +11,8 @@ LUCI_DESCRIPTION:=Live firewall log table (firewall4/nft; iptables-tagged lines
|
||||
LUCI_DEPENDS:=+luci-base +logd +jsonfilter
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_VERSION:=0.1.53
|
||||
PKG_RELEASE:=69
|
||||
PKG_VERSION:=0.1.54
|
||||
PKG_RELEASE:=70
|
||||
|
||||
# Reproducible build: honor SOURCE_DATE_EPOCH from the build environment (set by docker-sdk.sh / CI).
|
||||
ifdef SOURCE_DATE_EPOCH
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
return baseclass.extend({
|
||||
/* Keep in sync with openwrt-feed/luci-app-fwlive/Makefile PKG_VERSION. */
|
||||
APP_VERSION: '0.1.53',
|
||||
APP_VERSION: '0.1.54',
|
||||
ROW_LIMIT_OPTIONS: [25, 50, 100, 250, 500, 1000, 2000],
|
||||
DEFAULT_ROW_LIMIT: 100,
|
||||
FETCH_MODE_OPTIONS: ['auto', 'manual'],
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
* GENERATED — do not edit. Edit fwlive.css and run: node scripts/embed-fwlive-css.js
|
||||
*/
|
||||
return baseclass.extend({
|
||||
styleText: "\n/* SPDX-License-Identifier: Apache-2.0 */\n.fwlive-map {\n\tmax-width: none;\n\twidth: 100%;\n\t--fwlive-pass-color: var(--success-color-high, var(--success-color, #46a546));\n\t--fwlive-deny-color: var(--error-color-high, var(--error-color, #ca3c3c));\n\t--fwlive-bg-medium: var(--background-color-medium, var(--white-color-low, #f9f9f9));\n\t--fwlive-paused-color: #b45309;\n}\n/* Wide page in Detail only — Simple keeps LuCI’s 940px column. */\n#maincontent.container:has(.fwlive-map[data-view=\"detailed\"]) {\n\tmax-width: none;\n\tpadding-left: 16px;\n\tpadding-right: 16px;\n}\n.fwlive-map[data-row-tint=\"accessible\"] {\n\t--fwlive-pass-color: #0d9488;\n\t--fwlive-deny-color: #c2410c;\n}\n.fwlive-map.fwlive-watch-paused .fwlive-title-row,\n.fwlive-map.fwlive-watch-paused .fwlive-watch-strip {\n\tbackground: rgba(180, 83, 9, 0.08);\n\tbackground: color-mix(in srgb, var(--fwlive-paused-color) 8%, transparent);\n}\n.fwlive-map.fwlive-watch-paused .fwlive-title-row {\n\tmargin: 0 -8px;\n\tpadding: 6px 8px 0;\n\tborder-radius: 3px 3px 0 0;\n}\n.fwlive-map.fwlive-watch-paused .fwlive-watch-strip {\n\tmargin: 0 -8px 10px;\n\tpadding: 8px;\n\tborder-radius: 0 0 3px 3px;\n\tborder-bottom-color: transparent;\n}\n.fwlive-title-row {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: baseline;\n\tjustify-content: space-between;\n\tgap: 8px 16px;\n\tmargin: 0 0 4px;\n}\n.fwlive-title-row h2 {\n\tmargin: 0;\n\tflex: 0 1 auto;\n}\n.fwlive-title-status {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n\tflex-wrap: wrap;\n\tmin-width: 0;\n\tmargin-left: auto;\n}\n.fwlive-watch-strip {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: stretch;\n\tjustify-content: flex-start;\n\tgap: 0;\n\tmin-height: 40px;\n\tpadding: 8px 0 10px;\n\tborder-bottom: 1px solid var(--border-color-medium);\n\tmargin-bottom: 10px;\n}\n.fwlive-watch-group {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tmin-height: 28px;\n\tpadding: 0 10px;\n\tborder-left: 1px solid var(--border-color-medium);\n\tflex-wrap: wrap;\n}\n.fwlive-watch-group:last-child {\n\tpadding-right: 0;\n}\n.fwlive-watch-group-label {\n\tmargin-right: 2px;\n\tcolor: var(--text-color-medium);\n\tfont-size: 0.72em;\n\tfont-weight: 700;\n\tletter-spacing: 0.08em;\n\ttext-transform: uppercase;\n\twhite-space: nowrap;\n}\n.fwlive-watch-seg {\n\tdisplay: inline-flex;\n\talign-items: stretch;\n\tborder: 1px solid var(--border-color-medium);\n\tborder-radius: 3px;\n\toverflow: hidden;\n}\n.fwlive-watch-seg .fwlive-seg-btn {\n\tmargin: 0;\n\tborder: 0;\n\tborder-radius: 0;\n\tborder-right: 1px solid var(--border-color-medium);\n\tbackground: transparent;\n\tpadding: 4px 10px;\n\tfont-size: 0.88em;\n\tline-height: 1.25;\n\tmin-height: 28px;\n}\n.fwlive-watch-seg .fwlive-seg-btn:last-child {\n\tborder-right: 0;\n}\n.fwlive-watch-seg .fwlive-seg-btn[aria-pressed=\"true\"] {\n\tbackground: rgba(26, 111, 156, 0.12);\n\tbackground: color-mix(in srgb, var(--primary-color-high) 12%, transparent);\n\tcolor: var(--primary-color-high);\n\tfont-weight: 600;\n}\n.fwlive-watch-label { font-weight: 600; }\n.fwlive-watch-paused .fwlive-watch-label { color: var(--fwlive-paused-color); }\n.fwlive-map.fwlive-watch-paused .fwlive-title-status .fwlive-watch-label { color: var(--fwlive-paused-color); }\n.fwlive-dot {\n\twidth: 8px;\n\theight: 8px;\n\tborder-radius: 50%;\n\tbackground: var(--text-color-low, var(--border-color-high));\n\tdisplay: inline-block;\n\tflex-shrink: 0;\n}\n.fwlive-dot.fwlive-dot-on {\n\tbackground: var(--fwlive-pass-color);\n\tbox-shadow: 0 0 0 3px color-mix(in srgb, var(--fwlive-pass-color) 22%, transparent);\n}\n.fwlive-btn-ghost {\n\tbackground: transparent;\n\tborder-color: var(--border-color-medium);\n}\n.fwlive-btn-quiet {\n\tbackground: transparent;\n\tborder-color: var(--border-color-medium);\n\tcolor: var(--text-color-medium);\n\tfont-weight: 500;\n}\n.fwlive-log-merged {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 10px;\n\tborder: 1px solid var(--border-color-medium);\n\tborder-radius: 3px;\n\tbackground: var(--background-color-medium, var(--white-color-low, var(--background-color-high)));\n\tcolor: var(--text-color-high);\n\tfont-weight: 500;\n\tfont-size: 0.88em;\n\tline-height: 1.25;\n\tmin-height: 28px;\n\tcursor: pointer;\n}\n.fwlive-log-merged:hover {\n\tbackground: var(--background-color-low, var(--background-color-medium));\n}\n.fwlive-log-merged:disabled {\n\topacity: 0.65;\n\tcursor: default;\n}\n.fwlive-log-on-dot {\n\twidth: 6px;\n\theight: 6px;\n\tborder-radius: 50%;\n\tbackground: var(--fwlive-pass-color);\n\tflex-shrink: 0;\n}\n.fwlive-log-rate {\n\tcolor: var(--text-color-medium);\n\tfont-weight: 400;\n}\n.fwlive-display-bar {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px 14px;\n\tmargin: 0 0 12px;\n\tpadding: 8px 12px;\n\tborder: 1px solid var(--border-color-medium);\n\tborder-radius: 3px;\n\tbackground: var(--background-color-high);\n}\n.fwlive-dLine truncated
|
||||
styleText: "\n/* SPDX-License-Identifier: Apache-2.0 */\n.fwlive-map {\n\tmax-width: none;\n\twidth: 100%;\n\t--fwlive-pass-color: var(--success-color-high, var(--success-color, #46a546));\n\t--fwlive-deny-color: var(--error-color-high, var(--error-color, #ca3c3c));\n\t--fwlive-bg-medium: var(--background-color-medium, var(--white-color-low, #f9f9f9));\n\t--fwlive-paused-color: #b45309;\n}\n/* Wide page in Detail only — Simple keeps LuCI’s 940px column. */\n#maincontent.container:has(.fwlive-map[data-view=\"detailed\"]) {\n\tmax-width: none;\n\tpadding-left: 16px;\n\tpadding-right: 16px;\n}\n.fwlive-map[data-row-tint=\"accessible\"] {\n\t--fwlive-pass-color: #0d9488;\n\t--fwlive-deny-color: #c2410c;\n}\n.fwlive-map.fwlive-watch-paused .fwlive-title-row,\n.fwlive-map.fwlive-watch-paused .fwlive-watch-strip {\n\tbackground: rgba(180, 83, 9, 0.08);\n\tbackground: color-mix(in srgb, var(--fwlive-paused-color) 8%, transparent);\n}\n.fwlive-map.fwlive-watch-paused .fwlive-title-row {\n\tmargin: 0 -8px;\n\tpadding: 6px 8px 0;\n\tborder-radius: 3px 3px 0 0;\n}\n.fwlive-map.fwlive-watch-paused .fwlive-watch-strip {\n\tmargin: 0 -8px 10px;\n\tpadding: 8px;\n\tborder-radius: 0 0 3px 3px;\n\tborder-bottom-color: transparent;\n}\n.fwlive-title-row {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: baseline;\n\tjustify-content: space-between;\n\tgap: 8px 16px;\n\tmargin: 0 0 4px;\n}\n.fwlive-title-row h2 {\n\tmargin: 0;\n\tflex: 0 1 auto;\n}\n.fwlive-title-status {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n\tflex-wrap: wrap;\n\tmin-width: 0;\n\tmargin-left: auto;\n}\n.fwlive-watch-strip {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: stretch;\n\tjustify-content: flex-start;\n\tgap: 0;\n\tmin-height: 40px;\n\tpadding: 8px 0 10px;\n\tborder-bottom: 1px solid var(--border-color-medium);\n\tmargin-bottom: 10px;\n}\n.fwlive-watch-group {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tmin-height: 28px;\n\tpadding: 0 10px;\n\tborder-left: 1px solid var(--border-color-medium);\n\tflex-wrap: wrap;\n}\n.fwlive-watch-group:last-child {\n\tpadding-right: 0;\n}\n.fwlive-watch-group-label {\n\tmargin-right: 2px;\n\tcolor: var(--text-color-medium);\n\tfont-size: 0.72em;\n\tfont-weight: 700;\n\tletter-spacing: 0.08em;\n\ttext-transform: uppercase;\n\twhite-space: nowrap;\n}\n.fwlive-watch-seg {\n\tdisplay: inline-flex;\n\talign-items: stretch;\n\tborder: 1px solid var(--border-color-medium);\n\tborder-radius: 3px;\n\toverflow: hidden;\n}\n.fwlive-watch-seg .fwlive-seg-btn {\n\tmargin: 0;\n\tborder: 0;\n\tborder-radius: 0;\n\tborder-right: 1px solid var(--border-color-medium);\n\tbackground: transparent;\n\tpadding: 4px 10px;\n\tfont-size: 0.88em;\n\tline-height: 1.25;\n\tmin-height: 28px;\n}\n.fwlive-watch-seg .fwlive-seg-btn:last-child {\n\tborder-right: 0;\n}\n.fwlive-watch-seg .fwlive-seg-btn[aria-pressed=\"true\"] {\n\tbackground: rgba(26, 111, 156, 0.12);\n\tbackground: color-mix(in srgb, var(--primary-color-high) 12%, transparent);\n\tcolor: var(--primary-color-high);\n\tfont-weight: 600;\n}\n.fwlive-watch-label { font-weight: 600; }\n.fwlive-watch-paused .fwlive-watch-label { color: var(--fwlive-paused-color); }\n.fwlive-map.fwlive-watch-paused .fwlive-title-status .fwlive-watch-label { color: var(--fwlive-paused-color); }\n.fwlive-dot {\n\twidth: 8px;\n\theight: 8px;\n\tborder-radius: 50%;\n\tbackground: var(--text-color-low, var(--border-color-high));\n\tdisplay: inline-block;\n\tflex-shrink: 0;\n}\n.fwlive-dot.fwlive-dot-on {\n\tbackground: var(--fwlive-pass-color);\n\tbox-shadow: 0 0 0 3px color-mix(in srgb, var(--fwlive-pass-color) 22%, transparent);\n}\n.fwlive-btn-ghost {\n\tbackground: transparent;\n\tborder-color: var(--border-color-medium);\n}\n.fwlive-btn-quiet {\n\tbackground: transparent;\n\tborder-color: var(--border-color-medium);\n\tcolor: var(--text-color-medium);\n\tfont-weight: 500;\n}\n.fwlive-log-merged {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 10px;\n\tborder: 1px solid var(--border-color-medium);\n\tborder-radius: 3px;\n\tbackground: var(--background-color-medium, var(--white-color-low, var(--background-color-high)));\n\tcolor: var(--text-color-high);\n\tfont-weight: 500;\n\tfont-size: 0.88em;\n\tline-height: 1.25;\n\tmin-height: 28px;\n\tcursor: pointer;\n}\n.fwlive-log-merged:hover {\n\tbackground: var(--background-color-low, var(--background-color-medium));\n}\n.fwlive-log-merged:disabled {\n\topacity: 0.65;\n\tcursor: default;\n}\n.fwlive-log-on-dot {\n\twidth: 6px;\n\theight: 6px;\n\tborder-radius: 50%;\n\tbackground: var(--fwlive-pass-color);\n\tflex-shrink: 0;\n}\n.fwlive-log-rate {\n\tcolor: var(--text-color-medium);\n\tfont-weight: 400;\n}\n.fwlive-display-bar {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px 14px;\n\tmargin: 0 0 12px;\n\tpadding: 8px 12px;\n\tborder: 1px solid var(--border-color-medium);\n\tborder-radius: 3px;\n\tbackground: var(--background-color-high);\n}\n.fwlive-dLine truncated
|
||||
});
|
||||
@@ -714,6 +714,8 @@
|
||||
background: color-mix(in srgb, var(--warn-color-high) 10%, transparent);
|
||||
}
|
||||
.fwlive-map[data-view="simple"] #fwlive-msg-group { display: none; }
|
||||
.fwlive-map[data-view="simple"] label[for="fwlive-fetch-mode"],
|
||||
.fwlive-map[data-view="simple"] label[for="fwlive-manual-lines"] { display: none; }
|
||||
@media (max-width: 850px) {
|
||||
.fwlive-title-status {
|
||||
flex-basis: 100%;
|
||||
|
||||
@@ -231,8 +231,37 @@ return baseclass.extend({
|
||||
return String(message).replace(this.KV_SPAN, '');
|
||||
},
|
||||
|
||||
isClassifyActionWord: function (token) {
|
||||
const prefix = (token || '').toUpperCase();
|
||||
const words = this.CLASSIFY_SPEC.actionWords;
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
if (words[i] === prefix) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
messageForDetectAction: function (message) {
|
||||
let msg = this.normalizeNetfilterMessage(message || '').trim();
|
||||
msg = msg.replace(/^\[\s*[\d.]+\]\s*/, '');
|
||||
|
||||
if (/^fw4:\s*/i.test(msg)) msg = msg.replace(/^fw4:\s*/i, '');
|
||||
|
||||
const beforeKv = msg.match(/^([A-Za-z0-9_.-]+)(?::|\s+)(?=IN=|OUT=|SRC=|DST=|PROTO=)/);
|
||||
if (beforeKv && !this.isClassifyActionWord(beforeKv[1]))
|
||||
return msg.slice(beforeKv[0].length);
|
||||
|
||||
const colon = msg.match(/^([A-Za-z0-9_.-]+):/);
|
||||
if (colon) {
|
||||
const tag = colon[1].toLowerCase();
|
||||
if (tag !== 'kernel' && tag !== 'iptables' && !this.isClassifyActionWord(colon[1]))
|
||||
return msg.slice(colon[0].length).replace(/^\s*/, '');
|
||||
}
|
||||
|
||||
return msg;
|
||||
},
|
||||
|
||||
detectAction: function (message) {
|
||||
const m = this.stripKvSpans(message).match(this.ACTION_RE);
|
||||
const m = this.stripKvSpans(this.messageForDetectAction(message)).match(this.ACTION_RE);
|
||||
return m ? m[2].toUpperCase() : 'UNKNOWN';
|
||||
},
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
/* Own queued render intent and the token bucket; the view owns DOM work.
|
||||
* Adapters supply the epoch, paint callback, cost policy, clock and frame APIs.
|
||||
* Without a frame API, schedule() paints synchronously. */
|
||||
function headIdentity(rows) {
|
||||
/* logd may reuse IDs after restart; the view preserves raw time/message. */
|
||||
return rows.length ? rows[0]._clearKey || rows[0].id : '';
|
||||
}
|
||||
|
||||
function createScheduler(options) {
|
||||
const { getEpoch, render, renderCost, capacity, requestFrame, cancelFrame } = options;
|
||||
if (!Number.isFinite(capacity) || capacity <= 0)
|
||||
@@ -71,7 +76,7 @@ function createScheduler(options) {
|
||||
|
||||
const cost = renderCost({
|
||||
visibleRowCount: rows.length,
|
||||
visibleHeadId: rows.length ? rows[0].id : '',
|
||||
visibleHeadId: headIdentity(rows),
|
||||
lastRenderedRowCount: lastRenderedRowCount,
|
||||
lastRenderedHeadId: lastRenderedHeadId,
|
||||
lastBatchNewIdCount: lastBatchNewIdCount
|
||||
@@ -101,7 +106,7 @@ function createScheduler(options) {
|
||||
|
||||
function markRendered(rows) {
|
||||
lastRenderedRowCount = rows.length;
|
||||
lastRenderedHeadId = rows.length ? rows[0].id : '';
|
||||
lastRenderedHeadId = headIdentity(rows);
|
||||
}
|
||||
|
||||
function resetBudget() {
|
||||
|
||||
@@ -152,6 +152,10 @@ return view.extend({
|
||||
entries: [],
|
||||
filteredRowsCache: null,
|
||||
sessionSeen: null,
|
||||
/* Recent identities follow poll recency, independently of session-new counts.
|
||||
* Clear snapshots them so counter-cache eviction cannot resurrect rows. */
|
||||
recentEntryKeys: null,
|
||||
clearedEntryKeys: null,
|
||||
pauseBufferLoading: false,
|
||||
/* Freezes row rendering while polling, health, and cadence updates continue. */
|
||||
tablePaused: false,
|
||||
@@ -210,6 +214,8 @@ return view.extend({
|
||||
ruleTargets: {},
|
||||
firewallBackend: 'nft',
|
||||
viewMode: 'simple',
|
||||
/* Hash diag=1: adaptive banner and unactionable Watching tags. */
|
||||
diagnosticMode: false,
|
||||
expandedRowId: null,
|
||||
loggingStatus: null,
|
||||
/* Invalidates status reads started before a newer toggle or refresh. */
|
||||
@@ -265,6 +271,7 @@ return view.extend({
|
||||
parts.push('maxraw=%s'.format(encodeURIComponent(this.manualFetchLines)));
|
||||
}
|
||||
if (this.viewMode === 'detailed') parts.push('view=detailed');
|
||||
if (this.diagnosticMode) parts.push('diag=1');
|
||||
history.replaceState(history.state, '', '#' + parts.join('&'));
|
||||
},
|
||||
|
||||
@@ -420,12 +427,17 @@ return view.extend({
|
||||
applyHash() {
|
||||
this.resolveRpcPreferences();
|
||||
|
||||
this.diagnosticMode = false;
|
||||
const entries = this.hashEntries();
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
const key = entries[i].key;
|
||||
const val = entries[i].val;
|
||||
if (key === 'limit' || key === 'poll' || key === 'maxraw') continue;
|
||||
if (key === 'fetch-mode' || key === 'row-tint') continue;
|
||||
if (key === 'diag') {
|
||||
this.diagnosticMode = val === '1' || val === 'true';
|
||||
continue;
|
||||
}
|
||||
if (key === 'view') {
|
||||
if (val === 'advanced' || val === 'detailed') this.viewMode = 'detailed';
|
||||
else if (val === 'simple') this.viewMode = 'simple';
|
||||
@@ -687,6 +699,7 @@ return view.extend({
|
||||
this.updateDetailToggleUi();
|
||||
this.renderThead();
|
||||
this.updateHash(this.readFilters());
|
||||
this.updateAdaptiveBanner();
|
||||
this.renderRows(true);
|
||||
},
|
||||
|
||||
@@ -1166,6 +1179,12 @@ return view.extend({
|
||||
const row = this.enrichEntry(log.normalizeEntry(raw[i]));
|
||||
if (seen[row.id]) continue;
|
||||
seen[row.id] = true;
|
||||
/* Keep the original time precision: logd can reuse IDs after restart. */
|
||||
const clearKey = JSON.stringify([row.id, raw[i].time, row.message]);
|
||||
/* Free-text search enumerates row fields; this identity is private. */
|
||||
Object.defineProperty(row, '_clearKey', { value: clearKey });
|
||||
this.rememberRecentEntryKey(clearKey);
|
||||
if (this.clearedEntryKeys && this.clearedEntryKeys.has(clearKey)) continue;
|
||||
if (this.rememberSessionId(row.id)) pollNew++;
|
||||
normalized.push(row);
|
||||
}
|
||||
@@ -1249,7 +1268,9 @@ return view.extend({
|
||||
|
||||
this.notePollRtt(rtt, false);
|
||||
this.updateAdaptiveBanner();
|
||||
if (this.clientBackoffEnabled()) {
|
||||
/* Server summaries cover the raw sample and cannot honor a browser Clear.
|
||||
* Keep rows after Clear; cadence backoff and render throttling still apply. */
|
||||
if (this.clientBackoffEnabled() && !this.clearedEntryKeys) {
|
||||
if (this.summaryMode) {
|
||||
this.summaryData =
|
||||
reply.summary &&
|
||||
@@ -1272,7 +1293,7 @@ return view.extend({
|
||||
this.entries = buffer.applyFetchedEntries(this.entries, batch.rows, {
|
||||
/* buffer.js retains its public paused option; this is the view's table state. */
|
||||
paused: this.tablePaused,
|
||||
resumeMerge: resumeMerge || context.pausedAtStart,
|
||||
resumeMerge: resumeMerge || context.pausedAtStart || !!this.clearedEntryKeys,
|
||||
rowLimit: this.rowLimit,
|
||||
fetchLinesMax: constants.FETCH_LINES_MAX
|
||||
});
|
||||
@@ -1316,6 +1337,18 @@ return view.extend({
|
||||
}
|
||||
},
|
||||
|
||||
rememberRecentEntryKey(key) {
|
||||
if (!this.recentEntryKeys) this.recentEntryKeys = new Set();
|
||||
/* logd returns oldest first. Touch hits as well as misses so a wider
|
||||
* lookback cannot make still-reachable recent events the first evicted.
|
||||
* The cache covers at least the maximum raw poll window. */
|
||||
this.recentEntryKeys.delete(key);
|
||||
this.recentEntryKeys.add(key);
|
||||
const cap = Math.max(this.rowLimit * 2, constants.FETCH_LINES_MAX);
|
||||
while (this.recentEntryKeys.size > cap)
|
||||
this.recentEntryKeys.delete(this.recentEntryKeys.values().next().value);
|
||||
},
|
||||
|
||||
rememberSessionId(id) {
|
||||
if (!this.sessionSeen) this.sessionSeen = new Set();
|
||||
if (this.sessionSeen.has(id)) return false;
|
||||
@@ -1356,9 +1389,11 @@ return view.extend({
|
||||
bits.push(
|
||||
_('display limited to %d rows').format(constants.WEAK_DEVICE_DISPLAY_ROW_CAP)
|
||||
);
|
||||
if (this.degradedSampling) bits.push(_('polling slowed'));
|
||||
if (this.serverTruncated) bits.push(_('server limited fetch'));
|
||||
if (this.resolveLoadShed) bits.push(_('hostname lookup paused'));
|
||||
if (this.diagnosticMode) {
|
||||
if (this.degradedSampling) bits.push(_('polling slowed'));
|
||||
if (this.serverTruncated) bits.push(_('server limited fetch'));
|
||||
if (this.resolveLoadShed) bits.push(_('hostname lookup paused'));
|
||||
}
|
||||
if (!this.tablePaused && !this.followLive)
|
||||
bits.push(_('scroll frozen — scroll to top to follow live'));
|
||||
return bits.length ? ' — ' + bits.join(', ') : '';
|
||||
@@ -1554,7 +1589,7 @@ return view.extend({
|
||||
const el = document.getElementById('fwlive-adaptive');
|
||||
if (!el) return;
|
||||
|
||||
const parts = this.adaptiveBannerParts();
|
||||
const parts = !this.diagnosticMode || this.summaryMode ? [] : this.adaptiveBannerParts();
|
||||
|
||||
if (parts.length) {
|
||||
el.style.display = 'block';
|
||||
@@ -1653,6 +1688,7 @@ return view.extend({
|
||||
this.summaryData =
|
||||
summary && typeof summary === 'object' && !Array.isArray(summary) ? summary : null;
|
||||
this.renderSummary();
|
||||
this.updateAdaptiveBanner();
|
||||
},
|
||||
|
||||
leaveSummaryMode() {
|
||||
@@ -1661,6 +1697,7 @@ return view.extend({
|
||||
this.summaryRowsShown = false;
|
||||
this.summaryData = null;
|
||||
this.updateSummaryUi();
|
||||
this.updateAdaptiveBanner();
|
||||
if (this.tablePaused) {
|
||||
this.syncEmptyScrollVisibility(this.filteredRowsState().rows.length);
|
||||
this.updateStatus();
|
||||
@@ -1959,6 +1996,29 @@ return view.extend({
|
||||
}
|
||||
},
|
||||
|
||||
onClearEntriesClick() {
|
||||
this.clearedEntryKeys = new Set(this.recentEntryKeys || []);
|
||||
for (let i = 0; i < this.entries.length; i++) {
|
||||
const key = this.entries[i]._clearKey;
|
||||
if (key) this.clearedEntryKeys.add(key);
|
||||
}
|
||||
this.entries = [];
|
||||
this.expandedRowId = null;
|
||||
this.lastBatchNewIdCount = 0;
|
||||
this.fillingBuffer = false;
|
||||
this.pauseBufferLoading = false;
|
||||
this.invalidateFilteredRows();
|
||||
this.ensureRenderScheduler().resetBudget();
|
||||
if (this.summaryMode) {
|
||||
this.summaryMode = false;
|
||||
this.summaryRowsShown = false;
|
||||
this.summaryData = null;
|
||||
this.updateSummaryUi();
|
||||
this.updateAdaptiveBanner();
|
||||
}
|
||||
this.renderRows(true);
|
||||
},
|
||||
|
||||
onRowLimitChange(ev) {
|
||||
const n = parseInt(ev && ev.target ? ev.target.value : '', 10);
|
||||
if (!isFinite(n) || constants.ROW_LIMIT_OPTIONS.indexOf(n) < 0) return;
|
||||
@@ -2426,6 +2486,9 @@ return view.extend({
|
||||
const pauseBtn = document.getElementById('fwlive-pause');
|
||||
if (pauseBtn) pauseBtn.addEventListener('click', this.onPauseClick.bind(this));
|
||||
|
||||
const clearBtn = document.getElementById('fwlive-clear');
|
||||
if (clearBtn) clearBtn.addEventListener('click', this.onClearEntriesClick.bind(this));
|
||||
|
||||
const limitSel = document.getElementById('fwlive-limit');
|
||||
if (limitSel) limitSel.addEventListener('change', this.onRowLimitChange.bind(this));
|
||||
|
||||
@@ -2562,7 +2625,10 @@ return view.extend({
|
||||
{
|
||||
'id': 'fwlive-fetch-mode',
|
||||
'class': 'cbi-input-select',
|
||||
'aria-controls': 'fwlive-manual-lines'
|
||||
'aria-controls': 'fwlive-manual-lines',
|
||||
'title': _(
|
||||
'Auto reads extra kernel log lines so the table can fill; it is not the same as Limit.'
|
||||
)
|
||||
},
|
||||
this.fetchModeOptions()
|
||||
)
|
||||
@@ -2628,6 +2694,11 @@ return view.extend({
|
||||
'The table updates automatically when your firewall logs traffic. Use Pause if it moves too fast.'
|
||||
)
|
||||
]),
|
||||
E('li', {}, [
|
||||
_(
|
||||
'Clear empties the table. Already seen events stay hidden; new ones still appear.'
|
||||
)
|
||||
]),
|
||||
E('li', {}, [
|
||||
_(
|
||||
'Enable logging turns on WAN zone drop/reject logging only (same as Network → Firewall). It does not add rules or log normal LAN browsing.'
|
||||
@@ -2635,7 +2706,7 @@ return view.extend({
|
||||
]),
|
||||
E('li', {}, [
|
||||
_(
|
||||
'Display options set Limit, Fetch budget, Maximum raw lines, row tint, palette, and hostnames.'
|
||||
'Display options set Limit, row tint, palette, and hostnames. Fetch budget is in Detail view.'
|
||||
)
|
||||
]),
|
||||
E('li', {}, [
|
||||
@@ -2645,7 +2716,7 @@ return view.extend({
|
||||
]),
|
||||
E('li', {}, [
|
||||
_(
|
||||
'Fetch budget controls raw log lines per poll. Auto derives from Limit; Manual selects a bounded maximum.'
|
||||
'Limit is how many events the table keeps. In Detail view, Fetch budget Auto reads extra kernel log lines so the table can fill; Manual selects that read size.'
|
||||
)
|
||||
]),
|
||||
E('li', {}, [
|
||||
@@ -2772,6 +2843,16 @@ return view.extend({
|
||||
},
|
||||
[_('Pause')]
|
||||
),
|
||||
E(
|
||||
'button',
|
||||
{
|
||||
'id': 'fwlive-clear',
|
||||
'class': 'cbi-button fwlive-btn-ghost',
|
||||
'type': 'button',
|
||||
'title': _('Remove shown events. New events still appear.')
|
||||
},
|
||||
[_('Clear')]
|
||||
),
|
||||
E('span', { 'id': 'fwlive-logging-bar', 'class': 'fwlive-logging-bar' }, [])
|
||||
]),
|
||||
E('div', { 'class': 'fwlive-watch-group' }, [
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,51 +1,51 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1791
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1828
|
||||
msgid "%d matching · %d/%d stored"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1756
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1793
|
||||
msgid "%dd"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1755
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1792
|
||||
msgid "%dh"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1754
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1791
|
||||
msgid "%dm"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1753
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1790
|
||||
msgid "%ds"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1517
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552
|
||||
msgid "%s · requested up to %d raw lines · %d firewall messages returned"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1507
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1542
|
||||
msgid ""
|
||||
"%s · requested up to %d raw lines · server limited fetch to %d · %d firewall "
|
||||
"messages returned"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:580
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:609
|
||||
msgid "%s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1793
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1830
|
||||
msgid "0 matching · %d/%d stored"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:487
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:499
|
||||
msgid "Accessible (teal/orange)"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:440
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:469
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:38
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2896
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2977
|
||||
msgid "Action"
|
||||
msgstr ""
|
||||
|
||||
@@ -54,11 +54,11 @@ msgid ""
|
||||
"Activate the message button or click a row to show or hide the full message"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:998
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1011
|
||||
msgid "Administrator access is required to disable logging."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:982
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:995
|
||||
msgid "Administrator access is required to enable logging."
|
||||
msgstr ""
|
||||
|
||||
@@ -66,7 +66,7 @@ msgstr ""
|
||||
msgid "Allow/deny rules, LAN logging, or anything else."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2004
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2064
|
||||
msgid "Also seen"
|
||||
msgstr ""
|
||||
|
||||
@@ -80,19 +80,25 @@ msgid ""
|
||||
"state."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2899
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2980
|
||||
msgid "Any action"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1997
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2057
|
||||
msgid "Any protocol"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1498
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1570
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1533
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1605
|
||||
msgid "Auto"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2630
|
||||
msgid ""
|
||||
"Auto reads extra kernel log lines so the table can fill; it is not the same "
|
||||
"as Limit."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:379
|
||||
msgid "Before you enable logging"
|
||||
msgstr ""
|
||||
@@ -105,33 +111,43 @@ msgstr ""
|
||||
msgid "Changes:"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:486
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:498
|
||||
msgid "Classic (green/red)"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2604
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2670
|
||||
msgid "Classic uses green/red; Accessible uses teal/orange"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2854
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/chips.js:94
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/chips.js:274
|
||||
msgid "Clear all"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2972
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699
|
||||
msgid ""
|
||||
"Clear empties the table. Already seen events stay hidden; new ones still "
|
||||
"appear."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3053
|
||||
msgid ""
|
||||
"Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for "
|
||||
"firewall settings · in Simple view, activate the message button or click a "
|
||||
"row to show or hide the full message"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2755
|
||||
msgid ""
|
||||
"Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a "
|
||||
"chip) to exclude."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1998
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2058
|
||||
msgid "Common"
|
||||
msgstr ""
|
||||
|
||||
@@ -141,7 +157,7 @@ msgid ""
|
||||
"it; kernel/logd may still constrain total log volume."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1804
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1841
|
||||
msgid "Connection lost — retrying…"
|
||||
msgstr ""
|
||||
|
||||
@@ -153,49 +169,49 @@ msgstr ""
|
||||
msgid "Could not clear the WAN zone log option."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:804
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:817
|
||||
msgid "Could not create a temporary file for rule names."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:993
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1006
|
||||
msgid "Could not disable logging."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:971
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:984
|
||||
msgid "Could not enable logging."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:907
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:920
|
||||
msgid "Could not load logging status."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:810
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:823
|
||||
msgid "Could not load rule names."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:806
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:819
|
||||
msgid "Could not process firewall rule names."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:950
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:983
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:999
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:963
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:996
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1012
|
||||
msgid "Could not reach the router; check the current logging state."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:808
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:821
|
||||
msgid "Could not read the active firewall rules."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:906
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:919
|
||||
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:815
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:828
|
||||
msgid "Could not refresh rule names."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:813
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:826
|
||||
msgid "Could not refresh rule names; previously loaded names are still shown."
|
||||
msgstr ""
|
||||
|
||||
@@ -215,7 +231,7 @@ msgstr ""
|
||||
msgid "Could not write the WAN zone log option."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2927
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3008
|
||||
msgid "Custom protocol (prefix ! to exclude). Overrides the menu when set."
|
||||
msgstr ""
|
||||
|
||||
@@ -223,28 +239,28 @@ msgstr ""
|
||||
msgid "DPort"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:444
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:473
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:46
|
||||
msgid "Destination"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2957
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3038
|
||||
msgid "Destination IP contains (! to exclude)"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:446
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:475
|
||||
msgid "Destination port"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2962
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3043
|
||||
msgid "Destination port (! to exclude)"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2807
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2888
|
||||
msgid "Detail"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2760
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2831
|
||||
msgid "Details"
|
||||
msgstr ""
|
||||
|
||||
@@ -256,20 +272,20 @@ msgstr ""
|
||||
msgid "Disabling…"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1547
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1582
|
||||
msgid ""
|
||||
"Display limited to %d rows on this device; the larger Limit still buffers "
|
||||
"rows."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2545
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2608
|
||||
msgid "Display options"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2638
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2709
|
||||
msgid ""
|
||||
"Display options set Limit, Fetch budget, Maximum raw lines, row tint, "
|
||||
"palette, and hostnames."
|
||||
"Display options set Limit, row tint, palette, and hostnames. Fetch budget is "
|
||||
"in Detail view."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:387
|
||||
@@ -288,7 +304,7 @@ msgstr ""
|
||||
msgid "Enable logging"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2633
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2704
|
||||
msgid ""
|
||||
"Enable logging turns on WAN zone drop/reject logging only (same as Network → "
|
||||
"Firewall). It does not add rules or log normal LAN browsing."
|
||||
@@ -298,7 +314,7 @@ msgstr ""
|
||||
msgid "Enabling…"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2011
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2071
|
||||
msgid "Exclude"
|
||||
msgstr ""
|
||||
|
||||
@@ -307,20 +323,14 @@ msgstr ""
|
||||
msgid "Exclude instead"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2559
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2622
|
||||
msgid "Fetch budget"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2648
|
||||
msgid ""
|
||||
"Fetch budget controls raw log lines per poll. Auto derives from Limit; "
|
||||
"Manual selects a bounded maximum."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:63
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:84
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:149
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2896
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2977
|
||||
msgid "Filter by %s"
|
||||
msgstr ""
|
||||
|
||||
@@ -328,12 +338,12 @@ msgstr ""
|
||||
msgid "Filter logs by rule (hint: %s). Ctrl+click to open firewall settings."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2722
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2793
|
||||
#: openwrt-feed/luci-app-fwlive/root/usr/share/luci/menu.d/luci-app-fwlive.json:3
|
||||
msgid "Firewall Live View"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1771
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1808
|
||||
msgid "Firewall log has no current entries; showing rows last received %s ago."
|
||||
msgstr ""
|
||||
|
||||
@@ -345,7 +355,7 @@ msgstr ""
|
||||
msgid "Flow"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2658
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2729
|
||||
msgid ""
|
||||
"For a responsive table on a weak device, keep Limit at 250 rows or below. "
|
||||
"The weak-device cap affects rendered rows; the buffer can still retain more."
|
||||
@@ -359,7 +369,7 @@ msgstr ""
|
||||
msgid "Grant access to firewall live log view"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2624
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2690
|
||||
msgid "Help"
|
||||
msgstr ""
|
||||
|
||||
@@ -367,15 +377,15 @@ msgstr ""
|
||||
msgid "Hide full message"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1645
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1680
|
||||
msgid "Hide rows"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1543
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1578
|
||||
msgid "Hostname lookup paused while the router is under load."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2002
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2062
|
||||
msgid "ICMPv6"
|
||||
msgstr ""
|
||||
|
||||
@@ -383,7 +393,7 @@ msgstr ""
|
||||
msgid "IN"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2695
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2766
|
||||
msgid ""
|
||||
"If Row tint looks missing, the active LuCI theme may omit success/error or "
|
||||
"info/warn CSS variables; fwlive falls back to local colors (air-gapped, no "
|
||||
@@ -396,7 +406,7 @@ msgid ""
|
||||
"Help / the enabling-logs guide."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2679
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2750
|
||||
msgid ""
|
||||
"In Simple view, activate the message button or click a row to show or hide "
|
||||
"the full message."
|
||||
@@ -417,16 +427,16 @@ msgid ""
|
||||
"release, then reload the firewall."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1802
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1839
|
||||
msgid "Installation is incomplete. Reinstall luci-app-fwlive."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:441
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:470
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:40
|
||||
msgid "Interface"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2942
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3023
|
||||
msgid "Interface (prefix ! to exclude)"
|
||||
msgstr ""
|
||||
|
||||
@@ -443,11 +453,18 @@ msgstr ""
|
||||
msgid "Len"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2548
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2611
|
||||
msgid "Limit"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:861
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2719
|
||||
msgid ""
|
||||
"Limit is how many events the table keeps. In Detail view, Fetch budget Auto "
|
||||
"reads extra kernel log lines so the table can fill; Manual selects that read "
|
||||
"size."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:874
|
||||
msgid "Live view may be incomplete — a legacy iptables table is registered"
|
||||
msgstr ""
|
||||
|
||||
@@ -455,16 +472,16 @@ msgstr ""
|
||||
msgid "Logging is off on this router"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1498
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1571
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1533
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1606
|
||||
msgid "Manual"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2577
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2643
|
||||
msgid "Manual still uses server protection and poll cadence"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2653
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2724
|
||||
msgid ""
|
||||
"Manual still uses server protection and poll cadence; it changes the fetch "
|
||||
"budget, not the polling interval."
|
||||
@@ -474,18 +491,18 @@ msgstr ""
|
||||
msgid "Manual test (System → Terminal):"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2571
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2637
|
||||
msgid "Maximum raw lines"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:52
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:377
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2819
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2826
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2900
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2907
|
||||
msgid "Message"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2937
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3018
|
||||
msgid "More filters"
|
||||
msgstr ""
|
||||
|
||||
@@ -528,7 +545,7 @@ msgstr ""
|
||||
msgid "OUT"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2849
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2930
|
||||
msgid "One line"
|
||||
msgstr ""
|
||||
|
||||
@@ -555,34 +572,34 @@ msgstr ""
|
||||
msgid "Outbound"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2598
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2664
|
||||
msgid "Palette"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1865
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2773
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1902
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2844
|
||||
msgid "Pause"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1864
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1901
|
||||
msgid "Paused"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1530
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1565
|
||||
msgid ""
|
||||
"Polling slowed: the router is responding slowly, so polls run less often."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:442
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:471
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:44
|
||||
msgid "Proto"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2918
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2999
|
||||
msgid "Protocol — common values"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2889
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2970
|
||||
msgid "Quick search"
|
||||
msgstr ""
|
||||
|
||||
@@ -596,22 +613,26 @@ msgstr ""
|
||||
msgid "Remove filter"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1865
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2852
|
||||
msgid "Remove shown events. New events still appear."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1902
|
||||
msgid "Resume"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2588
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2654
|
||||
msgid "Row tint"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2760
|
||||
msgid ""
|
||||
"Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/"
|
||||
"red, default) or Accessible (teal/orange). Action text stays colored either "
|
||||
"way."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2745
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2816
|
||||
msgid ""
|
||||
"Row tint used a local color fallback because the active LuCI theme did not "
|
||||
"apply pass/deny backgrounds."
|
||||
@@ -621,19 +642,19 @@ msgstr ""
|
||||
msgid "Rule"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2760
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2831
|
||||
msgid "Rule name details"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:832
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:845
|
||||
msgid "Rule-name lookup does not change your firewall rules."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:817
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:830
|
||||
msgid "Rule-name lookup failed."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:824
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:837
|
||||
msgid "Rule-name lookup reached a safety limit."
|
||||
msgstr ""
|
||||
|
||||
@@ -641,26 +662,26 @@ msgstr ""
|
||||
msgid "SPort"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:439
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:468
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1527
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1562
|
||||
msgid "Server adaptive protection is disabled."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1535
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1570
|
||||
msgid ""
|
||||
"Server limited fetch: the router is under load; at most %d log lines per "
|
||||
"poll."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1540
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1575
|
||||
msgid ""
|
||||
"Server limited fetch: this poll returned fewer lines to protect the router."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1525
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1560
|
||||
msgid "Server protection state is unknown."
|
||||
msgstr ""
|
||||
|
||||
@@ -668,80 +689,80 @@ msgstr ""
|
||||
msgid "Show full message"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2615
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2681
|
||||
msgid "Show hostnames"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2586
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652
|
||||
msgid "Show pass/deny row background colors"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1645
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2872
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1680
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2953
|
||||
msgid "Show rows"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1605
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1640
|
||||
msgid "Showing a compact summary of the top of the shown sample."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2796
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2877
|
||||
msgid "Simple"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:835
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:848
|
||||
msgid ""
|
||||
"Some entries may show names derived from their log prefixes. Searching by a "
|
||||
"friendly rule name may miss those entries."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:855
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:868
|
||||
msgid "Some rule names may be missing"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:443
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:472
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:45
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2947
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3028
|
||||
msgid "Source IP contains (! to exclude)"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:445
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:474
|
||||
msgid "Source port"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2952
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3033
|
||||
msgid "Source port (! to exclude)"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1607
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1642
|
||||
msgid "Summary data is unavailable; show rows to inspect the sample."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2863
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2944
|
||||
msgid "Summary mode"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2643
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2714
|
||||
msgid ""
|
||||
"Summary mode: when the router responds slowly, a compact summary replaces "
|
||||
"the table. Use Show rows to see the table; it returns automatically after "
|
||||
"three fast polls."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1609
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1644
|
||||
msgid "Summary was bounded before all categories could be included."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2663
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2734
|
||||
msgid ""
|
||||
"Switching tabs pauses polling; returning performs one catch-up poll. "
|
||||
"Hostnames are off by default because lookups add work."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1700
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1737
|
||||
msgid ""
|
||||
"Table refresh throttled: the event rate is high, so the table repaints less "
|
||||
"often to protect the browser. The buffer still updates; refresh resumes "
|
||||
@@ -752,7 +773,7 @@ msgstr ""
|
||||
msgid "The firewall did not reload; saved and live logging may differ."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2673
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2744
|
||||
msgid ""
|
||||
"The rate shown for WAN logging is the configured WAN zone log_limit, not "
|
||||
"proof the running fw4 supports it. The fw4 bundled with OpenWrt 23.05.5 "
|
||||
@@ -760,23 +781,23 @@ msgid ""
|
||||
"fwlive does not impose a limit."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1803
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1840
|
||||
msgid "The router could not read the firewall log — retrying…"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2668
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2739
|
||||
msgid ""
|
||||
"The router log ring may evict older events before fwlive reads them. fwlive "
|
||||
"cannot recover evicted entries or change forwarding behavior."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2628
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2694
|
||||
msgid ""
|
||||
"The table updates automatically when your firewall logs traffic. Use Pause "
|
||||
"if it moves too fast."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2748
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2819
|
||||
msgid "Theme tint fallback"
|
||||
msgstr ""
|
||||
|
||||
@@ -793,15 +814,15 @@ msgstr ""
|
||||
msgid "Time"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1614
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1649
|
||||
msgid "Top drops"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1617
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1652
|
||||
msgid "Top rules"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1611
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1646
|
||||
msgid "Top talkers"
|
||||
msgstr ""
|
||||
|
||||
@@ -823,16 +844,16 @@ msgstr ""
|
||||
msgid "Undo:"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2692
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2763
|
||||
msgid "Use Detail for all columns (flags, length, raw message)."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2778
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2784
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2859
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2865
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:994
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1007
|
||||
msgid "WAN drop/reject logging is off."
|
||||
msgstr ""
|
||||
|
||||
@@ -842,13 +863,13 @@ msgid ""
|
||||
"here. Normal LAN browsing will not."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:975
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:988
|
||||
msgid ""
|
||||
"WAN drop/reject logging is on. Blocked inbound traffic should appear here as "
|
||||
"it happens — not normal LAN browsing."
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:977
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:990
|
||||
msgid "WAN logging is already enabled."
|
||||
msgstr ""
|
||||
|
||||
@@ -877,25 +898,25 @@ msgstr ""
|
||||
msgid "Waiting for firewall events"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1864
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2736
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1901
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2807
|
||||
msgid "Watching"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2838
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2919
|
||||
msgid "Wrap"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:74
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2901
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2982
|
||||
msgid "block"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1348
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1381
|
||||
msgid "buffer filling"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1352
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1385
|
||||
msgid "buffer full"
|
||||
msgstr ""
|
||||
|
||||
@@ -907,7 +928,7 @@ msgstr ""
|
||||
msgid "contains"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1357
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1390
|
||||
msgid "display limited to %d rows"
|
||||
msgstr ""
|
||||
|
||||
@@ -916,11 +937,11 @@ msgid "does not contain"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:75
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2902
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2983
|
||||
msgid "drop"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1361
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1395
|
||||
msgid "hostname lookup paused"
|
||||
msgstr ""
|
||||
|
||||
@@ -928,11 +949,11 @@ msgstr ""
|
||||
msgid "is"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1347
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1380
|
||||
msgid "loading buffer"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1789
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1826
|
||||
msgid "loading…"
|
||||
msgstr ""
|
||||
|
||||
@@ -940,8 +961,8 @@ msgstr ""
|
||||
msgid "no WAN rate limit configured"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1587
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1596
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1622
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1631
|
||||
msgid "none"
|
||||
msgstr ""
|
||||
|
||||
@@ -949,98 +970,98 @@ msgstr ""
|
||||
msgid "not"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2019
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2079
|
||||
msgid "not AH"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2018
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2078
|
||||
msgid "not ESP"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2017
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2077
|
||||
msgid "not GRE"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2014
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2074
|
||||
msgid "not ICMP"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2015
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2075
|
||||
msgid "not ICMPv6"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2016
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2076
|
||||
msgid "not IGMP"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2020
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2080
|
||||
msgid "not SCTP"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2012
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2072
|
||||
msgid "not TCP"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2013
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2073
|
||||
msgid "not UDP"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2907
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2988
|
||||
msgid "not block"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2906
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2987
|
||||
msgid "not drop"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2905
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2986
|
||||
msgid "not pass"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2908
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2989
|
||||
msgid "not reject"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2909
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2990
|
||||
msgid "not unknown"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2925
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:3006
|
||||
msgid "or type…"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:73
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2900
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2981
|
||||
msgid "pass"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1359
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1393
|
||||
msgid "polling slowed"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:76
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2903
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2984
|
||||
msgid "reject"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1363
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1398
|
||||
msgid "scroll frozen — scroll to top to follow live"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1360
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1394
|
||||
msgid "server limited fetch"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1354
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1387
|
||||
msgid "table refresh throttled"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:65
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2904
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2985
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:797
|
||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:810
|
||||
msgid "using fw4"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -54,8 +54,36 @@ function strip_kv(s, out, i, n, prev, rest) {
|
||||
}
|
||||
return out
|
||||
}
|
||||
function action_word_prefix(first, words, n, i) {
|
||||
n = split("ACCEPT ALLOW PASS DROP REJECT DENY BLOCK", words, " ")
|
||||
first = tolower(first)
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (tolower(words[i]) == first) return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
function strip_leading_rule_hint(s, first, rest) {
|
||||
sub(/^\[[[:space:]]*[0-9.]+\][[:space:]]*/, "", s)
|
||||
if (match(tolower(s), /^fw4:[[:space:]]*/))
|
||||
s = substr(s, RSTART + RLENGTH)
|
||||
if (match(s, "^[A-Za-z0-9_.-]+(:|[[:space:]]+)(IN=|OUT=|SRC=|DST=|PROTO=)")) {
|
||||
match(s, "^[A-Za-z0-9_.-]+")
|
||||
first = substr(s, RSTART, RLENGTH)
|
||||
if (!action_word_prefix(first)) {
|
||||
rest = substr(s, RSTART + RLENGTH)
|
||||
match(rest, "^(:|[[:space:]]+)")
|
||||
s = substr(rest, RSTART + RLENGTH)
|
||||
}
|
||||
}
|
||||
else if (match(s, "^[A-Za-z0-9_.-]+:")) {
|
||||
first = substr(s, RSTART, RLENGTH - 1)
|
||||
if (tolower(first) != "kernel" && tolower(first) != "iptables" && !action_word_prefix(first))
|
||||
s = substr(s, RSTART + RLENGTH)
|
||||
}
|
||||
return s
|
||||
}
|
||||
function detect_action(s, words, n, i, w, wl, lc, start, pos, before, afterc, best, bestpos) {
|
||||
s = strip_kv(s)
|
||||
s = strip_kv(strip_leading_rule_hint(s))
|
||||
n = split("ACCEPT ALLOW PASS DROP REJECT DENY BLOCK", words, " ")
|
||||
lc = tolower(s)
|
||||
best = ""
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-open-box
|
||||
PKG_VERSION:=0.1.337
|
||||
PKG_RELEASE:=34
|
||||
PKG_VERSION:=0.1.338
|
||||
PKG_RELEASE:=35
|
||||
|
||||
PKG_MAINTAINER:=liandu2024
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
|
||||
@@ -85,7 +85,9 @@ const PodmanFormContainer = podmanView.form.extend({
|
||||
field.value(name, name);
|
||||
}
|
||||
});
|
||||
field.description = _('Add the container to an existing pod. Network, hostname and port mappings come from the pod\'s infra container.');
|
||||
field.description = _(
|
||||
'Add the container to an existing pod. Network, hostname and port mappings come from the pod\'s infra container.'
|
||||
);
|
||||
|
||||
field = this.section.option(form.Value, 'command', _('Command'));
|
||||
field.placeholder = '/bin/sh';
|
||||
@@ -115,7 +117,8 @@ const PodmanFormContainer = podmanView.form.extend({
|
||||
field.placeholder = '/host/path:/container/path:ro\nvolume-name:/data';
|
||||
field.rows = 4;
|
||||
field.optional = true;
|
||||
field.description = _('One per line. Format: source:destination[:options]. Options: ro, rw, Z, z');
|
||||
field.description = _(
|
||||
'One per line. Format: source:destination[:options]. Options: ro, rw, Z, z');
|
||||
|
||||
field = this.section.option(form.ListValue, 'network', _('Network'));
|
||||
field.depends('pod', '');
|
||||
@@ -254,15 +257,20 @@ const PodmanFormContainer = podmanView.form.extend({
|
||||
|
||||
const opts = parts.length > 2 ? parts[2].split(',') : [];
|
||||
if (parts[0].includes('/')) {
|
||||
const mount = { Source: parts[0], Destination: parts[1] };
|
||||
if (opts.includes('ro')) mount.ReadOnly = true;
|
||||
const selinux = opts.filter((o) => o === 'Z' || o === 'z');
|
||||
if (selinux.length > 0) mount.options = selinux;
|
||||
const mount = {
|
||||
Type: 'bind',
|
||||
Source: parts[0],
|
||||
Destination: parts[1]
|
||||
};
|
||||
if (opts.length > 0) mount.Options = opts;
|
||||
mounts.push(mount);
|
||||
return;
|
||||
}
|
||||
|
||||
const vol = { Name: parts[0], Dest: parts[1] };
|
||||
const vol = {
|
||||
Name: parts[0],
|
||||
Dest: parts[1]
|
||||
};
|
||||
if (opts.length > 0) vol.Options = opts;
|
||||
volumes.push(vol);
|
||||
});
|
||||
@@ -271,11 +279,17 @@ const PodmanFormContainer = podmanView.form.extend({
|
||||
}
|
||||
if (!data.pod) {
|
||||
if (data.network === 'host') {
|
||||
spec.netns = { nsmode: 'host' };
|
||||
spec.netns = {
|
||||
nsmode: 'host'
|
||||
};
|
||||
} else if (data.network === 'none') {
|
||||
spec.netns = { nsmode: 'none' };
|
||||
spec.netns = {
|
||||
nsmode: 'none'
|
||||
};
|
||||
} else if (data.network && data.network !== 'bridge') {
|
||||
spec.networks = { [data.network]: {} };
|
||||
spec.networks = {
|
||||
[data.network]: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
if (data.restart !== 'no') spec.restart_policy = data.restart;
|
||||
@@ -304,11 +318,15 @@ const PodmanFormContainer = podmanView.form.extend({
|
||||
if (data.cpus || data.memory) {
|
||||
spec.resource_limits = {};
|
||||
if (data.cpus) {
|
||||
spec.resource_limits.cpu = { quota: parseFloat(data.cpus) * 100000 };
|
||||
spec.resource_limits.cpu = {
|
||||
quota: parseFloat(data.cpus) * 100000
|
||||
};
|
||||
}
|
||||
if (data.memory) {
|
||||
const memBytes = podmanUtil.format.parseMemory(data.memory);
|
||||
if (memBytes > 0) spec.resource_limits.memory = { limit: memBytes };
|
||||
if (memBytes > 0) spec.resource_limits.memory = {
|
||||
limit: memBytes
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +346,7 @@ const PodmanFormContainer = podmanView.form.extend({
|
||||
if (shouldStart) await container.start();
|
||||
};
|
||||
|
||||
return this.super('handleCreate', [ createFn, _('Container') ]);
|
||||
return this.super('handleCreate', [createFn, _('Container')]);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -135,7 +135,9 @@ const Container = Model.base.extend({
|
||||
},
|
||||
|
||||
getStateBadge() {
|
||||
return E('div', { class: `badge ${this.getState()}` }, [ this.getState() ]);
|
||||
return E('div', {
|
||||
class: `badge ${this.getState()}`
|
||||
}, [this.getState()]);
|
||||
},
|
||||
|
||||
getAutoUpdateLabel() {
|
||||
@@ -164,7 +166,9 @@ const Container = Model.base.extend({
|
||||
const networkSettings = this.NetworkSettings || {};
|
||||
const mounts = this.Mounts || [];
|
||||
|
||||
const spec = { image: imageRef };
|
||||
const spec = {
|
||||
image: imageRef
|
||||
};
|
||||
|
||||
// Name (strip leading slash added by Podman inspect)
|
||||
if (this.Name) spec.name = this.Name.replace(/^\//, '');
|
||||
@@ -179,12 +183,36 @@ const Container = Model.base.extend({
|
||||
if (config.Hostname) spec.hostname = config.Hostname;
|
||||
if (config.StopSignal) {
|
||||
const sigMap = {
|
||||
SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGTRAP: 5,
|
||||
SIGABRT: 6, SIGBUS: 7, SIGFPE: 8, SIGKILL: 9, SIGUSR1: 10,
|
||||
SIGSEGV: 11, SIGUSR2: 12, SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15,
|
||||
SIGCHLD: 17, SIGCONT: 18, SIGSTOP: 19, SIGTSTP: 20, SIGTTIN: 21,
|
||||
SIGTTOU: 22, SIGURG: 23, SIGXCPU: 24, SIGXFSZ: 25, SIGVTALRM: 26,
|
||||
SIGPROF: 27, SIGWINCH: 28, SIGIO: 29, SIGPWR: 30, SIGSYS: 31,
|
||||
SIGHUP: 1,
|
||||
SIGINT: 2,
|
||||
SIGQUIT: 3,
|
||||
SIGILL: 4,
|
||||
SIGTRAP: 5,
|
||||
SIGABRT: 6,
|
||||
SIGBUS: 7,
|
||||
SIGFPE: 8,
|
||||
SIGKILL: 9,
|
||||
SIGUSR1: 10,
|
||||
SIGSEGV: 11,
|
||||
SIGUSR2: 12,
|
||||
SIGPIPE: 13,
|
||||
SIGALRM: 14,
|
||||
SIGTERM: 15,
|
||||
SIGCHLD: 17,
|
||||
SIGCONT: 18,
|
||||
SIGSTOP: 19,
|
||||
SIGTSTP: 20,
|
||||
SIGTTIN: 21,
|
||||
SIGTTOU: 22,
|
||||
SIGURG: 23,
|
||||
SIGXCPU: 24,
|
||||
SIGXFSZ: 25,
|
||||
SIGVTALRM: 26,
|
||||
SIGPROF: 27,
|
||||
SIGWINCH: 28,
|
||||
SIGIO: 29,
|
||||
SIGPWR: 30,
|
||||
SIGSYS: 31,
|
||||
};
|
||||
const sigStr = String(config.StopSignal).toUpperCase().replace(/^SIG/, '');
|
||||
const sigNum = sigMap['SIG' + sigStr] ?? parseInt(config.StopSignal, 10);
|
||||
@@ -213,9 +241,12 @@ const Container = Model.base.extend({
|
||||
if (hostConfig.CapAdd && hostConfig.CapAdd.length) spec.cap_add = hostConfig.CapAdd;
|
||||
if (hostConfig.CapDrop && hostConfig.CapDrop.length) spec.cap_drop = hostConfig.CapDrop;
|
||||
if (hostConfig.Dns && hostConfig.Dns.length) spec.dns_server = hostConfig.Dns;
|
||||
if (hostConfig.DnsOptions && hostConfig.DnsOptions.length) spec.dns_option = hostConfig.DnsOptions;
|
||||
if (hostConfig.DnsSearch && hostConfig.DnsSearch.length) spec.dns_search = hostConfig.DnsSearch;
|
||||
if (hostConfig.ExtraHosts && hostConfig.ExtraHosts.length) spec.hostadd = hostConfig.ExtraHosts;
|
||||
if (hostConfig.DnsOptions && hostConfig.DnsOptions.length) spec.dns_option = hostConfig
|
||||
.DnsOptions;
|
||||
if (hostConfig.DnsSearch && hostConfig.DnsSearch.length) spec.dns_search = hostConfig
|
||||
.DnsSearch;
|
||||
if (hostConfig.ExtraHosts && hostConfig.ExtraHosts.length) spec.hostadd = hostConfig
|
||||
.ExtraHosts;
|
||||
if (hostConfig.GroupAdd && hostConfig.GroupAdd.length) spec.groups = hostConfig.GroupAdd;
|
||||
if (hostConfig.ShmSize) spec.shm_size = hostConfig.ShmSize;
|
||||
if (hostConfig.OomScoreAdj) spec.oom_score_adj = hostConfig.OomScoreAdj;
|
||||
@@ -248,7 +279,10 @@ const Container = Model.base.extend({
|
||||
const [port, protocol] = portProto.split('/');
|
||||
const containerPort = parseInt(port, 10);
|
||||
for (const b of bindings) {
|
||||
const m = { container_port: containerPort, protocol: protocol || 'tcp' };
|
||||
const m = {
|
||||
container_port: containerPort,
|
||||
protocol: protocol || 'tcp'
|
||||
};
|
||||
if (b.HostPort) m.host_port = parseInt(b.HostPort, 10);
|
||||
if (b.HostIp && b.HostIp !== '0.0.0.0') m.host_ip = b.HostIp;
|
||||
spec.portmappings.push(m);
|
||||
@@ -260,9 +294,13 @@ const Container = Model.base.extend({
|
||||
if (hostConfig.Memory > 0 || hostConfig.CpuQuota > 0) {
|
||||
spec.resource_limits = {};
|
||||
if (hostConfig.Memory > 0)
|
||||
spec.resource_limits.memory = { limit: hostConfig.Memory };
|
||||
spec.resource_limits.memory = {
|
||||
limit: hostConfig.Memory
|
||||
};
|
||||
if (hostConfig.CpuQuota > 0) {
|
||||
spec.resource_limits.cpu = { quota: hostConfig.CpuQuota };
|
||||
spec.resource_limits.cpu = {
|
||||
quota: hostConfig.CpuQuota
|
||||
};
|
||||
if (hostConfig.CpuPeriod > 0)
|
||||
spec.resource_limits.cpu.period = hostConfig.CpuPeriod;
|
||||
}
|
||||
@@ -281,20 +319,28 @@ const Container = Model.base.extend({
|
||||
}
|
||||
|
||||
if (bindMounts.length) {
|
||||
spec.mounts = bindMounts.map(m => ({
|
||||
Source: m.Source,
|
||||
Destination: m.Destination,
|
||||
ReadOnly: !m.RW,
|
||||
options: m.Options || []
|
||||
}));
|
||||
spec.mounts = bindMounts.map(m => {
|
||||
const options = (m.Options || []).slice();
|
||||
if (!m.RW) options.push('ro');
|
||||
return {
|
||||
Type: 'bind',
|
||||
Source: m.Source,
|
||||
Destination: m.Destination,
|
||||
Options: options
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Network
|
||||
const nm = hostConfig.NetworkMode || '';
|
||||
if (nm === 'host') {
|
||||
spec.netns = { nsmode: 'host' };
|
||||
spec.netns = {
|
||||
nsmode: 'host'
|
||||
};
|
||||
} else if (nm === 'none') {
|
||||
spec.netns = { nsmode: 'none' };
|
||||
spec.netns = {
|
||||
nsmode: 'none'
|
||||
};
|
||||
} else {
|
||||
const nets = networkSettings.Networks || {};
|
||||
const nonDefault = Object.keys(nets).filter(n => n !== 'bridge' && n !== 'default');
|
||||
@@ -364,7 +410,13 @@ const Container = Model.base.extend({
|
||||
const portBindings = networkPorts[port] || [];
|
||||
|
||||
if (portBindings.length === 0) {
|
||||
ports.push({ string: port, port: portOnly, protocol: protocol || '', hostPort: null, hostIp: null });
|
||||
ports.push({
|
||||
string: port,
|
||||
port: portOnly,
|
||||
protocol: protocol || '',
|
||||
hostPort: null,
|
||||
hostIp: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -393,16 +445,28 @@ const Container = Model.base.extend({
|
||||
const cleanUrl = this.Image.split('@')[0];
|
||||
const lastColon = cleanUrl.lastIndexOf(':');
|
||||
const lastSlash = cleanUrl.lastIndexOf('/');
|
||||
return { cleanUrl, lastColon, lastSlash };
|
||||
return {
|
||||
cleanUrl,
|
||||
lastColon,
|
||||
lastSlash
|
||||
};
|
||||
},
|
||||
|
||||
getImageRepo() {
|
||||
const { cleanUrl, lastColon, lastSlash } = this._parseImageRef();
|
||||
const {
|
||||
cleanUrl,
|
||||
lastColon,
|
||||
lastSlash
|
||||
} = this._parseImageRef();
|
||||
return lastColon > lastSlash ? cleanUrl.substring(0, lastColon) : '';
|
||||
},
|
||||
|
||||
getImageTag() {
|
||||
const { cleanUrl, lastColon, lastSlash } = this._parseImageRef();
|
||||
const {
|
||||
cleanUrl,
|
||||
lastColon,
|
||||
lastSlash
|
||||
} = this._parseImageRef();
|
||||
return lastColon > lastSlash ? cleanUrl.substring(lastColon + 1) : 'latest';
|
||||
},
|
||||
|
||||
@@ -446,15 +510,17 @@ const Container = Model.base.extend({
|
||||
text = constants.ICON.INIT_DISABLED;
|
||||
}
|
||||
|
||||
return E('span', { class: `autostart-status autostart-${status || ''}` }, text);
|
||||
return E('span', {
|
||||
class: `autostart-status autostart-${status || ''}`
|
||||
}, text);
|
||||
},
|
||||
|
||||
isRunning() {
|
||||
const state = this.getState();
|
||||
return this.State?.Running
|
||||
|| state === 'running'
|
||||
|| state === 'starting'
|
||||
|| state === 'unhealthy';
|
||||
return this.State?.Running ||
|
||||
state === 'running' ||
|
||||
state === 'starting' ||
|
||||
state === 'unhealthy';
|
||||
},
|
||||
|
||||
isStopped() {
|
||||
@@ -530,7 +596,8 @@ const Container = Model.base.extend({
|
||||
if (hasRestartPolicy && (initScriptStatus === 'none' || initScriptStatus === 'missing')) {
|
||||
await this.generateInitScript();
|
||||
await this.enableInitScript();
|
||||
} else if (!hasRestartPolicy && (initScriptStatus === 'enabled' || initScriptStatus === 'disabled')) {
|
||||
} else if (!hasRestartPolicy && (initScriptStatus === 'enabled' || initScriptStatus ===
|
||||
'disabled')) {
|
||||
await this.removeInitScript();
|
||||
}
|
||||
},
|
||||
@@ -564,25 +631,39 @@ const Container = Model.base.extend({
|
||||
},
|
||||
|
||||
async connect(networkName, payload) {
|
||||
return Network.getSingleton({ name: networkName }).connect(Object.assign({ container: this.getID() }, payload));
|
||||
return Network.getSingleton({
|
||||
name: networkName
|
||||
}).connect(Object.assign({
|
||||
container: this.getID()
|
||||
}, payload));
|
||||
},
|
||||
|
||||
async disconnect(networkName) {
|
||||
return Network.getSingleton({ name: networkName }).disconnect({ Container: this.getID() });
|
||||
return Network.getSingleton({
|
||||
name: networkName
|
||||
}).disconnect({
|
||||
Container: this.getID()
|
||||
});
|
||||
},
|
||||
|
||||
streamTop(onChunk, delay, psargs) {
|
||||
const params = new URLSearchParams({ delay: String(delay || 2) });
|
||||
const params = new URLSearchParams({
|
||||
delay: String(delay || 2)
|
||||
});
|
||||
if (psargs) params.set('ps_args', psargs);
|
||||
const url = L.url('admin/podman/stream/top', this.getID()) + '?' + params;
|
||||
return this._stream(
|
||||
() => url,
|
||||
(data) => { if (!data.raw && !data.Error) onChunk(data); }
|
||||
(data) => {
|
||||
if (!data.raw && !data.Error) onChunk(data);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
streamStats(onChunk, interval) {
|
||||
const params = new URLSearchParams({ interval: String(interval || 2) });
|
||||
const params = new URLSearchParams({
|
||||
interval: String(interval || 2)
|
||||
});
|
||||
const url = L.url('admin/podman/stream/stats', this.getID()) + '?' + params;
|
||||
return this._stream(
|
||||
() => url,
|
||||
@@ -595,7 +676,12 @@ const Container = Model.base.extend({
|
||||
);
|
||||
},
|
||||
|
||||
streamLogs(onChunk, { tail = 100, since = null, until = null, follow = true } = {}) {
|
||||
streamLogs(onChunk, {
|
||||
tail = 100,
|
||||
since = null,
|
||||
until = null,
|
||||
follow = true
|
||||
} = {}) {
|
||||
if (!follow) {
|
||||
// Historical fetch: single request, stop after completion (no reconnect)
|
||||
let handle;
|
||||
@@ -632,7 +718,9 @@ const Container = Model.base.extend({
|
||||
return L.url('admin/podman/stream/logs', this.getID()) + '?' + params;
|
||||
},
|
||||
onChunk,
|
||||
() => { reconnectSince = Date.now() / 1000; }
|
||||
() => {
|
||||
reconnectSince = Date.now() / 1000;
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
@@ -656,7 +744,9 @@ const Container = Model.base.extend({
|
||||
|
||||
const imageRef = image.getDisplayTag() || this.Image;
|
||||
if (!imageRef || imageRef.startsWith('<none>'))
|
||||
return { hasUpdate: false };
|
||||
return {
|
||||
hasUpdate: false
|
||||
};
|
||||
|
||||
const localArch = image.Architecture || 'amd64';
|
||||
const localOs = image.Os || 'linux';
|
||||
@@ -666,7 +756,8 @@ const Container = Model.base.extend({
|
||||
const remoteDigest = findArchDigest(manifest, localArch, localOs);
|
||||
|
||||
const repoDigests = image.RepoDigests || [];
|
||||
const hasUpdate = !!(remoteDigest && !repoDigests.some(rd => rd.includes(remoteDigest)));
|
||||
const hasUpdate = !!(remoteDigest && !repoDigests.some(rd => rd.includes(
|
||||
remoteDigest)));
|
||||
|
||||
return {
|
||||
hasUpdate,
|
||||
@@ -727,37 +818,58 @@ const Container = Model.base.extend({
|
||||
|
||||
if (wasRunning) {
|
||||
onProgress?.('→ ' + _('Stopping container') + '\n');
|
||||
try { await this.stop(); }
|
||||
catch (e) { throw new Error(_('Stop failed: %s').format(e.message || e)); }
|
||||
try {
|
||||
await this.stop();
|
||||
} catch (e) {
|
||||
throw new Error(_('Stop failed: %s').format(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
onProgress?.('→ ' + _('Removing container') + '\n');
|
||||
try { await this.remove(); }
|
||||
catch (e) { throw new Error(_('Remove failed: %s').format(e.message || e)); }
|
||||
try {
|
||||
await this.remove();
|
||||
} catch (e) {
|
||||
throw new Error(_('Remove failed: %s').format(e.message || e));
|
||||
}
|
||||
|
||||
onProgress?.('→ ' + _('Creating container') + '\n');
|
||||
let created;
|
||||
try { created = await ContainerRPC.create(spec); }
|
||||
catch (e) { throw new Error(_('Create failed: %s').format(e.message || e)); }
|
||||
try {
|
||||
created = await ContainerRPC.create(spec);
|
||||
} catch (e) {
|
||||
throw new Error(_('Create failed: %s').format(e.message || e));
|
||||
}
|
||||
if (!created || created.error)
|
||||
throw new Error(_('Create failed: %s').format(created?.error || _('Failed to create container')));
|
||||
throw new Error(_('Create failed: %s').format(created?.error || _(
|
||||
'Failed to create container')));
|
||||
|
||||
if (wasRunning) {
|
||||
onProgress?.('→ ' + _('Starting container') + '\n');
|
||||
try { await ContainerRPC.start(created.Id); }
|
||||
catch (e) { throw new Error(_('Start failed: %s').format(e.message || e)); }
|
||||
try {
|
||||
await ContainerRPC.start(created.Id);
|
||||
} catch (e) {
|
||||
throw new Error(_('Start failed: %s').format(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
onProgress?.('→ ' + _('Reinstating init script') + '\n');
|
||||
try { await this._reinstateInitScript(initStatus); }
|
||||
catch (e) { throw new Error(_('Init script reinstate failed: %s').format(e.message || e)); }
|
||||
try {
|
||||
await this._reinstateInitScript(initStatus);
|
||||
} catch (e) {
|
||||
throw new Error(_('Init script reinstate failed: %s').format(e.message || e));
|
||||
}
|
||||
|
||||
onProgress?.('✓ ' + _('Updated to %s').format((newImageId || '').substring(0, 12)) + '\n');
|
||||
return { oldImage: image };
|
||||
onProgress?.('✓ ' + _('Updated to %s').format((newImageId || '').substring(0, 12)) +
|
||||
'\n');
|
||||
return {
|
||||
oldImage: image
|
||||
};
|
||||
},
|
||||
|
||||
async getImage() {
|
||||
const image = Image.getSingleton({ Id: this.ImageID || this.Image });
|
||||
const image = Image.getSingleton({
|
||||
Id: this.ImageID || this.Image
|
||||
});
|
||||
return Image.getSingleton(await image.inspect());
|
||||
},
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
import { readfile, writefile, popen, stat, chmod, unlink, glob, access } from 'fs';
|
||||
import { cursor } from 'uci';
|
||||
import { urlencode, ENCODE_FULL } from 'lucihttp'; // ucode-lsp disable
|
||||
import { init_enabled, init_action } from 'luci.sys'; // ucode-lsp disable
|
||||
import * as podman_socket from 'luci.podman_socket'; // ucode-lsp disable
|
||||
import { API_BASE } from 'luci.podman_socket'; // ucode-lsp disable
|
||||
import {
|
||||
@@ -33,6 +32,9 @@ import {
|
||||
build_request, parse_status, parse_content_length, read_headers
|
||||
} from 'luci.podman_http'; // ucode-lsp disable
|
||||
|
||||
import { connect } from 'ubus';
|
||||
let ubus = connect();
|
||||
|
||||
// --- Configuration ---
|
||||
|
||||
const uci = cursor();
|
||||
@@ -897,14 +899,17 @@ const methods = {
|
||||
let err = require_param('name', req.args.name) || validate_name(req.args.name);
|
||||
if (err) return { error: err };
|
||||
|
||||
let script_path = init_script_path(req.args.name);
|
||||
let exists = !!stat(script_path);
|
||||
let enabled = false;
|
||||
|
||||
if (exists)
|
||||
enabled = init_enabled(`${INIT_SCRIPT_PREFIX}${req.args.name}`);
|
||||
|
||||
return { exists: exists, enabled: enabled };
|
||||
let name = `${INIT_SCRIPT_PREFIX}${req.args.name}`;
|
||||
return ubus.defer(
|
||||
'rc', 'list', { name: name },
|
||||
function (rc, reply) {
|
||||
if (reply[name] == null) {
|
||||
req.reply({ exists: false, enabled: false });
|
||||
} else {
|
||||
req.reply({ exists: true, enabled: reply[name].enabled });
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -918,12 +923,18 @@ const methods = {
|
||||
if (!stat(script_path))
|
||||
return { error: 'Init script not found. Generate it first.' };
|
||||
|
||||
let name = `${INIT_SCRIPT_PREFIX}${req.args.name}`;
|
||||
let action = (req.args.enabled === true || req.args.enabled === 1) ? 'enable' : 'disable';
|
||||
let rc = init_action(`${INIT_SCRIPT_PREFIX}${req.args.name}`, action);
|
||||
if (rc)
|
||||
return { error: `Failed to ${action} service` };
|
||||
|
||||
return { success: true, enabled: (action === 'enable') };
|
||||
return ubus.defer(
|
||||
'rc', 'init', { name: name, action: action },
|
||||
function (rc, reply) {
|
||||
if (rc == 0) {
|
||||
req.reply({ success: true, enabled: (action === 'enable')});
|
||||
} else {
|
||||
req.reply({ error: `Failed to ${action} service: ${reply}`});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -938,13 +949,22 @@ const methods = {
|
||||
return { success: true, message: 'Init script does not exist' };
|
||||
|
||||
// Disable before removing
|
||||
init_action(`${INIT_SCRIPT_PREFIX}${req.args.name}`, 'disable');
|
||||
unlink(script_path);
|
||||
|
||||
if (stat(script_path))
|
||||
return { error: 'Failed to remove init script' };
|
||||
|
||||
return { success: true };
|
||||
let name = `${INIT_SCRIPT_PREFIX}${req.args.name}`;
|
||||
return ubus.call(
|
||||
'rc', 'init', { name: name, action: 'disable' },
|
||||
function (rc, reply) {
|
||||
if (rc == 0) {
|
||||
unlink(script_path);
|
||||
if (stat(script_path)) {
|
||||
req.reply({ error: 'failed to remove init script' });
|
||||
} else {
|
||||
req.reply({ success: true });
|
||||
}
|
||||
} else {
|
||||
req.reply({ error: `Failed to disable service: ${reply}` });
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -678,7 +678,8 @@ function getDisplayTxPower(radioNet) {
|
||||
if (isPlausibleTxPowerValue(info != null ? info.txpower : null, hwtype))
|
||||
return info.txpower;
|
||||
|
||||
if (isPlausibleTxPowerValue(cfgvalue, hwtype))
|
||||
// mt_dbdc configures power as a percentage, not dBm.
|
||||
if (hwtype != 'mt_dbdc' && isPlausibleTxPowerValue(cfgvalue, hwtype))
|
||||
return cfgvalue;
|
||||
|
||||
return null;
|
||||
@@ -1404,7 +1405,9 @@ function getDisplaySignalPercent(radioNet, hwtype, is_assoc, disabled) {
|
||||
}
|
||||
|
||||
function getDisplaySignalValue(radioNet, hwtype, is_assoc) {
|
||||
if ((hwtype == 'mt_dbdc' || (isQcaWifiHwtype(hwtype) && radioNet.getMode() == 'ap')) && is_assoc)
|
||||
if (hwtype == 'mt_dbdc' && radioNet.getMode() == 'ap')
|
||||
return is_assoc ? getDisplayTxPower(radioNet) : null;
|
||||
if (isQcaWifiHwtype(hwtype) && radioNet.getMode() == 'ap' && is_assoc)
|
||||
return getDisplayTxPower(radioNet) ?? 30;
|
||||
|
||||
return radioNet.getSignal();
|
||||
@@ -1437,7 +1440,7 @@ function renderStatusRow(pairs, className) {
|
||||
return added ? row : null;
|
||||
}
|
||||
|
||||
function render_signal_badge(signalPercent, signalValue, noiseValue, wrap, mode) {
|
||||
function render_signal_badge(signalPercent, signalValue, noiseValue, wrap, mode, txpower = false) {
|
||||
let icon = L.resource('icons/signal-075-100.svg'), title, value;
|
||||
|
||||
switch(true) {
|
||||
@@ -1459,13 +1462,13 @@ function render_signal_badge(signalPercent, signalValue, noiseValue, wrap, mode)
|
||||
}
|
||||
else {
|
||||
value = `${signalValue}\xa0${_('dBm')}`;
|
||||
title = `${_('Signal')} ${signalValue} ${_('dBm')}`;
|
||||
title = `${txpower ? _('Tx-Power') : _('Signal')} ${signalValue} ${_('dBm')}`;
|
||||
}
|
||||
}
|
||||
else if (signalPercent > -1) {
|
||||
switch (mode) {
|
||||
case 'ap':
|
||||
title = _('No client associated');
|
||||
title = txpower ? _('Tx-Power') : _('No client associated');
|
||||
break;
|
||||
|
||||
case 'sta':
|
||||
@@ -1516,7 +1519,8 @@ function render_network_badge(radioNet) {
|
||||
return render_signal_badge(
|
||||
getDisplaySignalPercent(radioNet, hwtype, is_assoc, disabled),
|
||||
getDisplaySignalValue(radioNet, hwtype, is_assoc),
|
||||
getDisplayNoiseValue(radioNet, hwtype, is_assoc), false, radioNet.getMode());
|
||||
getDisplayNoiseValue(radioNet, hwtype, is_assoc), false, radioNet.getMode(),
|
||||
hwtype == 'mt_dbdc' && radioNet.getMode() == 'ap');
|
||||
}
|
||||
|
||||
function render_radio_status(radioDev, wifiNets) {
|
||||
@@ -1591,7 +1595,8 @@ function render_modal_status(node, radioNet) {
|
||||
|
||||
dom.content(node.firstElementChild, render_signal_badge(
|
||||
getDisplaySignalPercent(radioNet, hwtype, is_assoc, disabled),
|
||||
getDisplaySignalValue(radioNet, hwtype, is_assoc), noise, true, radioNet.getMode()));
|
||||
getDisplaySignalValue(radioNet, hwtype, is_assoc), noise, true, radioNet.getMode(),
|
||||
hwtype == 'mt_dbdc' && radioNet.getMode() == 'ap'));
|
||||
|
||||
L.itemlist(node.lastElementChild, [
|
||||
_('Mode'), mode,
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ MISE_HASH_x86_64:=3832f39c325e343f81fe3d92b2447c5d1a5eea1bc85092bb7b6c2580622264
|
||||
MISE_HASH_aarch64:=06186cfbfe947049b21d58575fb0ea800cc26ed1375f20f4b678cb3a9d679437
|
||||
|
||||
PKG_NAME:=mise
|
||||
PKG_VERSION:=2026.10.12
|
||||
PKG_RELEASE:=36
|
||||
PKG_VERSION:=2026.10.13
|
||||
PKG_RELEASE:=37
|
||||
PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION)-linux-$(MISE_ARCH)-musl.tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/jdx/mise/releases/download/v$(PKG_VERSION)/
|
||||
PKG_HASH:=skip
|
||||
|
||||
+2
-2
@@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=natflow
|
||||
PKG_VERSION:=20260930
|
||||
PKG_RELEASE:=94
|
||||
PKG_RELEASE:=95
|
||||
|
||||
PKG_SOURCE:=$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=68cc4c87a23a1afbdb194bd3d3f9bb64d767f6ba
|
||||
PKG_SOURCE_VERSION:=51496417511f8dc4ebef2618206db11ddedd7773
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
+3
-3
@@ -50,12 +50,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wwand
|
||||
PKG_VERSION:=1.7.0_pre33
|
||||
PKG_RELEASE:=79
|
||||
PKG_VERSION:=1.8.0_pre3
|
||||
PKG_RELEASE:=80
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/ddimension/wwand.git
|
||||
PKG_SOURCE_VERSION:=5281731de7f5465552a9bba1b909b082b3050fae
|
||||
PKG_SOURCE_VERSION:=8a170a136d1e1340ef54da2006edc8b622a87e43
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=Xray-core
|
||||
PKG_VERSION:=26.10.10
|
||||
PKG_RELEASE:=25
|
||||
PKG_VERSION:=26.10.17
|
||||
PKG_RELEASE:=26
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)?
|
||||
|
||||
Reference in new issue
Block a user