normalizeTag/sigmoid/clamp 等工具函数 — JM Shelf 推荐脚本的模块库,通过 @require 被主脚本引用。
Acest script nu ar trebui instalat direct. Aceasta este o bibliotecă pentru alte scripturi care este inclusă prin directiva meta a // @require https://update.sleazyfork.org/scripts/581099/1842598/JM%20Shelf%20-%20Utils.js
// ==UserScript==
// @name JM Shelf - Utils
// @namespace jmshelf-lib
// @version 1.0.0
// @author Kesdi
// @description normalizeTag/sigmoid/clamp 等工具函数 — JM Shelf 推荐脚本的模块库,通过 @require 被主脚本引用。
// @license MIT
// ==/UserScript==
//
// 此文件是 GreasyFork 库(library),不直接安装。
// 请安装主脚本: JM Shelf 给杂鱼的个性化推荐
//
// ═══ [2] UTILS ═══
function normalizeTag(t) {
const _ntCache = normalizeTag._cache || (normalizeTag._cache = {});
if (!t) return t;
// 逐字转换 (TAG_NORMALIZE, ~490常用字)
let result = '';
let hadHit = false, hadMiss = false;
for (const ch of t) {
const v = TAG_NORMALIZE[ch];
if (v !== undefined) { result += v; hadHit = true; }
else { result += ch; hadMiss = true; }
}
// 如果有未命中且OpenCC可用, 提交异步转换缓存
if (hadMiss && _occ) {
if (_ocCache[t] === undefined) {
_ocCache[t] = result; // placeholder, 本次返回逐字结果
Promise.resolve(_occ(t)).then(r => { _ocCache[t] = r; }).catch(() => {});
} else if (_ocCache[t] !== result) {
return _ocCache[t]; // 缓存已就绪
}
}
_ntCache[t] = result;
return result.toLowerCase();
}
function normalizeTags(arr) { return [...new Set((arr || []).map(t => normalizeTag(t)))]; }
function sleep(ms) {
return new Promise(r => setTimeout(r, ms));
}
function clamp(v, lo, hi) { return Math.max(lo, Math.min(hi, v)); }
function sigmoid(x, center, steep) { return 1 / (1 + Math.exp(-steep * (x - center))); }
function parseViewCount(str) {
str = str.replace(/,/g, '').trim();
if (str.endsWith('K')) return Math.round(parseFloat(str) * 1000);
if (str.endsWith('M')) return Math.round(parseFloat(str) * 1000000);
if (str.endsWith('B')) return Math.round(parseFloat(str) * 1000000000);
return parseInt(str, 10) || 0;
}
// Migrate blacklist sets from JSON
// (Sets don't survive JSON.stringify, so we store arrays)
function getBlacklist() {
const raw = Storage.get('blacklist');
if (!raw) return { tags: [], albums: [] };
return raw;
}
function setBlacklist(b) {
Storage.set('blacklist', { tags: b.tags, albums: b.albums });
}