// ==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.10
// @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 _=Object.defineProperty;var r=(e,o)=>_(e,"name",{value:o,configurable:!0});var i=(e,o,t)=>new Promise((n,a)=>{var p=s=>{try{u(t.next(s))}catch(f){a(f)}},R=s=>{try{u(t.throw(s))}catch(f){a(f)}},u=s=>s.done?n(s.value):Promise.resolve(s.value).then(p,R);u((t=t.apply(e,o)).next())});function c(e){let o=e.trim();return o.startsWith("http")||(o=`https://${o}`),o}r(c,"normalizeUrl");var I=/[\W\s]((?:https?:\/\/)?(?:\w+[\.\/])+(?:\w?)+)/g,h={patreon:"patreon.com",fanbox:"Fanbox",fantia:"fantia.jp"};function L(e){return e.map(o=>{try{let t=new URL(c(o));return{label:h[Object.keys(h).filter(n=>t.host.includes(n))[0]],url:t}}catch(t){}})}r(L,"preprocessMatches");function b(e){let t=document.body.querySelector(".description").innerText.replaceAll(/\/\s+/g,"/").replaceAll("(dot)",".");return k(L(Array.from(t.matchAll(I)).map(n=>n[1])).filter(n=>n),e)}r(b,"getLinksFromDescription");function k(e,o){let t=o.map(n=>n.label);return e.filter(n=>!t.includes(n.label))}r(k,"removeDuplicates");function l(e){unsafeWindow.ppixiv.userCache.callUserModifiedCallbacks(e)}r(l,"notifyUserUpdated");function v(e){let o=0;if(e.length===0)return o;for(let t=0;t<e.length;t++)o+=e.charCodeAt(t);return o}r(v,"fastHash");var m={};function M(e){return i(this,null,function*(){let t=(yield GM.xmlHttpRequest({method:"GET",redirect:"manual",url:e})).finalUrl!==e;m[e]=t})}r(M,"cacheRedirect");var d=new Set;function x(e,o){let t=v(JSON.stringify(e));d.has(t)||(d.add(t),Promise.all(e.filter(n=>m[n.url.toString()]===void 0).map(n=>M(n.url.toString()))).then(n=>{d.delete(t),n.length>0&&l(o.userId)}).catch(console.error));for(let n of e){let a=m[n.url.toString()];a===!0?(n.label+=" (Redirected)",n.disabled=!0):a===void 0&&(n.disabled=!0)}return e}r(x,"disableDeadLinks");function w(e,o){e.push({url:new URL(`https://kemono.su/fanbox/user/${o}`),icon:"mat:money_off",type:`kemono_fanbox#${o}`,label:"Kemono fanbox"})}r(w,"fanbox");function y(e,o){let t=e.url.toString().split("/").pop();o.push({url:new URL(`https://kemono.su/fantia/user/${t}`),icon:"mat:money_off",type:`kemono_fantia#${t}`,label:"Kemono fantia"})}r(y,"fantia");function S(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(S,"normalizePatreonLink");var $=new RegExp('"id":\\s*"(\\d+)",[\\n\\s]*"type":\\s*"user"',"ms");function C(e){return i(this,null,function*(){var t,n;return(n=(t=(yield GM.xmlHttpRequest({method:"GET",url:e})).responseText.match($))==null?void 0:t[1])!=null?n:"undefined"})}r(C,"ripPatreonId");var U={};function g(e,o,t){S(e);let n=e.url.toString(),a=U[n];a?o.push({url:new URL(`https://kemono.su/patreon/user/${a}`),icon:"mat:money_off",type:`kemono_patreon#${a}`,label:"Kemono patreon"}):C(n).then(p=>{U[n]=p,l(t)}).catch(console.error)}r(g,"patreon");var D=r(({extraLinks:e,userInfo:o})=>{let t=[];for(let a of[...e,...b(e)])switch(a.label){case"Fanbox":w(t,o.userId);break;case"patreon.com":g(a,t,o.userId);break;case"fantia.jp":y(a,t);break;default:}let n=x(t,o);e.push(...n)},"addUserLinks");unsafeWindow.vviewHooks={addUserLinks:D};})();