diff --git a/聆澜/Koneko_聆澜_GIT音源_v0.1.3_QZv2.js b/聆澜/Koneko_聆澜_GIT音源_v0.1.4_QZv2.js similarity index 92% rename from 聆澜/Koneko_聆澜_GIT音源_v0.1.3_QZv2.js rename to 聆澜/Koneko_聆澜_GIT音源_v0.1.4_QZv2.js index aaf4b52..85bad4b 100644 --- a/聆澜/Koneko_聆澜_GIT音源_v0.1.3_QZv2.js +++ b/聆澜/Koneko_聆澜_GIT音源_v0.1.4_QZv2.js @@ -232,14 +232,11 @@ var pluginInfo = { info: { id: 'koneko_ceru_git', name: 'GIT音源 - Koneko 聆澜', - version: '0.1.3', + version: '0.1.4', source: 'git', description: 'GIT音源,基于 GitCode audio_database.json 本地搜索 + Ceru 播放接口' }, - ext: [ - { type: 'button', name: '激活付费', description: '点击激活付费模式(需先在环境变量填入 ceru_key)', entry: 'activatePremium' }, - { type: 'button', name: '公益模式', description: '切换到公益模式(不使用 API Key)', entry: 'activatePublic' } - ], + ext: [], env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜付费密钥。留空=公益模式(仅128k);填写=付费模式(高音质)。修改后下次播放自动生效,也可点扩展按钮激活' }], quality: [ { name: '标准音质', ui: '标', id: '128k' }, @@ -251,17 +248,6 @@ var pluginInfo = { supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric'] } -// ===== 激活/切换模式 ===== -function activatePremium() { - var envNow = global.env || {}; - if (!envNow.ceru_key) return Promise.reject(new Error('请先在环境变量中填写 ceru_key')); - return Promise.resolve({ success: true, message: '付费模式已激活,下次播放将使用高音质' }); -} - -function activatePublic() { - return Promise.resolve({ success: true, message: '已切换到公益模式' }); -} - module.exports = { musicSearch: { search: search }, tipSearch: { search: tipSearch }, @@ -275,7 +261,5 @@ module.exports = { getUrl: getUrl, musicDetail: musicDetail, musicInfo: musicInfo, - activatePremium: activatePremium, - activatePublic: activatePublic, pluginInfo: pluginInfo }; diff --git a/聆澜/Koneko_聆澜_QQ音乐_v0.1.3_QZv2.js b/聆澜/Koneko_聆澜_QQ音乐_v0.1.4_QZv2.js similarity index 77% rename from 聆澜/Koneko_聆澜_QQ音乐_v0.1.3_QZv2.js rename to 聆澜/Koneko_聆澜_QQ音乐_v0.1.4_QZv2.js index 4a106b2..fd23cc2 100644 --- a/聆澜/Koneko_聆澜_QQ音乐_v0.1.3_QZv2.js +++ b/聆澜/Koneko_聆澜_QQ音乐_v0.1.4_QZv2.js @@ -128,6 +128,41 @@ function signRequest(data) { }, JSON.stringify(data)); } +// ===== 批量音质信息 ===== +function getBatchMusicQualityInfo(songList) { + var songIds = songList.map(function(item) { return item.id; }); + var body = { + comm: { ct: '19', cv: '1859', uin: '0' }, + req: { + module: 'music.trackInfo.UniformRuleCtrl', + method: 'CgiGetTrackInfo', + param: { types: songIds.map(function(){ return 1; }), ids: songIds, ctx: 0 } + } + }; + return requestUrl('https://u.y.qq.com/cgi-bin/musicu.fcg', 'POST', { + 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)', + 'Content-Type': 'application/json' + }, JSON.stringify(body)).then(function(res) { + if (!res.body || res.body.code !== 0) return {}; + var qualityInfoMap = {}; + var tracks = (res.body.req && res.body.req.data && res.body.req.data.tracks) ? res.body.req.data.tracks : []; + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + var file = track.file || {}; + var qualities = {}; + if (file.size_128mp3) qualities['128k'] = sizeFormate(file.size_128mp3); + if (file.size_320mp3) qualities['320k'] = sizeFormate(file.size_320mp3); + if (file.size_flac) qualities['flac'] = sizeFormate(file.size_flac); + if (file.size_hires) qualities['hires'] = sizeFormate(file.size_hires); + if (file.size_new && file.size_new[0]) qualities['master'] = sizeFormate(file.size_new[0]); + if (file.size_new && file.size_new[1]) qualities['atmos'] = sizeFormate(file.size_new[1]); + if (file.size_new && file.size_new[2]) qualities['atmos_plus'] = sizeFormate(file.size_new[2]); + qualityInfoMap[track.id] = { qualities: qualities }; + } + return qualityInfoMap; + }).catch(function() { return {}; }); +} + // ===== 搜索实现 ===== function musicSearch(str, page, limit) { var body = { @@ -141,38 +176,33 @@ function musicSearch(str, page, limit) { } function handleSearchResult(rawList) { - var list = []; - if (!rawList) return list; - for (var i = 0; i < rawList.length; i++) { - var item = rawList[i]; - if (!item.file || !item.file.media_mid) continue; - var qualities = {}; - var file = item.file; - if (file.size_128mp3 !== 0) qualities['128k'] = sizeFormate(file.size_128mp3); - if (file.size_320mp3 !== 0) qualities['320k'] = sizeFormate(file.size_320mp3); - if (file.size_flac !== 0) qualities['flac'] = sizeFormate(file.size_flac); - var albumId = ''; - var albumName = ''; - if (item.album) { albumName = item.album.name; albumId = item.album.mid; } - var singerName = formatSingerName(item.singer, 'name'); - var picUrl = albumId && albumId !== '空' - ? 'https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg' - : (item.singer && item.singer.length ? 'https://y.gtimg.cn/music/photo_new/T001R500x500M000' + item.singer[0].mid + '.jpg' : ''); - list.push({ - id: String(item.mid), - name: item.name + (item.title_extra || ''), - artists: singerName, - source: 'tx', - pic: picUrl, - mPic: picUrl, - sPic: picUrl, - albumName: albumName, - albumId: String(albumId || ''), - interval: String(formatPlayTime(item.interval) || '--/--'), - qualities: qualities - }); - } - return list; + if (!rawList || rawList.length === 0) return Promise.resolve([]); + return getBatchMusicQualityInfo(rawList).then(function(qualityInfoMap) { + var list = []; + for (var i = 0; i < rawList.length; i++) { + var item = rawList[i]; + if (!item.file || !item.file.media_mid) continue; + var albumId = ''; + var albumName = ''; + if (item.album) { albumName = item.album.name; albumId = item.album.mid; } + var picUrl = (albumId === '' || albumId === '空') + ? (item.singer && item.singer.length ? 'https://y.gtimg.cn/music/photo_new/T001R500x500M000' + item.singer[0].mid + '.jpg' : '') + : 'https://y.gtimg.cn/music/photo_new/T002R500x500M000' + albumId + '.jpg'; + var qInfo = qualityInfoMap[item.id] || {}; + list.push({ + id: String(item.mid), + name: item.name + (item.title_extra || ''), + artists: formatSingerName(item.singer, 'name'), + source: 'tx', + pic: picUrl, mPic: picUrl, sPic: picUrl, + albumName: albumName, + albumId: String(albumId || ''), + interval: String(formatPlayTime(item.interval) || '--/--'), + qualities: qInfo.qualities || {} + }); + } + return list; + }); } function search(str, page, limit, retryNum) { @@ -181,10 +211,11 @@ function search(str, page, limit, retryNum) { if (!limit) limit = 30; return musicSearch(str, page, limit).then(function(data) { if (!data || !data.body || !data.body.item_song) return search(str, page, limit, retryNum); - var list = handleSearchResult(data.body.item_song); - var meta = data.meta || {}; - var total = meta.estimate_sum || 0; - return { list: list, allPage: Math.ceil(total / limit), limit: limit, total: total, source: 'tx' }; + return handleSearchResult(data.body.item_song).then(function(list) { + var meta = data.meta || {}; + var total = meta.estimate_sum || 0; + return { list: list, allPage: Math.ceil(total / limit), limit: limit, total: total, source: 'tx' }; + }); }); } @@ -269,7 +300,7 @@ function musicInfo(songmid) { return musicDetail(songmid); } function hotSearch() { var data = { comm: { ct: '19', cv: '1803', guid: '0', patch: '118', psrf_access_token_expiresAt: 0, psrf_qqaccess_token: '', psrf_qqopenid: '', psrf_qqunionid: '', tmeAppID: 'qqmusic', tmeLoginType: 0, uin: '0', wid: '0' }, - hotkey: { method: 'GetHotkeyForQQMusicPC', module: 'tencent_musicsoso_hotkey.HotkeyService', param: { search_id: '', uin: 0 } } + hotkey: { method: 'GetHotkeyForQQMusicMobile', module: 'tencent_musicsoso_hotkey.HotkeyService', param: { search_id: '', uin: 0 } } }; return requestUrl('https://u.y.qq.com/cgi-bin/musicu.fcg', 'POST', { 'User-Agent': 'Mozilla/5.0 (Linux; Android 10)', @@ -315,36 +346,24 @@ var pluginInfo = { info: { id: 'koneko_ceru_tx', name: 'QQ音乐 - Koneko 聆澜', - version: '0.1.3', + version: '0.1.4', source: 'tx', description: 'QQ音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口' }, - ext: [ - { type: 'button', name: '激活付费', description: '点击激活付费模式(需先在环境变量填入 ceru_key)', entry: 'activatePremium' }, - { type: 'button', name: '公益模式', description: '切换到公益模式(不使用 API Key)', entry: 'activatePublic' } - ], + ext: [], env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜付费密钥。留空=公益模式(仅128k);填写=付费模式(高音质)。修改后下次播放自动生效,也可点扩展按钮激活' }], quality: [ { name: '标准音质', ui: '标', id: '128k' }, { name: '高品音质', ui: 'HQ', id: '320k' }, { name: '无损音质', ui: 'SQ', id: 'flac' }, { name: '高解析度无损(Hi-Res)', ui: 'HR', id: 'hires' }, - { name: '至臻母带', ui: 'MT', id: 'master' } + { name: '至臻母带', ui: 'MT', id: 'master' }, + { name: '全景声', ui: 'AT', id: 'atmos' }, + { name: '全景声+', ui: 'AT+', id: 'atmos_plus' } ], supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric'] } -// ===== 激活/切换模式 ===== -function activatePremium() { - var envNow = global.env || {}; - if (!envNow.ceru_key) return Promise.reject(new Error('请先在环境变量中填写 ceru_key')); - return Promise.resolve({ success: true, message: '付费模式已激活,下次播放将使用高音质' }); -} - -function activatePublic() { - return Promise.resolve({ success: true, message: '已切换到公益模式' }); -} - module.exports = { musicSearch: { search: search }, tipSearch: { search: tipSearch }, @@ -358,7 +377,5 @@ module.exports = { getUrl: getUrl, musicDetail: musicDetail, musicInfo: musicInfo, - activatePremium: activatePremium, - activatePublic: activatePublic, pluginInfo: pluginInfo }; diff --git a/聆澜/Koneko_聆澜_咪咕音乐_v0.1.3_QZv2.js b/聆澜/Koneko_聆澜_咪咕音乐_v0.1.4_QZv2.js similarity index 91% rename from 聆澜/Koneko_聆澜_咪咕音乐_v0.1.3_QZv2.js rename to 聆澜/Koneko_聆澜_咪咕音乐_v0.1.4_QZv2.js index f38d77a..3835ee0 100644 --- a/聆澜/Koneko_聆澜_咪咕音乐_v0.1.3_QZv2.js +++ b/聆澜/Koneko_聆澜_咪咕音乐_v0.1.4_QZv2.js @@ -200,14 +200,11 @@ var pluginInfo = { info: { id: 'koneko_ceru_mg', name: '咪咕音乐 - Koneko 聆澜', - version: '0.1.3', + version: '0.1.4', source: 'mg', description: '咪咕音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口' }, - ext: [ - { type: 'button', name: '激活付费', description: '点击激活付费模式(需先在环境变量填入 ceru_key)', entry: 'activatePremium' }, - { type: 'button', name: '公益模式', description: '切换到公益模式(不使用 API Key)', entry: 'activatePublic' } - ], + ext: [], env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜付费密钥。留空=公益模式(仅128k);填写=付费模式(高音质)。修改后下次播放自动生效,也可点扩展按钮激活' }], quality: [ { name: '标准音质', ui: '标', id: '128k' }, @@ -219,17 +216,6 @@ var pluginInfo = { supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric'] } -// ===== 激活/切换模式 ===== -function activatePremium() { - var envNow = global.env || {}; - if (!envNow.ceru_key) return Promise.reject(new Error('请先在环境变量中填写 ceru_key')); - return Promise.resolve({ success: true, message: '付费模式已激活,下次播放将使用高音质' }); -} - -function activatePublic() { - return Promise.resolve({ success: true, message: '已切换到公益模式' }); -} - module.exports = { musicSearch: { search: search }, tipSearch: { search: tipSearch }, @@ -243,7 +229,5 @@ module.exports = { getUrl: getUrl, musicDetail: musicDetail, musicInfo: musicInfo, - activatePremium: activatePremium, - activatePublic: activatePublic, pluginInfo: pluginInfo }; diff --git a/聆澜/Koneko_聆澜_网易云音乐_v0.1.3_QZv2.js b/聆澜/Koneko_聆澜_网易云音乐_v0.1.4_QZv2.js similarity index 93% rename from 聆澜/Koneko_聆澜_网易云音乐_v0.1.3_QZv2.js rename to 聆澜/Koneko_聆澜_网易云音乐_v0.1.4_QZv2.js index 6667540..43841fb 100644 --- a/聆澜/Koneko_聆澜_网易云音乐_v0.1.3_QZv2.js +++ b/聆澜/Koneko_聆澜_网易云音乐_v0.1.4_QZv2.js @@ -141,22 +141,14 @@ function formatPlayCount(count) { return String(count); } -// ===== 搜索实现 ===== +// ===== 搜索实现(使用老式搜索API,无需weapi加密) ===== function musicSearch(str, page, limit) { - var form = weapi({ - s: str, - type: 1, - limit: limit, - offset: limit * (page - 1), - total: page == 1 - }); - return requestUrl('https://music.163.com/weapi/cloudsearch/get/web', 'POST', { + var url = 'https://music.163.com/api/search/get/web?s=' + encodeURIComponent(str) + '&type=1&offset=' + (limit * (page - 1)) + '&total=true&limit=' + limit; + return requestUrl(url, 'GET', { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36', - 'Origin': 'https://music.163.com', 'Referer': 'https://music.163.com', - 'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': WY_COOKIE - }, querystring.stringify(form)).then(function(res) { + }).then(function(res) { if (typeof res.body === 'string') { try { res.body = JSON.parse(res.body); } catch (e) { return null; } } @@ -174,18 +166,22 @@ function handleSearchResult(rawList) { if (item.h && item.h.size) qualities['320k'] = sizeFormate(item.h.size); if (item.sq && item.sq.size) qualities['flac'] = sizeFormate(item.sq.size); if (item.hr && item.hr.size) qualities['hires'] = sizeFormate(item.hr.size); - var picUrl = item.al && item.al.picUrl ? item.al.picUrl : ''; + var picUrl = item.album && item.album.picUrl ? item.album.picUrl : ''; + var singerName = ''; + if (item.artists && item.artists.length) { + var ns = []; + for (var j = 0; j < item.artists.length; j++) ns.push(item.artists[j].name); + singerName = ns.join('、'); + } list.push({ id: String(item.id), name: item.name || '', - artists: formatSingerName(item.ar, 'name'), + artists: singerName, source: 'wy', - pic: picUrl, - mPic: picUrl, - sPic: picUrl, - albumName: item.al && item.al.name ? item.al.name : '', - albumId: String(item.al && item.al.id ? item.al.id : ''), - interval: String(formatPlayTime((item.dt || 0) / 1000) || '--/--'), + pic: picUrl, mPic: picUrl, sPic: picUrl, + albumName: item.album && item.album.name ? item.album.name : '', + albumId: String(item.album && item.album.id ? item.album.id : ''), + interval: String(formatPlayTime((item.duration || 0) / 1000) || '--/--'), qualities: qualities }); } @@ -202,13 +198,7 @@ function search(str, page, limit, retryNum) { var list = handleSearchResult(songs); if (!list || list.length === 0) return search(str, page, limit, retryNum); var total = result.result && result.result.songCount ? result.result.songCount : 0; - return { - list: list, - allPage: Math.ceil(total / limit), - limit: limit, - total: total, - source: 'wy' - }; + return { list: list, allPage: Math.ceil(total / limit), limit: limit, total: total, source: 'wy' }; }); } @@ -629,16 +619,11 @@ var pluginInfo = { info: { id: 'koneko_ceru_wy', name: '网易云音乐 - Koneko 聆澜', - version: '0.1.3', + version: '0.1.4', source: 'wy', description: '网易云音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口' }, - ext: [ - { type: 'homePage', url: 'https://music.163.com/', name: '网易云音乐主页', description: '网易云音乐主页', entry: '' }, - { type: 'share', url: 'https://music.163.com/song/media/outer/url?id={id}.mp3', name: '外链分享', description: '外链分享', entry: '' }, - { type: 'button', name: '激活付费', description: '点击激活付费模式(需先在环境变量填入 ceru_key)', entry: 'activatePremium' }, - { type: 'button', name: '公益模式', description: '切换到公益模式(不使用 API Key)', entry: 'activatePublic' } - ], + ext: [], env: [ { key: 'ceru_key', name: 'Ceru API Key', description: '聆澜付费密钥。留空=公益模式(仅128k);填写=付费模式(高音质)。修改后下次播放自动生效,也可点扩展按钮激活' }, { key: 'cookie', name: '网易云Cookie', description: '网易云音乐登录Cookie,格式: MUSIC_U=xxx; MUSIC_U 值从浏览器登录网易云后 F12→Application→Cookies 复制。用于个人歌单、收藏等功能' } @@ -653,17 +638,6 @@ var pluginInfo = { supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric'] } -// ===== 激活/切换模式 ===== -function activatePremium() { - var envNow = global.env || {}; - if (!envNow.ceru_key) return Promise.reject(new Error('请先在环境变量中填写 ceru_key')); - return Promise.resolve({ success: true, message: '付费模式已激活,下次播放将使用高音质' }); -} - -function activatePublic() { - return Promise.resolve({ success: true, message: '已切换到公益模式' }); -} - module.exports = { musicSearch: { search: search }, tipSearch: { search: tipSearch }, @@ -677,7 +651,5 @@ module.exports = { getUrl: getUrl, musicDetail: musicDetail, musicInfo: musicInfo, - activatePremium: activatePremium, - activatePublic: activatePublic, pluginInfo: pluginInfo }; diff --git a/聆澜/Koneko_聆澜_酷我音乐_v0.1.3_QZv2.js b/聆澜/Koneko_聆澜_酷我音乐_v0.1.4_QZv2.js similarity index 91% rename from 聆澜/Koneko_聆澜_酷我音乐_v0.1.3_QZv2.js rename to 聆澜/Koneko_聆澜_酷我音乐_v0.1.4_QZv2.js index cfa3ae2..54b72c0 100644 --- a/聆澜/Koneko_聆澜_酷我音乐_v0.1.3_QZv2.js +++ b/聆澜/Koneko_聆澜_酷我音乐_v0.1.4_QZv2.js @@ -213,14 +213,11 @@ var pluginInfo = { info: { id: 'koneko_ceru_kw', name: '酷我音乐 - Koneko 聆澜', - version: '0.1.3', + version: '0.1.4', source: 'kw', description: '酷我音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口' }, - ext: [ - { type: 'button', name: '激活付费', description: '点击激活付费模式(需先在环境变量填入 ceru_key)', entry: 'activatePremium' }, - { type: 'button', name: '公益模式', description: '切换到公益模式(不使用 API Key)', entry: 'activatePublic' } - ], + ext: [], env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜付费密钥。留空=公益模式(仅128k);填写=付费模式(高音质)。修改后下次播放自动生效,也可点扩展按钮激活' }], quality: [ { name: '标准音质', ui: '标', id: '128k' }, @@ -232,17 +229,6 @@ var pluginInfo = { supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric'] } -// ===== 激活/切换模式 ===== -function activatePremium() { - var envNow = global.env || {}; - if (!envNow.ceru_key) return Promise.reject(new Error('请先在环境变量中填写 ceru_key')); - return Promise.resolve({ success: true, message: '付费模式已激活,下次播放将使用高音质' }); -} - -function activatePublic() { - return Promise.resolve({ success: true, message: '已切换到公益模式' }); -} - module.exports = { musicSearch: { search: search }, tipSearch: { search: tipSearch }, @@ -256,7 +242,5 @@ module.exports = { getUrl: getUrl, musicDetail: musicDetail, musicInfo: musicInfo, - activatePremium: activatePremium, - activatePublic: activatePublic, pluginInfo: pluginInfo }; diff --git a/聆澜/Koneko_聆澜_酷狗音乐_v0.1.3_QZv2.js b/聆澜/Koneko_聆澜_酷狗音乐_v0.1.4_QZv2.js similarity index 91% rename from 聆澜/Koneko_聆澜_酷狗音乐_v0.1.3_QZv2.js rename to 聆澜/Koneko_聆澜_酷狗音乐_v0.1.4_QZv2.js index 1f09684..1b803ec 100644 --- a/聆澜/Koneko_聆澜_酷狗音乐_v0.1.3_QZv2.js +++ b/聆澜/Koneko_聆澜_酷狗音乐_v0.1.4_QZv2.js @@ -215,14 +215,11 @@ var pluginInfo = { info: { id: 'koneko_ceru_kg', name: '酷狗音乐 - Koneko 聆澜', - version: '0.1.3', + version: '0.1.4', source: 'kg', description: '酷狗音乐音源,基于 CeruMusic musicSdk 搜索 + Ceru 播放接口' }, - ext: [ - { type: 'button', name: '激活付费', description: '点击激活付费模式(需先在环境变量填入 ceru_key)', entry: 'activatePremium' }, - { type: 'button', name: '公益模式', description: '切换到公益模式(不使用 API Key)', entry: 'activatePublic' } - ], + ext: [], env: [{ key: 'ceru_key', name: 'Ceru API Key', description: '聆澜付费密钥。留空=公益模式(仅128k);填写=付费模式(高音质)。修改后下次播放自动生效,也可点扩展按钮激活' }], quality: [ { name: '标准音质', ui: '标', id: '128k' }, @@ -234,17 +231,6 @@ var pluginInfo = { supportFunc: ['search_song', 'search_playlist', 'playlist', 'album', 'lyric'] } -// ===== 激活/切换模式 ===== -function activatePremium() { - var envNow = global.env || {}; - if (!envNow.ceru_key) return Promise.reject(new Error('请先在环境变量中填写 ceru_key')); - return Promise.resolve({ success: true, message: '付费模式已激活,下次播放将使用高音质' }); -} - -function activatePublic() { - return Promise.resolve({ success: true, message: '已切换到公益模式' }); -} - module.exports = { musicSearch: { search: search }, tipSearch: { search: tipSearch }, @@ -258,7 +244,5 @@ module.exports = { getUrl: getUrl, musicDetail: musicDetail, musicInfo: musicInfo, - activatePremium: activatePremium, - activatePublic: activatePublic, pluginInfo: pluginInfo };