// ==UserScript==
// @name Icons8 Downloader
// @namespace http://tampermonkey.net/
// @version 2.1.4
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAF4SURBVHgB7Ze/SgNBEMa/WbUJoulUSPQQC7HSVhu1MFaimCKd4AuoeQHJC0h8AUlpEfFPZRqx0darREHkiBaWZ4g2yo07IcQIySkeyzb3wd6y+xXzu9nb4Yag5RzPOyBsMdGqXiabw4R8PTxicsFBwVu79EiCs6Ibg0G7wlDAMwo9atdCcFEy0FlXzDwNSyJ95ErPDuwpKQA20v8DwKp6w0xv5QK/yTlbxEBfPzbH15FNLyOVGMLz+wvK1QoOHo9Q+6zj3wB/kQQ/nN3D1OBEay+VGMb25AaWRuaQu8qHQkQ+Annz9uDtkn3xwxQZIJvOhPujGbMAku4ofmQA+eCi+JEByk+VcL96DqMActVuXx86erIvvlGA2kcdues8ivelVrplLt6V9BXc0VfwDUYBvkXN0W3dWXEhigtRXIjiQkRjpwsMi7L+TygAPuzJtwvA8BQxn8CSGOwq/dyHnSz4ilFQjRZZd6lMXAKzaxim0Z7rfrQoMSX2Fxbus4Ue8tqGAAAAAElFTkSuQmCC
// @description Help to quick download content from icons8.com without premium account or inspect html
// @author Kds
// @match https://icons8.com/*
// @grant none
// @license MIT
// ==/UserScript==
!function(){"use strict";const e=window.parent!=window,t="icons8-downloader",n=`<style name="${t}-css">#app_support{display:none}#icons8-downloader{bottom:12px;font:var(--font-ui-14-regular);font-weight:600;height:calc(3rem + 16px);padding:8px;position:fixed;right:12px;text-decoration:none;width:calc(3rem + 16px);z-index:2147483001}#icons8-downloader .icons8-button{align-items:center;background-color:var(--c-green_500);border-radius:50%;cursor:pointer;display:flex;height:3rem;justify-content:center;width:3rem}#icons8-downloader:hover .icons8-modal{display:flex}#icons8-downloader input{background:#f5f6fa;border:1px solid #f5f6fa}#icons8-downloader input:focus{background:#00b1ff1a;border:1px solid #00b1ff}#icons8-downloader span{user-select:none}#icons8-downloader *{font-size:14px;font-weight:600;letter-spacing:-.002em;line-height:1;text-decoration:none}#icons8-downloader .icons8-modal{background-color:#fff;border-radius:12px;bottom:8px;box-shadow:0 4px 16px 0 #1e315033;color:#1e3150;display:none;flex-direction:column;left:-400px;position:absolute;width:400px}#icons8-downloader-config,#icons8-downloader-menu{display:grid;gap:4px;grid-template-columns:auto auto;padding:8px}#icons8-downloader-menu span{border-radius:8px;cursor:pointer;padding:12px}#icons8-downloader-menu span:hover{background-color:#1e31501a}#icons8-downloader-config{border-top:1px solid #00b1ff1a}#icons8-downloader-config>div{align-items:center;border-radius:8px;display:flex;gap:8px;height:44px;padding:6px 12px}#icons8-downloader-config span{min-width:48px;user-select:none}#icons8-downloader-config input{text-align:center;width:100%}#icons8-downloader-config>div[checkbox]{cursor:pointer;flex-direction:row-reverse;justify-content:start}#icons8-downloader-config>div[checkbox] *{cursor:pointer}#icons8-downloader-config [type=checkbox]{height:16px;width:16px}#icons8-downloader-config [config-id=color] [data-preview]{border:1px solid #03425c;border-radius:50%;height:20px;min-width:20px;width:20px}</style>`,o=[{label:"Download Icon",id:"download_svg"},{label:"Download PNG",id:"download_png"},{label:"Download React",id:"download_react"}],a={color:"#1e3150",prefix:"ic",size:"100","style-name":"true"},c=u();Object.keys(c).length||g(a);const r={cssReady:!1,...a,...c},l=`<div id="${t}"><div class="icons8-button"><svg width="24" height="24" viewBox="0 0 48 48" ><path fill="white" d="M23.971 5.973A2 2 0 0 0 22 8v19.172l-2.586-2.586a2 2 0 1 0-2.828 2.828l6 6a2 2 0 0 0 2.828 0l6-6a2 2 0 1 0-2.828-2.828L26 27.172V8a2 2 0 0 0-2.029-2.027zm-16 25A2 2 0 0 0 6 33v3c0 3.29 2.71 6 6 6h24c3.29 0 6-2.71 6-6v-3a2 2 0 1 0-4 0v3a1.97 1.97 0 0 1-2 2H12a1.97 1.97 0 0 1-2-2v-3a2 2 0 0 0-2.029-2.027z" /></svg></div><div class="icons8-modal"><div id="${t}-menu">${o.map(e=>`<span id="${e.id}">${e.label}</span>`).join("")}</div><div id="${t}-config">${[{id:"color",name:"config-style-color",label:"Color"},{id:"prefix",name:"config-style-prefix",label:"Prefix"},{id:"size",name:"config-style-size",label:"Size"},{id:"style-name",name:"config-style-name",label:"Add Style Name",checkbox:!0}].map(e=>{const t=r[e.id];return`<div config-id="${e.id}" ${e.checkbox?"checkbox":""} ><span>${e.label}</span><div style="display:flex;gap:8px;align-items:center">${"color"==e.id?`<div data-preview style="background:${t}"></div>`:""}<input type="${e.checkbox?"checkbox":"text"}" name="${e.name}" ${e.checkbox?t?"checked":"":`value="${t}"`} /></div></div>`}).join("")}</div></div></div>`,i="https://api-icons.icons8.com/siteApi/icons/";function s(e){return"string"==typeof e}function d(e,t){return t?e<100?`${e}0`:e:`${e<10?"0":""}${e}`}function u(){return function(e){try{let t=null;return s(e)?(t=JSON.parse(e),s(t)&&(t=JSON.parse(t))):t=JSON.parse(JSON.stringify(e)),t}catch(e){return null}}(localStorage.getItem(t))||{}}function g(e){localStorage.setItem(t,JSON.stringify({...u(),...e}))}function h(...t){console.log(`[${function(){let e=new Date,t=d(e.getDate()),n=d(e.getMonth()+1),o=e.getFullYear();return`${d(e.getHours())}:${d(e.getMinutes())}:${d(e.getSeconds())}:${d(e.getMilliseconds(),!0)} ${t}/${n}/${o}`}()}][Icons8 Downloader]`+(e?"[IFRAME]":""),...t)}function f(e,t,n){let o=document.createElement("a"),a=n?URL.createObjectURL(e):e;o.href=a,o.target="_blank",o.download=t,o.click(),o.remove(),n&&URL.revokeObjectURL(a)}const m={},p=(e,t)=>{try{let n=(e,t)=>document[t?"querySelectorAll":"querySelector"](e),o=t;const a=t||__NUXT__.data?.["page:icon:id"]?.icon?.id||n(".app-accordion2")?.dataset?.icon,c=n(".app-grid-icon[class*=selected]",!0);let l=new Set;if(a&&l.add(a),c.length&&c.forEach(e=>{l.add(e.dataset.icon)}),l=Array.from(l),!l.length)return alert("Please select an icon!");const s=e=>new Promise(t=>{const n=m[e];n?.data?t(n):fetch(i+"icon?id="+e+"&svg=true").then(e=>e.json()).then(n=>{m[e]={data:n},t({data:n})}).catch(e=>t({error:e}))}),d=async t=>{let{data:n,error:a}=await s(t);if(!n?.icon||a)return o?null:alert("Icon not found!");let{isAnimated:c,isColor:l,name:i,platform:d,svg:u,jsonAnimateIcon:g}=n.icon,h="";if(r.prefix&&"react"!==e&&(h+=`${r.prefix}_`),"true"===r["style-name"]&&(h+=`${d}_`),h+=i.toLowerCase().replace("%","percent").replace(/[\s:-]/g,"_"),c){let e=(e=>{if("string"==typeof e&&RegExp(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i).exec(e)){const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(!t)throw new Error("Color can be only hex or rgb array (ex. [10,20,30])");return[Math.round(parseInt(t[1],16)/255*1e3)/1e3,Math.round(parseInt(t[2],16)/255*1e3)/1e3,Math.round(parseInt(t[3],16)/255*1e3)/1e3]}if("object"==typeof e&&3===e.length&&e.every(e=>e>=0&&e<=255))return[Math.round(e[0]/255*1e3)/1e3,Math.round(e[1]/255*1e3)/1e3,Math.round(e[2]/255*1e3)/1e3];if(e)throw new Error("Color can be only hex or rgb array (ex. [10,20,30])")})(r.color).join(",");return g=g.replace(/"k":\[0,0,0,1\]/g,`"k":[${e},1]`).replace(/"k":\[0,0,0\]/g,`"k":[${e}]`),o?{anim:g}:f(new Blob([g],{type:"text/plain"}),h+".json",!0)}let m=document.createElement("div");m.innerHTML=atob(u).replace(/\t+/g," ");let p=m.children[0],y=p.cloneNode(!0),$=p.getAttribute("viewBox").split(" ").pop(),w=p.innerHTML,v=`<path d="M0,${$}v-${$}h${$}v${$}z" fill="none"></path>`,b=l?"":` fill="${r.color}"`;p.innerHTML=`<g>${v}<g${b}>${w}</g></g></g>`;let S=p.outerHTML,I="data:image/svg+xml;base64,"+btoa(S);switch(e){case"png":h+=".png",await new Promise(e=>{let t=document.createElement("img");t.src=I,t.onload=function(){let n=document.createElement("canvas"),o=r.size||iconSize;n.setAttribute("width",o),n.setAttribute("height",o),n.getContext("2d").drawImage(t,0,0,o,o),I=n.toDataURL(),t.remove(),n.remove(),e()}});break;case"react":{w="";let e=y.innerHTML.match(/<()Gradient\s/)||y.querySelector("path[fill]");return y.childNodes.forEach(t=>{t&&(e||"path"!=t.nodeName.toLowerCase()||t.setAttribute("fill","currentColor"),w+=t.outerHTML||"")}),h=h.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),I=`import { IconSvgProps } from '@/types'; \n\n export default function Icon${h}({ size = 20, width, height, ...props }: IconSvgProps) { \n\treturn ( \n\t\t<svg \n\t\t\tviewBox='0 0 ${$} ${$}' \n\t\t\twidth={size || width} \n\t\t\theight={size || height} \n\t\t\trole={'presentation'} \n\t\t\taria-hidden={true} \n\t\t\tfocusable={false} \n\t\t\t{...props} \n\t\t> \n\t\t\t${w.replace(/"/g,"'")} \n\t\t</svg> \n\t); \n} \n `,f(new Blob([I],{type:"text/plain"}),h+".tsx",!0)}default:h+=".svg"}if(o)return{svg:S};f(I,h)};l.forEach(e=>{d(e)})}catch(e){console.log("\u{1f680} Kds: downloadSelectedIcon -> error",e)}};let y,$,w,v;const b=function(e){let t=__NUXT__.data||{},n=t[Object.keys(t)[0]]||{};console.log("\u{1f680}%c Kds: summaryIconStyle -> styleData:","color:orange",JSON.parse(JSON.stringify(n)));const{hero:o,cards:a}=n;if(y=0,$=[],!a)return alert("Icon style not found!");a.filter(e=>"Popular"!==e.title).forEach(({link:e,quantity:t,title:n},a)=>{const c=e.match(/([^/]+)--style-(.+)$/)||[];a||(w=o.apiCode,v={code:w,id:c[2],name:document.querySelector(".base-hero__title")?.innerText?.trim()||o.title||"unknown"});let r={code:c[1],name:n,total:t,page:0,subs:[],icons:[]};y+=r.total,$.push(r)});let c=`Icon style "${v.name}" have total "${y}" icons!`;console.log("\n%c"+c,"color:"+(y?"green":"orange"),v,$),e||alert(c)};let S;const I=async function(e){let t=[],n=[],o=[],a=!1;S=!1;try{if($||b(!0),!$.length)return alert("Icon style empty!");let c=(e,t)=>function(e,{middle:t="",unit:n={},unitStr:o,minStr:a}={}){if(o||t||(t=":"),!(e=parseInt(e||0)))return o?"0s":`00${t}00`;let c=e>86400,r=e>3600,l=c?Math.trunc(e/86400):0,i=c||r?Math.trunc((c?e%86400:e)/3600):0,s=Math.trunc((c||r?e%3600:e)/60),d=Math.trunc((c||r?e%3600:e)%60),u=l?`${!a&&l<10?"0":""}${l}${n.d||(o?"d":"")}${t}`:"",g=l||i?`${!a&&i<10?"0":""}${i}${n.h||(o?"h":"")}${t}`:"",h=`${!a&&s<10?"0":""}${s}${n.m||(o?"m":"")}${t}`;return`${u}${g}${a&&s>0||!a?h:""}${!a&&d<10?"0":""}${d}${n.s||(o?"s":"")}`}((t-e)/1e3),r=(e,t)=>new Promise(n=>{fetch(i+`packs/demarcation?category=${e}&amount=100&offset=${100*t}&platform=${w}&language=en-US`,{method:"GET",redirect:"follow"}).then(e=>e.json()).then(e=>n(e)).catch(e=>n(e))}),l=Date.now(),s=$.slice(0,1);if(console.log("\n\u{1f680}%c Kds: downloadAllIconOfStyle -> icons -> starting!","color:green"),!s[0].icons.length)for(let e of s)try{if(a)break;let l=e.code,i=0,s={code:l,name:e.name},d=0,u=!0,g=Date.now();for(;u;){let o=(await r(l,d)).category;o?(d+=1,o.subcategory.forEach(({code:o,name:a,icons:c})=>{let r=c.length,l={code:o,name:a};c.forEach(({id:o,name:a,commonName:c})=>{let r={code:c,id:o,name:a,category:s,subcategory:{...l}};n.some(e=>e.id===o)||n.push(r),t.push(r),e.icons.push(r)}),i+=r,l.total=r,e.subs.push(l)})):(e.page=d-1,u=!1)}let h=Date.now(),f=i===e.total;f||o.push(e),console.log("\n\u{1f680}%c Kds: downloadCategory:","color:"+(f?"green":"orange"),[c(g,h),f,`${i} : ${t.length} / ${y}`],e)}catch(t){a=!0,console.log("\n\u{1f680}%c Kds: downloadCategory -> error:","color:red",e,t)}n=n.sort((e,t)=>e.name.localeCompare(t.name));let d=Date.now();if(console.log("\n\u{1f680}%c Kds: downloadAllIconOfStyle -> icons -> result:","color:green",c(l,d)),console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> style -> info:","color:green",v),console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> style -> styleIcons:","color:green",t),console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> style -> uniqIcons:","color:green",n),console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> icons -> iconStyleCategories:","color:orange",$),console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> icons -> notMatchCategories:","color:orange",o),e)return;let u=n.length,g=[];for(let e=0;e<u&&!a;e++){let t=n[e];console.log(`\u{1f680} Kds: downloading icon ->${e+1} of ${u} at:`,t.id,t.name,Date.now());try{let e=await p(!1,t.id);e?Object.assign(t,e):g.push(t)}catch(e){console.error("\u{1f680} Kds: download icon -> error:",t,e)}}console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> icons -> uniqIcons:","color:green",n),console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> icons -> notFoundIcons:","color:red",g)}catch(e){a=!0,console.log("\u{1f680}%c Kds: downloadAllIconOfStyle -> error:","color:red",e)}};let k,x;var A;A=function(e){setTimeout(()=>{const{pathname:o}=location;k=document.getElementById(t);let a={};var c;!k&&["/icon/","/icons/"].some(e=>o.startsWith(e))&&"/icons/request-icon"!==o&&(r.cssReady||(document.head.insertAdjacentHTML("beforeend",n),r.cssReady=!0),document.body.insertAdjacentHTML("beforeend",l),k=document.getElementById(t),x=document.querySelector(`#${t}-menu`),x.childNodes.forEach(e=>{"SPAN"===e.nodeName&&e.addEventListener("click",()=>{try{switch(e.getAttribute("id")){case"download_icon_style":I();break;case"summary_icon_style":b();break;case"download_svg":p();break;case"download_react":p("react");break;case"download_png":p("png")}}catch(e){h("menu error:",e)}})}),(c="config",document.querySelectorAll(`#${t}-${c}`)).forEach(e=>{e.childNodes.forEach(e=>{if("DIV"!==e.nodeName)return;let t,n=e.getAttribute("config-id"),o="color"==n;a[n]=e.querySelector("input"),o&&(t=e.querySelector("[data-preview]"));try{switch(n){case"color":case"prefix":case"size":a[n].addEventListener("input",function(){r[n]=this.value,a[n].value=this.value,g({[n]:this.value}),o&&(t.style.background=this.value)}),a[n].addEventListener("keydown",function(e){let t=e.key||e.keyCode;["Enter",13].includes(t)&&this.blur()});break;case"style-name":e.addEventListener("click",()=>{let e=""===a[n].getAttribute("checked"),t=(e?"remove":"set")+"Attribute";a[n][t]("checked",""),e=!e,r[n]=e,g({[n]:e})})}}catch(e){h("config error:",e)}})}),!e&&h("ready to use!"))},500)},navigation.addEventListener("navigate",e=>{var t;!(t=e).canIntercept||t.hashChange||t.downloadRequest||t.formData||A(e.destination.url)}),A(location.href),h("loaded!")}();