hexo-bitiful-toolkit 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -58,7 +58,6 @@ bitiful_toolkit:
58
58
  add_max_width: false
59
59
  max_widths: "(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
60
60
  enable_lazy_loading: true
61
- lazy_skip_first: 2
62
61
  supported_domains: ["assets.vluv.space", "s3.bitiful.net", "bitiful.com"]
63
62
  exclude_formats: ['svg', 'gif'],
64
63
  inject_css: true
package/dist/index.js CHANGED
@@ -1,9 +1 @@
1
- var Q=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var at=Q((qt,nt)=>{function pt(e,t,s){if(e>100||t>100)throw new Error(`${e}x${t} doesn't fit in 100x100`);let{PI:c,round:o,max:n,cos:r,abs:l}=Math,p=0,g=0,h=0,i=0;for(let _=0,x=0;_<e*t;_++,x+=4){let b=s[x+3]/255;p+=b/255*s[x],g+=b/255*s[x+1],h+=b/255*s[x+2],i+=b}i&&(p/=i,g/=i,h/=i);let f=i<e*t,y=f?5:7,m=n(1,o(y*e/n(e,t))),d=n(1,o(y*t/n(e,t))),$=[],L=[],H=[],W=[];for(let _=0,x=0;_<e*t;_++,x+=4){let b=s[x+3]/255,D=p*(1-b)+b/255*s[x],a=g*(1-b)+b/255*s[x+1],u=h*(1-b)+b/255*s[x+2];$[_]=(D+a+u)/3,L[_]=(D+a)/2-u,H[_]=D-a,W[_]=b}let N=(_,x,b)=>{let D=0,a=[],u=0,F=[];for(let I=0;I<b;I++)for(let S=0;S*b<x*(b-I);S++){let O=0;for(let C=0;C<e;C++)F[C]=r(c/e*S*(C+.5));for(let C=0;C<t;C++)for(let K=0,dt=r(c/t*I*(C+.5));K<e;K++)O+=_[K+C*e]*F[K]*dt;O/=e*t,S||I?(a.push(O),u=n(u,l(O))):D=O}if(u)for(let I=0;I<a.length;I++)a[I]=.5+.5/u*a[I];return[D,a,u]},[G,k,V]=N($,n(3,m),n(3,d)),[X,J,Y]=N(L,3,3),[M,R,P]=N(H,3,3),[j,z,E]=f?N(W,5,5):[],q=e>t,w=o(63*G)|o(31.5+31.5*X)<<6|o(31.5+31.5*M)<<12|o(31*V)<<18|f<<23,A=(q?d:m)|o(63*Y)<<3|o(63*P)<<9|q<<15,v=[w&255,w>>8&255,w>>16,A&255,A>>8],B=f?6:5,U=0;f&&v.push(o(15*j)|o(15*E)<<4);for(let _ of f?[k,J,R,z]:[k,J,R])for(let x of _)v[B+(U>>1)]|=o(15*x)<<((U++&1)<<2);return new Uint8Array(v)}function st(e){let{PI:t,min:s,max:c,cos:o,round:n}=Math,r=e[0]|e[1]<<8|e[2]<<16,l=e[3]|e[4]<<8,p=(r&63)/63,g=(r>>6&63)/31.5-1,h=(r>>12&63)/31.5-1,i=(r>>18&31)/31,f=r>>23,y=(l>>3&63)/63,m=(l>>9&63)/63,d=l>>15,$=c(3,d?f?5:7:l&7),L=c(3,d?l&7:f?5:7),H=f?(e[5]&15)/15:1,W=(e[5]>>4)/15,N=f?6:5,G=0,k=(q,w,A)=>{let v=[];for(let B=0;B<w;B++)for(let U=B?0:1;U*w<q*(w-B);U++)v.push(((e[N+(G>>1)]>>((G++&1)<<2)&15)/7.5-1)*A);return v},V=k($,L,i),X=k(3,3,y*1.25),J=k(3,3,m*1.25),Y=f&&k(5,5,W),M=ot(e),R=n(M>1?32:32*M),P=n(M>1?32/M:32),j=new Uint8Array(R*P*4),z=[],E=[];for(let q=0,w=0;q<P;q++)for(let A=0;A<R;A++,w+=4){let v=p,B=g,U=h,_=H;for(let a=0,u=c($,f?5:3);a<u;a++)z[a]=o(t/R*(A+.5)*a);for(let a=0,u=c(L,f?5:3);a<u;a++)E[a]=o(t/P*(q+.5)*a);for(let a=0,u=0;a<L;a++)for(let F=a?0:1,I=E[a]*2;F*L<$*(L-a);F++,u++)v+=V[u]*z[F]*I;for(let a=0,u=0;a<3;a++)for(let F=a?0:1,I=E[a]*2;F<3-a;F++,u++){let S=z[F]*I;B+=X[u]*S,U+=J[u]*S}if(f)for(let a=0,u=0;a<5;a++)for(let F=a?0:1,I=E[a]*2;F<5-a;F++,u++)_+=Y[u]*z[F]*I;let x=v-2/3*B,b=(3*v-x+U)/2,D=b-U;j[w]=c(0,255*s(1,b)),j[w+1]=c(0,255*s(1,D)),j[w+2]=c(0,255*s(1,x)),j[w+3]=c(0,255*s(1,_))}return{w:R,h:P,rgba:j}}function gt(e){let{min:t,max:s}=Math,c=e[0]|e[1]<<8|e[2]<<16,o=(c&63)/63,n=(c>>6&63)/31.5-1,r=(c>>12&63)/31.5-1,p=c>>23?(e[5]&15)/15:1,g=o-2/3*n,h=(3*o-g+r)/2,i=h-r;return{r:s(0,t(1,h)),g:s(0,t(1,i)),b:s(0,t(1,g)),a:p}}function ot(e){let t=e[3],s=e[2]&128,c=e[4]&128,o=c?s?5:7:t&7,n=c?t&7:s?5:7;return o/n}function ct(e,t,s){let c=e*4+1,o=6+t*(5+c),n=[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,e>>8,e&255,0,0,t>>8,t&255,8,6,0,0,0,0,0,0,0,o>>>24,o>>16&255,o>>8&255,o&255,73,68,65,84,120,1],r=[0,498536548,997073096,651767980,1994146192,1802195444,1303535960,1342533948,-306674912,-267414716,-690576408,-882789492,-1687895376,-2032938284,-1609899400,-1111625188],l=1,p=0;for(let g=0,h=0,i=c-1;g<t;g++,i+=c-1)for(n.push(g+1<t?0:1,c&255,c>>8,~c&255,c>>8^255,0),p=(p+l)%65521;h<i;h++){let f=s[h]&255;n.push(f),l=(l+f)%65521,p=(p+l)%65521}n.push(p>>8,p&255,l>>8,l&255,0,0,0,0,0,0,0,0,73,69,78,68,174,66,96,130);for(let[g,h]of[[12,29],[37,41+o]]){let i=-1;for(let f=g;f<h;f++)i^=n[f],i=i>>>4^r[i&15],i=i>>>4^r[i&15];i=~i,n[h++]=i>>>24,n[h++]=i>>16&255,n[h++]=i>>8&255,n[h++]=i&255}return`data:image/png;base64,${btoa(String.fromCharCode(...n))}`}function mt(e){let t=st(e);return ct(t.w,t.h,t.rgba)}nt.exports={rgbaToThumbHash:pt,thumbHashToRGBA:st,thumbHashToAverageRGBA:gt,thumbHashToApproximateAspectRatio:ot,rgbaToDataURL:ct,thumbHashToDataURL:mt}});var et=Q((At,it)=>{var Z=require("node:fs/promises"),bt=require("node:path"),tt=class{constructor(t={}){this.config={cache_file:"thumbcache.json",hexo_root:process.cwd(),...t},this.cache={},this.hasUpdated=!1,this.cacheFilePath=bt.join(this.config.hexo_root,this.config.cache_file),this.stats={apiRequests:0,cacheHits:0}}async loadCacheFromFile(){try{if(console.log("[BITIFUL] Loading cache from local file..."),await Z.access(this.cacheFilePath).then(()=>!0).catch(()=>!1)){let t=await Z.readFile(this.cacheFilePath,"utf8");this.cache=JSON.parse(t||"{}"),console.log(`[BITIFUL] Cache loaded from ${this.cacheFilePath}, ${Object.keys(this.cache).length} items`)}else console.log("[BITIFUL] Cache file not found, starting with empty cache"),this.cache={};return!0}catch(t){return console.warn("[BITIFUL] Failed to load cache from file:",t.message),this.cache={},!1}}async saveCacheToFile(){if(!this.config.enable||!this.hasUpdated)return console.log("[BITIFUL] Skipping cache save: disabled or no changes"),!1;try{console.log("[BITIFUL] Saving cache to local file...");let t=JSON.stringify(this.cache,null,2);return await Z.writeFile(this.cacheFilePath,t,"utf8"),console.log(`[BITIFUL] Cache saved to ${this.cacheFilePath}, ${Object.keys(this.cache).length} items`),this.hasUpdated=!1,!0}catch(t){return console.warn("[BITIFUL] Failed to save cache to file:",t.message),!1}}getCachedDataURL(t){if(this.cache[t]){this.stats.cacheHits++;let s=this.cache[t];return typeof s=="string"?s:s&&typeof s=="object"&&s.dataURL||null}return this.stats.apiRequests++,null}getCachedDimensions(t){let s=this.cache[t];return s?(this.stats.cacheHits++,typeof s=="object"&&Number.isFinite(s?.width)&&Number.isFinite(s?.height)?{width:s.width,height:s.height}:null):(this.stats.apiRequests++,null)}setCachedDataURL(t,s){if(!s)return;let c=this.cache[t];typeof c=="object"?c.dataURL!==s&&(this.cache[t]={...c,dataURL:s},this.hasUpdated=!0):c!==s&&(this.cache[t]={dataURL:s},this.hasUpdated=!0)}setCachedDimensions(t,s,c){if(!Number.isFinite(s)||!Number.isFinite(c))return;let o=this.cache[t];(o.width!==s||o.height!==c)&&(this.cache[t]={...o,width:s,height:c},this.hasUpdated=!0)}getStats(){let t=this.stats.apiRequests+this.stats.cacheHits;return{totalItems:Object.keys(this.cache).length,isDirty:this.hasUpdated,cacheEnabled:this.config.enable,...this.stats,totalRequests:t,cacheHitRate:t>0?(this.stats.cacheHits/t*100).toFixed(1):0}}};it.exports=tt});var lt=Q((kt,rt)=>{var{thumbHashToDataURL:yt}=at(),Dt=et();async function xt(e,t=null){try{if(t){let l=t.getCachedDimensions(e);if(l)return l}console.log(`[BITIFUL] \u274C ${e.split("/").pop().split("?")[0]} \u5C3A\u5BF8\u7F13\u5B58\u672A\u547D\u4E2D\uFF0C\u6B63\u5728\u83B7\u53D6...`);let s=`${e.split("?")[0]}?fmt=info`,o=await(await fetch(s)).json(),n=o.ImageWidth,r=o.ImageHeight;return Number.isFinite(n)&&Number.isFinite(r)?(t&&t.setCachedDimensions(e,Number(n),Number(r)),{width:Number(n),height:Number(r)}):null}catch(s){return console.warn("Failed to generate thumbhash:",s.message),null}}async function _t(e,t=null){try{if(t){let l=t.getCachedDataURL(e);if(l)return l}console.log(`[BITIFUL] \u274C ${e.split("/").pop().split("?")[0]} \u7F13\u5B58\u672A\u547D\u4E2D\uFF0C\u6B63\u5728\u83B7\u53D6...`);let s=`${e.split("?")[0]}?fmt=thumbhash`,o=await(await fetch(s)).text(),n=It(o.trim()),r=yt(n);return t&&r&&(console.log(`[BITIFUL] \u5C06${e}\u53CA\u5176\u5BF9\u5E94\u7684dataUrl\u5199\u5165\u7F13\u5B58`),t.setCachedDataURL(e,r)),r}catch(s){return console.warn("Failed to generate thumbhash:",s.message),null}}function It(e){try{let t=e.replace(/\s/g,""),s=atob(t),c=new Uint8Array(s.length);for(let o=0;o<s.length;o++)c[o]=s.charCodeAt(o);return c}catch(t){throw new Error(`Base64 decode failed: ${t.message}`)}}rt.exports={getDimension:xt,getDataURL:_t}});var ft=Q((Rt,ht)=>{var{getDimension:Ft,getDataURL:wt}=lt();function $t(e,t,s){let c=t.some(r=>e.includes(r)),o=e.split(".").pop().split("?")[0].toLowerCase(),n=!s.includes(o);return c&&n}function Lt(e,t,s,c,o,n){let r=s.srcset_widths.map(m=>`${t.includes("?")?`${t}&w=${m}`:`${t}?w=${m}`} ${m}w`).join(", "),l=e.replace(/<img\s+/,"").replace(/\s*\/?>$/,"").replace(/src="[^"]*"\s*/,""),p=null,g=e.match(/\bwidth\s*=\s*["']?([^"'\s>]+)/i);if(g)p=g[1];else{let m=e.match(/style\s*=\s*["']([^"']*?)["']/i);if(m){let d=m[1].match(/width\s*:\s*([^;]+)/i);d&&(p=d[1].trim())}}o&&(l=l.replace(/\bwidth\s*=\s*["']?[^"'\s>]+["']?\s*/gi,""),l=l.replace(/style\s*=\s*["']([^"']*?)["']/gi,(m,d)=>{let $=d.replace(/width\s*:\s*[^;]+;?\s*/gi,"").trim();return $?`style="${$}"`:""}));let h=`${[`<img src="${t}" srcset="${r}"`,c?'loading="lazy" decoding="async"':'loading="eager"',o?'style="width: 100%; height: 100%; object-fit: cover;"':"",`onload="this.style.opacity=1; this.parentElement.style.backgroundImage='none';"`,l].filter(Boolean).join(" ")}>`,i=o?`background-image: url('${o}');`:"",f=n?`${n.width} / ${n.height}`:"auto",y=p||"100%";return o&&n?`<div class="pic" style="
2
- position: relative;
3
- overflow: hidden;
4
- max-width: ${n.width}px;
5
- width: ${y};
6
- aspect-ratio: ${f};
7
- ${i}
8
- background-size: cover;
9
- background-repeat: no-repeat;">${h}</div>`:h}async function Tt(e,t){let s={srcset_widths:[400,600,800,1200,2e3,3e3],add_max_width:!1,max_widths:"(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px",enable_lazy_loading:!0,lazy_skip_first:2,supported_domains:["assets.vluv.space","s3.bitiful.net","bitiful.com"],exclude_formats:["svg","gif"],...t},c=global.bitifulCacheInstance,o=/<img[^>]+src="(.+?)"[^>]*>/gm,n=Array.from(e.matchAll(o));if(n.length===0)return e;let r=new Map;n.forEach(y=>{let[m,d]=y;$t(d,s.supported_domains,s.exclude_formats)&&(r.has(d)||r.set(d,{src:d}))});let l=Array.from(r.keys()),p=await Promise.all(l.map(async y=>{let[m,d]=await Promise.all([wt(y,c),Ft(y,c)]);return{src:y,thumbhash:m,dimensions:d}})),g=new Map(p.map(y=>[y.src,y])),h="",i=0,f=0;for(let y of n){let[m,d]=y,$=y.index;h+=e.slice(i,$);let L=g.get(d);if(L){let H=s.enable_lazy_loading&&++f>s.lazy_skip_first;h+=Lt(m,d,s,H,L.thumbhash,L.dimensions)}else h+=m;i=$+m.length}return h+=e.slice(i),h}ht.exports=Tt});var ut=ft(),vt=et(),T=hexo.log,Bt=hexo.config.bitiful_toolkit?.env_name||"CI";function Ut(){if(!hexo.config.bitiful_toolkit||!hexo.config.bitiful_toolkit.enable||process.env[Bt]!=="true")return;let e=new vt({...hexo.config.bitiful_toolkit.cache,hexo_root:hexo.base_dir});global.bitifulCacheInstance=e,hexo.extend.filter.register("before_generate",async()=>{T.info("[BITIFUL] Initializing thumbhash cache..."),await e.loadCacheFromFile();let t=e.getStats();T.info(`[BITIFUL] Cache initialized with ${t.totalItems} items`)},8),hexo.extend.filter.register("after_generate",async()=>{if(e){let t=e.getStats();T.info("[BITIFUL] \u56FE\u7247\u5904\u7406\u5B8C\u6210\u7EDF\u8BA1:"),T.info(`[BITIFUL] - \u603B\u8BF7\u6C42\u6570: ${t.totalRequests}`),T.info(`[BITIFUL] - \u5B9E\u9645API\u8BF7\u6C42\u6570: ${t.apiRequests}`),T.info(`[BITIFUL] - \u7F13\u5B58\u547D\u4E2D\u6570: ${t.cacheHits}`),T.info(`[BITIFUL] - \u7F13\u5B58\u547D\u4E2D\u7387: ${t.cacheHitRate}%`),T.info(`[BITIFUL] - \u7F13\u5B58\u603B\u6761\u76EE\u6570: ${t.totalItems}`),t.isDirty?(T.info("[BITIFUL] Saving updated cache to local file..."),await e.saveCacheToFile()):T.info("[BITIFUL] No cache updates, skipping save")}}),hexo.config.bitiful_toolkit.all?(T.info("[BITIFUL] process all image"),hexo.extend.filter.register("after_render:html",async t=>(t=await ut(t,hexo.config.bitiful_toolkit),t),15)):(T.info("[BITIFUL] process post images"),hexo.extend.filter.register("before_post_render",async t=>(t.content=await ut(t.content,hexo.config.bitiful_toolkit),t),15))}Ut();
1
+ var Q=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var at=Q((qt,nt)=>{function pt(e,t,s){if(e>100||t>100)throw new Error(`${e}x${t} doesn't fit in 100x100`);let{PI:o,round:c,max:n,cos:l,abs:h}=Math,p=0,m=0,f=0,r=0;for(let x=0,y=0;x<e*t;x++,y+=4){let b=s[y+3]/255;p+=b/255*s[y],m+=b/255*s[y+1],f+=b/255*s[y+2],r+=b}r&&(p/=r,m/=r,f/=r);let a=r<e*t,d=a?5:7,g=n(1,c(d*e/n(e,t))),L=n(1,c(d*t/n(e,t))),$=[],T=[],O=[],W=[];for(let x=0,y=0;x<e*t;x++,y+=4){let b=s[y+3]/255,D=p*(1-b)+b/255*s[y],i=m*(1-b)+b/255*s[y+1],u=f*(1-b)+b/255*s[y+2];$[x]=(D+i+u)/3,T[x]=(D+i)/2-u,O[x]=D-i,W[x]=b}let k=(x,y,b)=>{let D=0,i=[],u=0,_=[];for(let I=0;I<b;I++)for(let S=0;S*b<y*(b-I);S++){let E=0;for(let C=0;C<e;C++)_[C]=l(o/e*S*(C+.5));for(let C=0;C<t;C++)for(let K=0,dt=l(o/t*I*(C+.5));K<e;K++)E+=x[K+C*e]*_[K]*dt;E/=e*t,S||I?(i.push(E),u=n(u,h(E))):D=E}if(u)for(let I=0;I<i.length;I++)i[I]=.5+.5/u*i[I];return[D,i,u]},[G,R,V]=k($,n(3,g),n(3,L)),[X,J,Y]=k(T,3,3),[N,j,M]=k(O,3,3),[H,P,z]=a?k(W,5,5):[],q=e>t,F=c(63*G)|c(31.5+31.5*X)<<6|c(31.5+31.5*N)<<12|c(31*V)<<18|a<<23,A=(q?L:g)|c(63*Y)<<3|c(63*M)<<9|q<<15,B=[F&255,F>>8&255,F>>16,A&255,A>>8],U=a?6:5,v=0;a&&B.push(c(15*H)|c(15*z)<<4);for(let x of a?[R,J,j,P]:[R,J,j])for(let y of x)B[U+(v>>1)]|=c(15*y)<<((v++&1)<<2);return new Uint8Array(B)}function st(e){let{PI:t,min:s,max:o,cos:c,round:n}=Math,l=e[0]|e[1]<<8|e[2]<<16,h=e[3]|e[4]<<8,p=(l&63)/63,m=(l>>6&63)/31.5-1,f=(l>>12&63)/31.5-1,r=(l>>18&31)/31,a=l>>23,d=(h>>3&63)/63,g=(h>>9&63)/63,L=h>>15,$=o(3,L?a?5:7:h&7),T=o(3,L?h&7:a?5:7),O=a?(e[5]&15)/15:1,W=(e[5]>>4)/15,k=a?6:5,G=0,R=(q,F,A)=>{let B=[];for(let U=0;U<F;U++)for(let v=U?0:1;v*F<q*(F-U);v++)B.push(((e[k+(G>>1)]>>((G++&1)<<2)&15)/7.5-1)*A);return B},V=R($,T,r),X=R(3,3,d*1.25),J=R(3,3,g*1.25),Y=a&&R(5,5,W),N=ot(e),j=n(N>1?32:32*N),M=n(N>1?32/N:32),H=new Uint8Array(j*M*4),P=[],z=[];for(let q=0,F=0;q<M;q++)for(let A=0;A<j;A++,F+=4){let B=p,U=m,v=f,x=O;for(let i=0,u=o($,a?5:3);i<u;i++)P[i]=c(t/j*(A+.5)*i);for(let i=0,u=o(T,a?5:3);i<u;i++)z[i]=c(t/M*(q+.5)*i);for(let i=0,u=0;i<T;i++)for(let _=i?0:1,I=z[i]*2;_*T<$*(T-i);_++,u++)B+=V[u]*P[_]*I;for(let i=0,u=0;i<3;i++)for(let _=i?0:1,I=z[i]*2;_<3-i;_++,u++){let S=P[_]*I;U+=X[u]*S,v+=J[u]*S}if(a)for(let i=0,u=0;i<5;i++)for(let _=i?0:1,I=z[i]*2;_<5-i;_++,u++)x+=Y[u]*P[_]*I;let y=B-2/3*U,b=(3*B-y+v)/2,D=b-v;H[F]=o(0,255*s(1,b)),H[F+1]=o(0,255*s(1,D)),H[F+2]=o(0,255*s(1,y)),H[F+3]=o(0,255*s(1,x))}return{w:j,h:M,rgba:H}}function gt(e){let{min:t,max:s}=Math,o=e[0]|e[1]<<8|e[2]<<16,c=(o&63)/63,n=(o>>6&63)/31.5-1,l=(o>>12&63)/31.5-1,p=o>>23?(e[5]&15)/15:1,m=c-2/3*n,f=(3*c-m+l)/2,r=f-l;return{r:s(0,t(1,f)),g:s(0,t(1,r)),b:s(0,t(1,m)),a:p}}function ot(e){let t=e[3],s=e[2]&128,o=e[4]&128,c=o?s?5:7:t&7,n=o?t&7:s?5:7;return c/n}function ct(e,t,s){let o=e*4+1,c=6+t*(5+o),n=[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,e>>8,e&255,0,0,t>>8,t&255,8,6,0,0,0,0,0,0,0,c>>>24,c>>16&255,c>>8&255,c&255,73,68,65,84,120,1],l=[0,498536548,997073096,651767980,1994146192,1802195444,1303535960,1342533948,-306674912,-267414716,-690576408,-882789492,-1687895376,-2032938284,-1609899400,-1111625188],h=1,p=0;for(let m=0,f=0,r=o-1;m<t;m++,r+=o-1)for(n.push(m+1<t?0:1,o&255,o>>8,~o&255,o>>8^255,0),p=(p+h)%65521;f<r;f++){let a=s[f]&255;n.push(a),h=(h+a)%65521,p=(p+h)%65521}n.push(p>>8,p&255,h>>8,h&255,0,0,0,0,0,0,0,0,73,69,78,68,174,66,96,130);for(let[m,f]of[[12,29],[37,41+c]]){let r=-1;for(let a=m;a<f;a++)r^=n[a],r=r>>>4^l[r&15],r=r>>>4^l[r&15];r=~r,n[f++]=r>>>24,n[f++]=r>>16&255,n[f++]=r>>8&255,n[f++]=r&255}return`data:image/png;base64,${btoa(String.fromCharCode(...n))}`}function mt(e){let t=st(e);return ct(t.w,t.h,t.rgba)}nt.exports={rgbaToThumbHash:pt,thumbHashToRGBA:st,thumbHashToAverageRGBA:gt,thumbHashToApproximateAspectRatio:ot,rgbaToDataURL:ct,thumbHashToDataURL:mt}});var et=Q((At,it)=>{var Z=require("node:fs/promises"),bt=require("node:path"),tt=class{constructor(t={}){this.config={cache_file:"thumbcache.json",hexo_root:process.cwd(),...t},this.cache={},this.hasUpdated=!1,this.cacheFilePath=bt.join(this.config.hexo_root,this.config.cache_file),this.stats={apiRequests:0,cacheHits:0}}async loadCacheFromFile(){try{if(console.log("[BITIFUL] Loading cache from local file..."),await Z.access(this.cacheFilePath).then(()=>!0).catch(()=>!1)){let t=await Z.readFile(this.cacheFilePath,"utf8");this.cache=JSON.parse(t||"{}"),console.log(`[BITIFUL] Cache loaded from ${this.cacheFilePath}, ${Object.keys(this.cache).length} items`)}else console.log("[BITIFUL] Cache file not found, starting with empty cache"),this.cache={};return!0}catch(t){return console.warn("[BITIFUL] Failed to load cache from file:",t.message),this.cache={},!1}}async saveCacheToFile(){if(!this.config.enable||!this.hasUpdated)return console.log("[BITIFUL] Skipping cache save: disabled or no changes"),!1;try{console.log("[BITIFUL] Saving cache to local file...");let t=JSON.stringify(this.cache,null,2);return await Z.writeFile(this.cacheFilePath,t,"utf8"),console.log(`[BITIFUL] Cache saved to ${this.cacheFilePath}, ${Object.keys(this.cache).length} items`),this.hasUpdated=!1,!0}catch(t){return console.warn("[BITIFUL] Failed to save cache to file:",t.message),!1}}getCachedDataURL(t){if(this.cache[t]){this.stats.cacheHits++;let s=this.cache[t];return typeof s=="string"?s:s&&typeof s=="object"&&s.dataURL||null}return this.stats.apiRequests++,null}getCachedDimensions(t){let s=this.cache[t];return s?(this.stats.cacheHits++,typeof s=="object"&&Number.isFinite(s?.width)&&Number.isFinite(s?.height)?{width:s.width,height:s.height}:null):(this.stats.apiRequests++,null)}setCachedDataURL(t,s){if(!s)return;let o=this.cache[t];typeof o=="object"?o.dataURL!==s&&(this.cache[t]={...o,dataURL:s},this.hasUpdated=!0):o!==s&&(this.cache[t]={dataURL:s},this.hasUpdated=!0)}setCachedDimensions(t,s,o){if(!Number.isFinite(s)||!Number.isFinite(o))return;let c=this.cache[t];(c.width!==s||c.height!==o)&&(this.cache[t]={...c,width:s,height:o},this.hasUpdated=!0)}getStats(){let t=this.stats.apiRequests+this.stats.cacheHits;return{totalItems:Object.keys(this.cache).length,isDirty:this.hasUpdated,cacheEnabled:this.config.enable,...this.stats,totalRequests:t,cacheHitRate:t>0?(this.stats.cacheHits/t*100).toFixed(1):0}}};it.exports=tt});var lt=Q((Rt,rt)=>{var{thumbHashToDataURL:yt}=at(),Dt=et();async function xt(e,t=null){try{if(t){let h=t.getCachedDimensions(e);if(h)return h}console.log(`[BITIFUL] \u274C ${e.split("/").pop().split("?")[0]} \u5C3A\u5BF8\u7F13\u5B58\u672A\u547D\u4E2D\uFF0C\u6B63\u5728\u83B7\u53D6...`);let s=`${e.split("?")[0]}?fmt=info`,c=await(await fetch(s)).json(),n=c.ImageWidth,l=c.ImageHeight;return Number.isFinite(n)&&Number.isFinite(l)?(t&&t.setCachedDimensions(e,Number(n),Number(l)),{width:Number(n),height:Number(l)}):null}catch(s){return console.warn(`[BITIFUL] Failed to get dimensions for ${e}:`,s.message),null}}async function It(e,t=null){try{if(t){let h=t.getCachedDataURL(e);if(h)return h}console.log(`[BITIFUL] \u274C ${e.split("/").pop().split("?")[0]} \u7F13\u5B58\u672A\u547D\u4E2D\uFF0C\u6B63\u5728\u83B7\u53D6...`);let s=`${e.split("?")[0]}?fmt=thumbhash`,c=await(await fetch(s)).text(),n=_t(c.trim()),l=yt(n);return t&&l&&(console.log(`[BITIFUL] \u5C06${e}\u53CA\u5176\u5BF9\u5E94\u7684dataUrl\u5199\u5165\u7F13\u5B58`),t.setCachedDataURL(e,l)),l}catch(s){return console.warn("Failed to generate thumbhash:",s.message),null}}function _t(e){try{let t=e.replace(/\s/g,""),s=atob(t),o=new Uint8Array(s.length);for(let c=0;c<s.length;c++)o[c]=s.charCodeAt(c);return o}catch(t){throw new Error(`Base64 decode failed: ${t.message}`)}}rt.exports={getDimension:xt,getDataURL:It}});var ft=Q((jt,ht)=>{var{getDimension:Ft,getDataURL:wt}=lt();function Lt(e,t,s){let o=t.some(l=>e.includes(l)),c=e.split(".").pop().split("?")[0].toLowerCase(),n=!s.includes(c);return o&&n}function $t(e,t,s,o,c,n){let l=s.srcset_widths.map(d=>`${t.includes("?")?`${t}&w=${d}`:`${t}?w=${d}`} ${d}w`).join(", "),h=e.replace(/<img\s+/,"").replace(/\s*\/?>$/,"").replace(/src="[^"]*"\s*/,""),p=null,m=e.match(/\bwidth\s*=\s*["']?([^"'\s>]+)/i);if(m)p=m[1];else{let d=e.match(/style\s*=\s*["']([^"']*?)["']/i);if(d){let g=d[1].match(/width\s*:\s*([^;]+)/i);g&&(p=g[1].trim())}}c&&(h=h.replace(/\bwidth\s*=\s*["']?[^"'\s>]+["']?\s*/gi,""),h=h.replace(/style\s*=\s*["']([^"']*?)["']/gi,(d,g)=>{let L=g.replace(/width\s*:\s*[^;]+;?\s*/gi,"").trim();return L?`style="${L}"`:""}));let f=`${[`<img src="${t}" srcset="${l}"`,o?'loading="lazy" decoding="async"':'loading="eager"',c?'style="width: 100%; height: 100%; object-fit: cover;"':"",`onload="this.style.opacity=1; this.parentElement.style.backgroundImage='none';"`,h].filter(Boolean).join(" ")}>`,a=["position: relative","overflow: hidden",`width: ${p||"100%"}`,`background-image: url('${c}')`,"background-size: cover","background-repeat: no-repeat"];if(n?.width&&n?.height){let d=n?`${n.width} / ${n.height}`:"auto";a.push(`max-width: ${n.width}px`,`aspect-ratio: ${d}`)}return c?`<div class="pic" style="${a.join(";")}">${f}</div>`:f}async function Tt(e,t){let s={srcset_widths:[400,600,800,1200,2e3,3e3],add_max_width:!1,max_widths:"(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px",enable_lazy_loading:!0,supported_domains:["assets.vluv.space","s3.bitiful.net","bitiful.com"],exclude_formats:["svg","gif"],...t},o=global.bitifulCacheInstance,c=/<img[^>]+src="(.+?)"[^>]*>/gm,n=Array.from(e.matchAll(c));if(n.length===0)return e;let l=new Map;n.forEach(a=>{let[d,g]=a;Lt(g,s.supported_domains,s.exclude_formats)&&(l.has(g)||l.set(g,{src:g}))});let h=Array.from(l.keys()),p=await Promise.all(h.map(async a=>{let[d,g]=await Promise.all([wt(a,o),Ft(a,o)]);return{src:a,thumbhash:d,dimensions:g}})),m=new Map(p.map(a=>[a.src,a])),f="",r=0;for(let a of n){let[d,g]=a,L=a.index;f+=e.slice(r,L);let $=m.get(g);if($){let T=s.enable_lazy_loading;f+=$t(d,g,s,T,$.thumbhash,$.dimensions)}else f+=d;r=L+d.length}return f+=e.slice(r),f}ht.exports=Tt});var ut=ft(),Bt=et(),w=hexo.log,Ut=hexo.config.bitiful_toolkit?.env_name||"CI";function vt(){if(!hexo.config.bitiful_toolkit||!hexo.config.bitiful_toolkit.enable||process.env[Ut]!=="true")return;let e=new Bt({...hexo.config.bitiful_toolkit.cache,hexo_root:hexo.base_dir});global.bitifulCacheInstance=e,hexo.extend.filter.register("before_generate",async()=>{w.info("[BITIFUL] Initializing thumbhash cache..."),await e.loadCacheFromFile();let t=e.getStats();w.info(`[BITIFUL] Cache initialized with ${t.totalItems} items`)},8),hexo.extend.filter.register("after_generate",async()=>{if(e){let t=e.getStats();w.info("[BITIFUL] \u56FE\u7247\u5904\u7406\u5B8C\u6210\u7EDF\u8BA1:"),w.info(`[BITIFUL] - \u603B\u8BF7\u6C42\u6570: ${t.totalRequests}`),w.info(`[BITIFUL] - \u5B9E\u9645API\u8BF7\u6C42\u6570: ${t.apiRequests}`),w.info(`[BITIFUL] - \u7F13\u5B58\u547D\u4E2D\u6570: ${t.cacheHits}`),w.info(`[BITIFUL] - \u7F13\u5B58\u547D\u4E2D\u7387: ${t.cacheHitRate}%`),w.info(`[BITIFUL] - \u7F13\u5B58\u603B\u6761\u76EE\u6570: ${t.totalItems}`),t.isDirty?(w.info("[BITIFUL] Saving updated cache to local file..."),await e.saveCacheToFile()):w.info("[BITIFUL] No cache updates, skipping save")}}),hexo.config.bitiful_toolkit.all?(w.info("[BITIFUL] process all image"),hexo.extend.filter.register("after_render:html",async t=>(t=await ut(t,hexo.config.bitiful_toolkit),t),15)):(w.info("[BITIFUL] process post images"),hexo.extend.filter.register("before_post_render",async t=>(t.content=await ut(t.content,hexo.config.bitiful_toolkit),t),15))}vt();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hexo-bitiful-toolkit",
3
3
  "main": "dist/index.js",
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "files": [
6
6
  "dist/index.js",
7
7
  "README.md"