Add kemono.su patreon & fanbox & fantia links into ppixiv
目前為
// ==UserScript==
// @name kemono.su links for ppixiv
// @author EnergoStalin
// @description Add kemono.su patreon & fanbox & fantia links into ppixiv
// @license AGPL-3.0-only
// @version 1.4.2
// @namespace https://pixiv.net
// @match https://*.pixiv.net/*
// @run-at document-body
// @icon https://www.google.com/s2/favicons?sz=64&domain=pixiv.net
// @connect www.patreon.com
// @connect kemono.su
// @grant GM.xmlHttpRequest
// ==/UserScript==
"use strict";(()=>{var L=Object.defineProperty;var r=(e,t)=>L(e,"name",{value:t,configurable:!0});var i=(e,t,o)=>new Promise((n,s)=>{var p=a=>{try{f(o.next(a))}catch(u){s(u)}},R=a=>{try{f(o.throw(a))}catch(u){s(u)}},f=a=>a.done?n(a.value):Promise.resolve(a.value).then(p,R);f((o=o.apply(e,t)).next())});function c(e){let t=e.trim();return t.startsWith("http")||(t=`https://${t}`),t}r(c,"normalizeUrl");var _=/[\W\s]((?:https?:\/\/)?(?:\w+[./].+){2,})/g,h={patreon:"patreon.com",fanbox:"Fanbox",fantia:"fantia.jp"};function k(e){return e.map(t=>{try{let o=new URL(c(t));return{label:h[Object.keys(h).filter(n=>o.host.includes(n))[0]],url:o}}catch(o){}})}r(k,"preprocessMatches");function b(e){return S(k(Array.from(document.body.querySelector(".description").textContent.matchAll(_)).map(t=>t[1])).filter(t=>t),e)}r(b,"getLinksFromDescription");function S(e,t){let o=t.map(n=>n.label);return e.filter(n=>!o.includes(n.label))}r(S,"removeDuplicates");function l(e){unsafeWindow.ppixiv.userCache.callUserModifiedCallbacks(e)}r(l,"notifyUserUpdated");function D(e){let t=0;if(e.length===0)return t;for(let o=0;o<e.length;o++)t+=e.charCodeAt(o);return t}r(D,"fastHash");var d={};function E(e){return i(this,null,function*(){let o=(yield GM.xmlHttpRequest({method:"GET",redirect:"manual",url:e})).finalUrl!==e;d[e]=o})}r(E,"cacheRedirect");var m=new Set;function w(e,t){let o=D(JSON.stringify(e));m.has(o)||(m.add(o),Promise.all(e.filter(n=>d[n.url.toString()]===void 0).map(n=>E(n.url.toString()))).then(n=>{m.delete(o),n.length>0&&l(t.userId)}).catch(console.error));for(let n of e)n.disabled=!0,d[n.url.toString()]===!0?n.label+=" (Redirected)":delete n.disabled;return e}r(w,"disableDeadLinks");function x(e,t){e.push({url:new URL(`https://kemono.su/fanbox/user/${t.userId}`),icon:"mat:money_off",type:"kemono_fanbox",label:"Kemono fanbox"})}r(x,"fanbox");function y(e,t){let o=e.url.toString().split("/").pop();t.push({url:new URL(`https://kemono.su/fantia/user/${o}`),icon:"mat:money_off",type:"kemono_fantia",label:"Kemono fantia"})}r(y,"fantia");function G(e){typeof e.url=="string"&&(e.url=new URL(c(e.url))),e.url.protocol="https",e.url.host.startsWith("www.")||(e.url.host=`www.${e.url.host}`)}r(G,"normalizePatreonLink");var M=new RegExp('"id":\\s*"(\\d+)",[\\n\\s]*"type":\\s*"user"',"ms");function v(e){return i(this,null,function*(){return(yield GM.xmlHttpRequest({method:"GET",url:e})).responseText.match(M)[1]})}r(v,"ripPatreonId");var U={};function g(e,t,o){G(e);let n=e.url.toString(),s=U[n];s?t.push({url:new URL(`https://kemono.su/patreon/user/${s}`),icon:"mat:money_off",type:"kemono_patreon",label:"Kemono patreon"}):v(n).then(p=>{U[n]=p,l(o.userId)}).catch(console.error)}r(g,"patreon");var z=r(({extraLinks:e,userInfo:t})=>{let o=[];for(let n of[...e,...b(e)])switch(n.label){case"Fanbox":x(o,t);break;case"patreon.com":g(n,o,t);break;case"fantia.jp":y(n,o);break;default:}e.push(...w(o,t))},"addUserLinks");unsafeWindow.vviewHooks={addUserLinks:z};})();