/** * YueTong 专用节点清理脚本 * 负责去掉“悦·”品牌前缀、钻石、专属/家宽等线路标识,以及压短 AI 解锁文案。 * 按地区稳定归并后重新连续编号,避免专属/普通节点撞号。 */ // noinspection JSUnusedGlobalSymbols const COMMON_SCRIPT_URL = 'https://git.orionc.me/orion/script/raw/branch/main/substore/common.js'; async function loadRenameUtils() { if (typeof globalThis !== 'undefined' && globalThis.SubStoreRenameUtils) { return globalThis.SubStoreRenameUtils; } const cache = typeof scriptResourceCache !== 'undefined' ? scriptResourceCache : null; let script = cache && cache.get(COMMON_SCRIPT_URL); if (!script) { const response = await $substore.http.get({ url: COMMON_SCRIPT_URL }); script = response && (response.body || response.data || response); if (cache) cache.set(COMMON_SCRIPT_URL, script); } new Function(String(script))(); return globalThis.SubStoreRenameUtils; } async function operator(proxies) { const utils = await loadRenameUtils(); const regionAliases = [ ['Hong Kong', 'HK'], ['香港', 'HK'], ['HK', 'HK'], ['Japan', 'JP'], ['日本', 'JP'], ['JP', 'JP'], ['Singapore', 'SG'], ['新加坡', 'SG'], ['狮城', 'SG'], ['SG', 'SG'], ['Taiwan', 'TW'], ['台湾', 'TW'], ['台灣', 'TW'], ['TW', 'TW'], ['United States', 'US'], ['America', 'US'], ['USA', 'US'], ['美国', 'US'], ['美國', 'US'], ['美西', 'US'], ['美东', 'US'], ['美東', 'US'], ['US', 'US'], ['Korea', 'KR'], ['韩国', 'KR'], ['韓國', 'KR'], ['KR', 'KR'], ['United Kingdom', 'UK'], ['Britain', 'UK'], ['英国', 'UK'], ['英國', 'UK'], ['UK', 'UK'], ['Germany', 'DE'], ['德国', 'DE'], ['德國', 'DE'], ['DE', 'DE'], ['Netherlands', 'NL'], ['荷兰', 'NL'], ['荷蘭', 'NL'], ['NL', 'NL'] ]; const { regionCodeOf } = utils.createRegionResolver(regionAliases); const withFreshRegionSequence = (name, sequenceNumber) => { const { flag, text } = utils.splitLeadingFlag(name); const sequenceText = String(sequenceNumber); let core = text.trim(); let feature = ''; core = core.replace(/\s*AI\s*\d+(?!\d)(?!\s*(?:[xX倍]|\.\d))/, () => { feature = 'AI'; return ''; }); if (!feature) { core = core.replace(/\s+AI\b|AI$/, () => { feature = 'AI'; return ''; }); } core = core .replace(/\s*\d+(?!\d)(?!\s*(?:[xX倍]|\.\d))(?=\s|$)/, '') .replace(/\s{2,}/g, ' '); return utils.normalizeWhitespace(`${flag}${core}${sequenceText}${feature ? ` ${feature}` : ''}`); }; const normalizedItems = proxies.map((proxy, originalIndex) => { if (typeof proxy.name !== 'string') { return { proxy, originalIndex, regionCode: '' }; } proxy.name = proxy.name .replace(/悦[·・]\s*/g, '') .replace(/AI解锁/g, 'AI') .replace(/\s*(?:专属|家宽|高速|专线)(?:\s*(\d+)(?!\s*(?:[xX倍]|\.\d)))?/g, '$1') .replace(/💎/gu, '') .replace(/([\u4e00-\u9fff])AI\b/g, '$1 AI') .replace(/\s{2,}/g, ' '); proxy.name = utils.normalizeWhitespace(proxy.name); return { proxy, originalIndex, regionCode: regionCodeOf(proxy.name) }; }); const regionOrder = Object.create(null); const groupOrder = normalizedItems.map(item => { if (!item.regionCode) return item.originalIndex; if (regionOrder[item.regionCode] === undefined) { regionOrder[item.regionCode] = item.originalIndex; } return regionOrder[item.regionCode]; }); normalizedItems.sort((firstItem, secondItem) => { const firstGroupOrder = groupOrder[firstItem.originalIndex]; const secondGroupOrder = groupOrder[secondItem.originalIndex]; if (firstGroupOrder !== secondGroupOrder) return firstGroupOrder - secondGroupOrder; return firstItem.originalIndex - secondItem.originalIndex; }); const regionCount = Object.create(null); return normalizedItems.map(item => { if (!item.regionCode) return item.proxy; regionCount[item.regionCode] = (regionCount[item.regionCode] || 0) + 1; item.proxy.name = withFreshRegionSequence(item.proxy.name, regionCount[item.regionCode]); return item.proxy; }); }