feat: M6.44+M6.45 现场补全 — 补齐按扩展名过滤遗漏的 web 前端与 license 合规件

真机 0.8.45 现场组成补全(初次提现场按扩展名过滤漏掉 7 个文本文件),
内容逐字节取自容器现场 /mnt/mb/home/Aska/Project/R3ProII 并 md5 对拍一致:

- patch_v2/meowpanel/web/meowpanel.css          (+17)  趋势/App 详情卡样式
- patch_v2/meowpanel/web/mp_pages.js            (+289) 性能趋势/功耗曲线/App 详情/蓝牙详情
- patch_v2/meowpanel/web/mp_shared.js           (+49)  趋势 sparkline 通用逻辑
- patch_v2/reader_app/.gitignore                (+2)   seg/chapter smoke host
- patch_v2/reader_app/NOTICE                    (+23)  FreeType 2.14.3 + zlib 条目
- patch_v2/reader_app/resources/licenses/NOTICE (+23)  同 reader_app/NOTICE(md5 一致)
- patch_v2/reader_app/resources/licenses/FTL.txt (新增 6743B) FreeType 许可证全文

面板前端对应已收编的后端 mp_files.c/mp_net.c(文件搜索+蓝牙详情),
NOTICE/FTL.txt 为 LGPL/FreeType 合规产物。仅投运现场内容,未改内容。
This commit is contained in:
AskaEth committed 2026-11-04 20:10:42 +08:00
1 parent 2ffb92c038
commit 20f4727714
7 files changed
+551 -23

No files matched your search

+48 -1
View File
@@ -99,6 +99,53 @@
if (arr.length > SPARK_MAX) arr.shift();
}
/* ---- F1-① 性能趋势(FUTURE_MEOWPANEL §2.1):pushSpark 模式泛化到任意 0..100 归一值 ---- */
const trendCpu = [], trendMem = [], trendLoad = [], trendTemp = [];
function pushTrend(arr, v) { // 0..100 归一值入队(<=SPARK_MAX 点);null/NaN 不入队(诚实空缺)
if (v == null || isNaN(v)) return;
arr.push(Math.max(0, Math.min(100, Number(v))));
if (arr.length > SPARK_MAX) arr.shift();
}
function resetTrend() { trendCpu.length = 0; trendMem.length = 0; trendLoad.length = 0; trendTemp.length = 0; }
/* series: [{cls,arr}],cls 决定颜色(CSS .trend-cpu/.trend-mem/.trend-load/.trend-temp),
* 位置稳定(首页 3 序列、perf 页 4 序列共用同一语义色,不靠序号猜色)。 */
function trendSvgHtml(series) {
let polys = '';
series.forEach(function (s) {
polys += '<polyline class="' + s.cls + '" points="" fill="none" stroke-width="1.6" vector-effect="non-scaling-stroke"/>';
});
return '<svg class="lvl-spark trend-spark" viewBox="0 0 100 46" preserveAspectRatio="none" aria-hidden="true">' +
'<line class="grid" x1="0" y1="46" x2="100" y2="46"/>' +
'<line class="grid" x1="0" y1="23" x2="100" y2="23"/>' + polys + '</svg>';
}
function drawTrendSpark(rootEl, series) {
const svg = rootEl && rootEl.querySelector('.trend-spark');
if (!svg) return;
series.forEach(function (s) {
const p = svg.querySelector('.' + s.cls);
if (p) p.setAttribute('points', sparklinePoints(s.arr));
});
}
/* 通用折线点串(任意长度数组,值 0..100 归一;null 跳过):x 铺满 w,y 反向映射 h 内(F1-② 功耗 4h 曲线用) */
function polylinePoints(vals, w, h) {
const n = vals.length;
if (!n) return '';
const out = [];
for (let i = 0; i < n; i++) {
const v = vals[i];
if (v == null || isNaN(v)) continue;
const x = n > 1 ? (i / (n - 1)) * w : w / 2;
const y = h - 2 - Math.max(0, Math.min(100, v)) / 100 * (h - 4);
out.push(x.toFixed(1) + ',' + y.toFixed(1));
}
return out.join(' ');
}
function drawSpark(rootEl) {
const svg = rootEl && rootEl.querySelector('.lvl-spark');
if (!svg) return;
@@ -463,5 +510,5 @@
});
}
Object.assign(MP, { $, $$, LOG_GROUP_NAME, SPARK_MAX, api, apiDownload, applyTheme, authMode, authRequired, barHtml, bindLogin, bindPwDlg, bindSlider, bindThemeUi, browserMode, confirmDlg, dbPct, dbg, dbgErr, debounce, deciToDb, devStyleLabel, devThemeLabel, doLogin, drawSpark, emptyState, errText, esc, fmtBytes, fmtDb, fmtTime, fmtUptime, hideLogin, homeCard, homeKv, homeUnavailable, initTheme, isAvail, levelMeterHtml, loginErr, modePill, passwordDlg, pct, pushSpark, refreshAuthGate, resetSpark, resolveMode, resolveStyle, saveSetting, setConn, showLogin, slur, sparkPeak, sparkRms, sparklineHtml, sparklinePoints, stat, state, storageDel, storageGet, storageSet, storedMode, storedStyle, toast, toastTimer, updateLevelMeter, volTimer });
Object.assign(MP, { $, $$, LOG_GROUP_NAME, SPARK_MAX, api, apiDownload, applyTheme, authMode, authRequired, barHtml, bindLogin, bindPwDlg, bindSlider, bindThemeUi, browserMode, confirmDlg, dbPct, dbg, dbgErr, debounce, deciToDb, devStyleLabel, devThemeLabel, doLogin, drawSpark, drawTrendSpark, emptyState, errText, esc, fmtBytes, fmtDb, fmtTime, fmtUptime, hideLogin, homeCard, homeKv, homeUnavailable, initTheme, isAvail, levelMeterHtml, loginErr, modePill, passwordDlg, pct, polylinePoints, pushSpark, pushTrend, refreshAuthGate, resetSpark, resetTrend, resolveMode, resolveStyle, saveSetting, setConn, showLogin, slur, sparkPeak, sparkRms, sparklineHtml, sparklinePoints, stat, state, storageDel, storageGet, storageSet, storedMode, storedStyle, toast, toastTimer, trendCpu, trendLoad, trendMem, trendSvgHtml, trendTemp, updateLevelMeter, volTimer });
})();