@macrulez/devtoolz 0.4.0 → 0.4.2
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 +19 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/image-batch/cli.js +4 -5
- package/dist/commands/image-batch/cli.js.map +1 -1
- package/dist/commands/image-batch/config.d.ts +3 -2
- package/dist/commands/image-batch/config.js +6 -20
- package/dist/commands/image-batch/config.js.map +1 -1
- package/dist/commands/image-batch/manage-cli.js +81 -4
- package/dist/commands/image-batch/manage-cli.js.map +1 -1
- package/dist/commands/image-batch/manage.d.ts +3 -2
- package/dist/commands/image-batch/manage.js +55 -14
- package/dist/commands/image-batch/manage.js.map +1 -1
- package/dist/commands/image-batch/run.d.ts +7 -3
- package/dist/commands/image-batch/run.js +11 -1
- package/dist/commands/image-batch/run.js.map +1 -1
- package/dist/commands/image-batch/sharpen-ask.d.ts +6 -0
- package/dist/commands/image-batch/sharpen-ask.js +53 -0
- package/dist/commands/image-batch/sharpen-ask.js.map +1 -0
- package/dist/commands/image-batch/sharpen-manage.d.ts +26 -0
- package/dist/commands/image-batch/sharpen-manage.js +238 -0
- package/dist/commands/image-batch/sharpen-manage.js.map +1 -0
- package/dist/commands/image-batch/sharpen-presets.d.ts +24 -0
- package/dist/commands/image-batch/sharpen-presets.js +145 -0
- package/dist/commands/image-batch/sharpen-presets.js.map +1 -0
- package/dist/commands/image-batch/sharpen.d.ts +33 -3
- package/dist/commands/image-batch/sharpen.js +141 -14
- package/dist/commands/image-batch/sharpen.js.map +1 -1
- package/dist/commands/image-hash/sharp-loader.d.ts +3 -0
- package/dist/commands/image-hash/sharp-loader.js.map +1 -1
- package/dist/commands/ui/cli.d.ts +2 -0
- package/dist/commands/ui/cli.js +78 -0
- package/dist/commands/ui/cli.js.map +1 -0
- package/dist/commands/ui/fs-routes.d.ts +7 -0
- package/dist/commands/ui/fs-routes.js +135 -0
- package/dist/commands/ui/fs-routes.js.map +1 -0
- package/dist/commands/ui/http.d.ts +41 -0
- package/dist/commands/ui/http.js +81 -0
- package/dist/commands/ui/http.js.map +1 -0
- package/dist/commands/ui/jobs.d.ts +15 -0
- package/dist/commands/ui/jobs.js +73 -0
- package/dist/commands/ui/jobs.js.map +1 -0
- package/dist/commands/ui/modules/checks.d.ts +28 -0
- package/dist/commands/ui/modules/checks.js +556 -0
- package/dist/commands/ui/modules/checks.js.map +1 -0
- package/dist/commands/ui/modules/cleanup.d.ts +2 -0
- package/dist/commands/ui/modules/cleanup.js +305 -0
- package/dist/commands/ui/modules/cleanup.js.map +1 -0
- package/dist/commands/ui/modules/image-batch-backups.d.ts +2 -0
- package/dist/commands/ui/modules/image-batch-backups.js +116 -0
- package/dist/commands/ui/modules/image-batch-backups.js.map +1 -0
- package/dist/commands/ui/modules/image-batch-manage.d.ts +2 -0
- package/dist/commands/ui/modules/image-batch-manage.js +245 -0
- package/dist/commands/ui/modules/image-batch-manage.js.map +1 -0
- package/dist/commands/ui/modules/image-batch.d.ts +2 -0
- package/dist/commands/ui/modules/image-batch.js +225 -0
- package/dist/commands/ui/modules/image-batch.js.map +1 -0
- package/dist/commands/ui/modules/image-hash.d.ts +2 -0
- package/dist/commands/ui/modules/image-hash.js +158 -0
- package/dist/commands/ui/modules/image-hash.js.map +1 -0
- package/dist/commands/ui/modules/index.d.ts +2 -0
- package/dist/commands/ui/modules/index.js +11 -0
- package/dist/commands/ui/modules/index.js.map +1 -0
- package/dist/commands/ui/open-browser.d.ts +1 -0
- package/dist/commands/ui/open-browser.js +18 -0
- package/dist/commands/ui/open-browser.js.map +1 -0
- package/dist/commands/ui/scan.d.ts +20 -0
- package/dist/commands/ui/scan.js +57 -0
- package/dist/commands/ui/scan.js.map +1 -0
- package/dist/commands/ui/server.d.ts +18 -0
- package/dist/commands/ui/server.js +196 -0
- package/dist/commands/ui/server.js.map +1 -0
- package/dist/ui/assets/ChecksPage-MLWSelKP.js +1 -0
- package/dist/ui/assets/ChecksPage-pbC0Txsh.css +1 -0
- package/dist/ui/assets/CleanupPage-B2ZTFOpP.js +4 -0
- package/dist/ui/assets/CleanupPage-k7sTI4iz.css +1 -0
- package/dist/ui/assets/FolderBrowser-BX3-y8sM.js +1 -0
- package/dist/ui/assets/FolderBrowser-DRh-WZPz.css +1 -0
- package/dist/ui/assets/ImageBatchPage-CvsCvu1q.js +4 -0
- package/dist/ui/assets/ImageBatchPage-DiK8ODUc.css +1 -0
- package/dist/ui/assets/ImageHashPage-Bbhxvjj0.js +1 -0
- package/dist/ui/assets/ImageHashPage-CUXnoJEA.css +1 -0
- package/dist/ui/assets/SourcePicker-C3qFDUoL.css +1 -0
- package/dist/ui/assets/SourcePicker-CVgtCk78.js +1 -0
- package/dist/ui/assets/UiSegmented-Q_ter8VK.css +1 -0
- package/dist/ui/assets/UiSegmented-YV1YATxM.js +1 -0
- package/dist/ui/assets/core-DVezgdzc.js +12 -0
- package/dist/ui/assets/css-Z72CF80r.js +1 -0
- package/dist/ui/assets/engine-javascript-CNmxVhbB.js +141 -0
- package/dist/ui/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/ui/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/ui/assets/highlight-CsAszz7F.js +2 -0
- package/dist/ui/assets/html-BlS82ilI.js +1 -0
- package/dist/ui/assets/index-BzfkjuG8.css +1 -0
- package/dist/ui/assets/index-pDKL0Y31.js +3 -0
- package/dist/ui/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/ui/assets/json-Cp-IABpG.js +1 -0
- package/dist/ui/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/ui/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/ui/assets/scss-Cw6XMfVs.js +1 -0
- package/dist/ui/assets/tsx-COt5Ahok.js +1 -0
- package/dist/ui/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/ui/assets/useCopy-vCfkPGWW.js +1 -0
- package/dist/ui/assets/vue-CwSeJimo.js +1 -0
- package/dist/ui/assets/yaml-Buea-lGh.js +1 -0
- package/dist/ui/index.html +17 -0
- package/package.json +17 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as oe,o as _,c as x,f as y,t as w,i as B,F,p as O,g as Z,h as ne,j as Ge,v as nt,y as pe,a as Q,n as H,r as L,A as P,b as le,w as me,H as ge,x as ke,C as Ee,P as st,Q as it,q as te,e as Ke,E as Le,k as Me,s as ye,z as ot,B as Pe}from"./index-pDKL0Y31.js";import{U as lt,F as at}from"./FolderBrowser-BX3-y8sM.js";import{U as rt}from"./UiSegmented-YV1YATxM.js";import{u as ut}from"./useCopy-vCfkPGWW.js";import{p as Fe,h as ct}from"./highlight-CsAszz7F.js";const ft={class:"overview"},vt={class:"card block"},dt={class:"head"},ht={key:0,class:"muted"},pt={key:1,class:"muted"},gt=["disabled"],yt={key:0,class:"check"},_t=["disabled"],mt={key:1,class:"progress-wrap",role:"status"},xt={class:"progress"},wt={class:"muted small"},kt={key:2,class:"chips"},$t={key:0,class:"sev sev--error"},bt={key:1,class:"sev sev--warning"},Ct={key:2,class:"sev"},Mt={key:3,class:"sev sev--ok"},Nt={class:"group__title"},St={class:"cards"},It=["onClick"],zt={class:"tile__top"},jt={class:"tile__state"},At={class:"tile__text muted"},Ot={key:0,class:"tile__sev"},Et={key:0,class:"sev sev--error"},Lt={key:1,class:"sev sev--warning"},Pt={key:2,class:"sev"},Ft={key:1,class:"tile__slow muted"},Tt=oe({__name:"ChecksOverview",props:{checks:{},outcomes:{},running:{type:Boolean},progress:{},tookMs:{}},emits:["run-all","open"],setup(e,{emit:n}){const t=e,o=n,s=L(!1),i=[{id:"code",title:"Code"},{id:"dependencies",title:"Dependencies"},{id:"docs",title:"Documentation"}],u=P(()=>t.checks.filter(f=>f.slow).map(f=>f.title)),l=P(()=>i.map(f=>({...f,items:t.checks.filter(r=>r.group===f.id)})).filter(f=>f.items.length>0)),h=P(()=>t.progress.total>0?Math.round(t.progress.done/t.progress.total*100):0),a=P(()=>t.checks.filter(f=>t.outcomes[f.id])),c=P(()=>a.value.filter(f=>{const r=t.outcomes[f.id];return r&&r.findings.length===0&&!r.error}).length),d=P(()=>{const f={error:0,warning:0,info:0};for(const r of a.value)for(const v of t.outcomes[r.id]?.findings??[])f[v.severity]+=1;return f}),m=P(()=>d.value.error+d.value.warning+d.value.info);function g(f){const r={error:0,warning:0,info:0};for(const v of t.outcomes[f]?.findings??[])r[v.severity]+=1;return r}function k(f){const r=t.outcomes[f];return r?r.error?"broken":r.findings.length===0?"clean":"found":"idle"}return(f,r)=>(_(),x("div",ft,[y("section",vt,[y("div",dt,[y("div",null,[r[3]||(r[3]=y("h2",null,"Project health",-1)),a.value.length?(_(),x("p",ht,[y("strong",null,w(c.value)+" of "+w(a.value.length),1),r[2]||(r[2]=B(" checks are clean · ",-1)),y("strong",null,w(m.value),1),B(" finding"+w(m.value===1?"":"s")+" ",1),e.tookMs!==void 0?(_(),x(F,{key:0},[B(" · "+w((e.tookMs/1e3).toFixed(1))+" s",1)],64)):O("",!0)])):(_(),x("p",pt,"Run every check at once to see where the project stands."))]),y("button",{class:"btn btn--primary",disabled:e.running,onClick:r[0]||(r[0]=v=>o("run-all",s.value))},[Z(ne,{name:"play",size:15}),B(" "+w(e.running?"Checking…":a.value.length?"Run all again":"Run all checks"),1)],8,gt)]),u.value.length?(_(),x("label",yt,[Ge(y("input",{"onUpdate:modelValue":r[1]||(r[1]=v=>s.value=v),type:"checkbox",disabled:e.running},null,8,_t),[[nt,s.value]]),y("span",null,[B(" Include the slow check ("+w(u.value.join(", "))+") ",1),r[4]||(r[4]=y("small",{class:"muted"}," — it type-checks the whole project",-1))])])):O("",!0),e.running?(_(),x("div",mt,[y("div",xt,[y("div",{class:"progress__bar",style:pe({width:`${h.value}%`})},null,4)]),y("span",wt,[B(w(e.progress.done)+" of "+w(e.progress.total)+" ",1),e.progress.current?(_(),x(F,{key:0},[B(" · "+w(e.progress.current),1)],64)):O("",!0)])])):O("",!0),a.value.length?(_(),x("div",kt,[d.value.error?(_(),x("span",$t,w(d.value.error)+" error"+w(d.value.error===1?"":"s"),1)):O("",!0),d.value.warning?(_(),x("span",bt,w(d.value.warning)+" warning"+w(d.value.warning===1?"":"s"),1)):O("",!0),d.value.info?(_(),x("span",Ct,w(d.value.info)+" note"+w(d.value.info===1?"":"s"),1)):O("",!0),m.value===0?(_(),x("span",Mt,"Everything is clean")):O("",!0)])):O("",!0)]),(_(!0),x(F,null,Q(l.value,v=>(_(),x("section",{key:v.id,class:"group"},[y("h3",Nt,w(v.title),1),y("div",St,[(_(!0),x(F,null,Q(v.items,p=>(_(),x("button",{key:p.id,class:H(["tile",`tile--${k(p.id)}`]),onClick:z=>o("open",p.id)},[y("span",zt,[y("strong",null,w(p.title),1),y("span",jt,[k(p.id)==="idle"?(_(),x(F,{key:0},[B("not run")],64)):k(p.id)==="clean"?(_(),x(F,{key:1},[B("✓ clean")],64)):k(p.id)==="broken"?(_(),x(F,{key:2},[B("couldn’t run")],64)):(_(),x(F,{key:3},[B(w(e.outcomes[p.id]?.findings.length),1)],64))])]),y("span",At,w(e.outcomes[p.id]?.summary??p.description),1),k(p.id)==="found"?(_(),x("span",Ot,[g(p.id).error?(_(),x("span",Et,w(g(p.id).error)+" error",1)):O("",!0),g(p.id).warning?(_(),x("span",Lt,w(g(p.id).warning)+" warning",1)):O("",!0),g(p.id).info?(_(),x("span",Pt,w(g(p.id).info)+" note",1)):O("",!0)])):O("",!0),p.slow&&k(p.id)==="idle"?(_(),x("span",Ft,"slow")):O("",!0)],10,It))),128))])]))),128))]))}}),Dt=le(Tt,[["__scopeId","data-v-0b1b992d"]]);function Bt(e,n){var t,o=1;e==null&&(e=0),n==null&&(n=0);function s(){var i,u=t.length,l,h=0,a=0;for(i=0;i<u;++i)l=t[i],h+=l.x,a+=l.y;for(h=(h/u-e)*o,a=(a/u-n)*o,i=0;i<u;++i)l=t[i],l.x-=h,l.y-=a}return s.initialize=function(i){t=i},s.x=function(i){return arguments.length?(e=+i,s):e},s.y=function(i){return arguments.length?(n=+i,s):n},s.strength=function(i){return arguments.length?(o=+i,s):o},s}function Rt(e){const n=+this._x.call(null,e),t=+this._y.call(null,e);return We(this.cover(n,t),n,t,e)}function We(e,n,t,o){if(isNaN(n)||isNaN(t))return e;var s,i=e._root,u={data:o},l=e._x0,h=e._y0,a=e._x1,c=e._y1,d,m,g,k,f,r,v,p;if(!i)return e._root=u,e;for(;i.length;)if((f=n>=(d=(l+a)/2))?l=d:a=d,(r=t>=(m=(h+c)/2))?h=m:c=m,s=i,!(i=i[v=r<<1|f]))return s[v]=u,e;if(g=+e._x.call(null,i.data),k=+e._y.call(null,i.data),n===g&&t===k)return u.next=i,s?s[v]=u:e._root=u,e;do s=s?s[v]=new Array(4):e._root=new Array(4),(f=n>=(d=(l+a)/2))?l=d:a=d,(r=t>=(m=(h+c)/2))?h=m:c=m;while((v=r<<1|f)===(p=(k>=m)<<1|g>=d));return s[p]=i,s[v]=u,e}function Ut(e){var n,t,o=e.length,s,i,u=new Array(o),l=new Array(o),h=1/0,a=1/0,c=-1/0,d=-1/0;for(t=0;t<o;++t)isNaN(s=+this._x.call(null,n=e[t]))||isNaN(i=+this._y.call(null,n))||(u[t]=s,l[t]=i,s<h&&(h=s),s>c&&(c=s),i<a&&(a=i),i>d&&(d=i));if(h>c||a>d)return this;for(this.cover(h,a).cover(c,d),t=0;t<o;++t)We(this,u[t],l[t],e[t]);return this}function Vt(e,n){if(isNaN(e=+e)||isNaN(n=+n))return this;var t=this._x0,o=this._y0,s=this._x1,i=this._y1;if(isNaN(t))s=(t=Math.floor(e))+1,i=(o=Math.floor(n))+1;else{for(var u=s-t||1,l=this._root,h,a;t>e||e>=s||o>n||n>=i;)switch(a=(n<o)<<1|e<t,h=new Array(4),h[a]=l,l=h,u*=2,a){case 0:s=t+u,i=o+u;break;case 1:t=s-u,i=o+u;break;case 2:s=t+u,o=i-u;break;case 3:t=s-u,o=i-u;break}this._root&&this._root.length&&(this._root=l)}return this._x0=t,this._y0=o,this._x1=s,this._y1=i,this}function Ht(){var e=[];return this.visit(function(n){if(!n.length)do e.push(n.data);while(n=n.next)}),e}function Yt(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function Y(e,n,t,o,s){this.node=e,this.x0=n,this.y0=t,this.x1=o,this.y1=s}function Xt(e,n,t){var o,s=this._x0,i=this._y0,u,l,h,a,c=this._x1,d=this._y1,m=[],g=this._root,k,f;for(g&&m.push(new Y(g,s,i,c,d)),t==null?t=1/0:(s=e-t,i=n-t,c=e+t,d=n+t,t*=t);k=m.pop();)if(!(!(g=k.node)||(u=k.x0)>c||(l=k.y0)>d||(h=k.x1)<s||(a=k.y1)<i))if(g.length){var r=(u+h)/2,v=(l+a)/2;m.push(new Y(g[3],r,v,h,a),new Y(g[2],u,v,r,a),new Y(g[1],r,l,h,v),new Y(g[0],u,l,r,v)),(f=(n>=v)<<1|e>=r)&&(k=m[m.length-1],m[m.length-1]=m[m.length-1-f],m[m.length-1-f]=k)}else{var p=e-+this._x.call(null,g.data),z=n-+this._y.call(null,g.data),C=p*p+z*z;if(C<t){var A=Math.sqrt(t=C);s=e-A,i=n-A,c=e+A,d=n+A,o=g.data}}return o}function Gt(e){if(isNaN(c=+this._x.call(null,e))||isNaN(d=+this._y.call(null,e)))return this;var n,t=this._root,o,s,i,u=this._x0,l=this._y0,h=this._x1,a=this._y1,c,d,m,g,k,f,r,v;if(!t)return this;if(t.length)for(;;){if((k=c>=(m=(u+h)/2))?u=m:h=m,(f=d>=(g=(l+a)/2))?l=g:a=g,n=t,!(t=t[r=f<<1|k]))return this;if(!t.length)break;(n[r+1&3]||n[r+2&3]||n[r+3&3])&&(o=n,v=r)}for(;t.data!==e;)if(s=t,!(t=t.next))return this;return(i=t.next)&&delete t.next,s?(i?s.next=i:delete s.next,this):n?(i?n[r]=i:delete n[r],(t=n[0]||n[1]||n[2]||n[3])&&t===(n[3]||n[2]||n[1]||n[0])&&!t.length&&(o?o[v]=t:this._root=t),this):(this._root=i,this)}function Kt(e){for(var n=0,t=e.length;n<t;++n)this.remove(e[n]);return this}function Wt(){return this._root}function Qt(){var e=0;return this.visit(function(n){if(!n.length)do++e;while(n=n.next)}),e}function Jt(e){var n=[],t,o=this._root,s,i,u,l,h;for(o&&n.push(new Y(o,this._x0,this._y0,this._x1,this._y1));t=n.pop();)if(!e(o=t.node,i=t.x0,u=t.y0,l=t.x1,h=t.y1)&&o.length){var a=(i+l)/2,c=(u+h)/2;(s=o[3])&&n.push(new Y(s,a,c,l,h)),(s=o[2])&&n.push(new Y(s,i,c,a,h)),(s=o[1])&&n.push(new Y(s,a,u,l,c)),(s=o[0])&&n.push(new Y(s,i,u,a,c))}return this}function Zt(e){var n=[],t=[],o;for(this._root&&n.push(new Y(this._root,this._x0,this._y0,this._x1,this._y1));o=n.pop();){var s=o.node;if(s.length){var i,u=o.x0,l=o.y0,h=o.x1,a=o.y1,c=(u+h)/2,d=(l+a)/2;(i=s[0])&&n.push(new Y(i,u,l,c,d)),(i=s[1])&&n.push(new Y(i,c,l,h,d)),(i=s[2])&&n.push(new Y(i,u,d,c,a)),(i=s[3])&&n.push(new Y(i,c,d,h,a))}t.push(o)}for(;o=t.pop();)e(o.node,o.x0,o.y0,o.x1,o.y1);return this}function qt(e){return e[0]}function en(e){return arguments.length?(this._x=e,this):this._x}function tn(e){return e[1]}function nn(e){return arguments.length?(this._y=e,this):this._y}function Ae(e,n,t){var o=new Oe(n??qt,t??tn,NaN,NaN,NaN,NaN);return e==null?o:o.addAll(e)}function Oe(e,n,t,o,s,i){this._x=e,this._y=n,this._x0=t,this._y0=o,this._x1=s,this._y1=i,this._root=void 0}function Te(e){for(var n={data:e.data},t=n;e=e.next;)t=t.next={data:e.data};return n}var G=Ae.prototype=Oe.prototype;G.copy=function(){var e=new Oe(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root,t,o;if(!n)return e;if(!n.length)return e._root=Te(n),e;for(t=[{source:n,target:e._root=new Array(4)}];n=t.pop();)for(var s=0;s<4;++s)(o=n.source[s])&&(o.length?t.push({source:o,target:n.target[s]=new Array(4)}):n.target[s]=Te(o));return e};G.add=Rt;G.addAll=Ut;G.cover=Vt;G.data=Ht;G.extent=Yt;G.find=Xt;G.remove=Gt;G.removeAll=Kt;G.root=Wt;G.size=Qt;G.visit=Jt;G.visitAfter=Zt;G.x=en;G.y=nn;function X(e){return function(){return e}}function se(e){return(e()-.5)*1e-6}function sn(e){return e.x+e.vx}function on(e){return e.y+e.vy}function ln(e){var n,t,o,s=1,i=1;typeof e!="function"&&(e=X(e==null?1:+e));function u(){for(var a,c=n.length,d,m,g,k,f,r,v=0;v<i;++v)for(d=Ae(n,sn,on).visitAfter(l),a=0;a<c;++a)m=n[a],f=t[m.index],r=f*f,g=m.x+m.vx,k=m.y+m.vy,d.visit(p);function p(z,C,A,T,N){var $=z.data,S=z.r,E=f+S;if($){if($.index>m.index){var D=g-$.x-$.vx,R=k-$.y-$.vy,j=D*D+R*R;j<E*E&&(D===0&&(D=se(o),j+=D*D),R===0&&(R=se(o),j+=R*R),j=(E-(j=Math.sqrt(j)))/j*s,m.vx+=(D*=j)*(E=(S*=S)/(r+S)),m.vy+=(R*=j)*E,$.vx-=D*(E=1-E),$.vy-=R*E)}return}return C>g+E||T<g-E||A>k+E||N<k-E}}function l(a){if(a.data)return a.r=t[a.data.index];for(var c=a.r=0;c<4;++c)a[c]&&a[c].r>a.r&&(a.r=a[c].r)}function h(){if(n){var a,c=n.length,d;for(t=new Array(c),a=0;a<c;++a)d=n[a],t[d.index]=+e(d,a,n)}}return u.initialize=function(a,c){n=a,o=c,h()},u.iterations=function(a){return arguments.length?(i=+a,u):i},u.strength=function(a){return arguments.length?(s=+a,u):s},u.radius=function(a){return arguments.length?(e=typeof a=="function"?a:X(+a),h(),u):e},u}function an(e){return e.index}function De(e,n){var t=e.get(n);if(!t)throw new Error("node not found: "+n);return t}function rn(e){var n=an,t=d,o,s=X(30),i,u,l,h,a,c=1;e==null&&(e=[]);function d(r){return 1/Math.min(l[r.source.index],l[r.target.index])}function m(r){for(var v=0,p=e.length;v<c;++v)for(var z=0,C,A,T,N,$,S,E;z<p;++z)C=e[z],A=C.source,T=C.target,N=T.x+T.vx-A.x-A.vx||se(a),$=T.y+T.vy-A.y-A.vy||se(a),S=Math.sqrt(N*N+$*$),S=(S-i[z])/S*r*o[z],N*=S,$*=S,T.vx-=N*(E=h[z]),T.vy-=$*E,A.vx+=N*(E=1-E),A.vy+=$*E}function g(){if(u){var r,v=u.length,p=e.length,z=new Map(u.map((A,T)=>[n(A,T,u),A])),C;for(r=0,l=new Array(v);r<p;++r)C=e[r],C.index=r,typeof C.source!="object"&&(C.source=De(z,C.source)),typeof C.target!="object"&&(C.target=De(z,C.target)),l[C.source.index]=(l[C.source.index]||0)+1,l[C.target.index]=(l[C.target.index]||0)+1;for(r=0,h=new Array(p);r<p;++r)C=e[r],h[r]=l[C.source.index]/(l[C.source.index]+l[C.target.index]);o=new Array(p),k(),i=new Array(p),f()}}function k(){if(u)for(var r=0,v=e.length;r<v;++r)o[r]=+t(e[r],r,e)}function f(){if(u)for(var r=0,v=e.length;r<v;++r)i[r]=+s(e[r],r,e)}return m.initialize=function(r,v){u=r,a=v,g()},m.links=function(r){return arguments.length?(e=r,g(),m):e},m.id=function(r){return arguments.length?(n=r,m):n},m.iterations=function(r){return arguments.length?(c=+r,m):c},m.strength=function(r){return arguments.length?(t=typeof r=="function"?r:X(+r),k(),m):t},m.distance=function(r){return arguments.length?(s=typeof r=="function"?r:X(+r),f(),m):s},m}var un={value:()=>{}};function Qe(){for(var e=0,n=arguments.length,t={},o;e<n;++e){if(!(o=arguments[e]+"")||o in t||/[\s.]/.test(o))throw new Error("illegal type: "+o);t[o]=[]}return new _e(t)}function _e(e){this._=e}function cn(e,n){return e.trim().split(/^|\s+/).map(function(t){var o="",s=t.indexOf(".");if(s>=0&&(o=t.slice(s+1),t=t.slice(0,s)),t&&!n.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:o}})}_e.prototype=Qe.prototype={constructor:_e,on:function(e,n){var t=this._,o=cn(e+"",t),s,i=-1,u=o.length;if(arguments.length<2){for(;++i<u;)if((s=(e=o[i]).type)&&(s=fn(t[s],e.name)))return s;return}if(n!=null&&typeof n!="function")throw new Error("invalid callback: "+n);for(;++i<u;)if(s=(e=o[i]).type)t[s]=Be(t[s],e.name,n);else if(n==null)for(s in t)t[s]=Be(t[s],e.name,null);return this},copy:function(){var e={},n=this._;for(var t in n)e[t]=n[t].slice();return new _e(e)},call:function(e,n){if((s=arguments.length-2)>0)for(var t=new Array(s),o=0,s,i;o<s;++o)t[o]=arguments[o+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(i=this._[e],o=0,s=i.length;o<s;++o)i[o].value.apply(n,t)},apply:function(e,n,t){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var o=this._[e],s=0,i=o.length;s<i;++s)o[s].value.apply(n,t)}};function fn(e,n){for(var t=0,o=e.length,s;t<o;++t)if((s=e[t]).name===n)return s.value}function Be(e,n,t){for(var o=0,s=e.length;o<s;++o)if(e[o].name===n){e[o]=un,e=e.slice(0,o).concat(e.slice(o+1));break}return t!=null&&e.push({name:n,value:t}),e}var ae=0,ce=0,re=0,Je=1e3,xe,fe,we=0,ie=0,$e=0,ve=typeof performance=="object"&&performance.now?performance:Date,Ze=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function qe(){return ie||(Ze(vn),ie=ve.now()+$e)}function vn(){ie=0}function ze(){this._call=this._time=this._next=null}ze.prototype=et.prototype={constructor:ze,restart:function(e,n,t){if(typeof e!="function")throw new TypeError("callback is not a function");t=(t==null?qe():+t)+(n==null?0:+n),!this._next&&fe!==this&&(fe?fe._next=this:xe=this,fe=this),this._call=e,this._time=t,je()},stop:function(){this._call&&(this._call=null,this._time=1/0,je())}};function et(e,n,t){var o=new ze;return o.restart(e,n,t),o}function dn(){qe(),++ae;for(var e=xe,n;e;)(n=ie-e._time)>=0&&e._call.call(void 0,n),e=e._next;--ae}function Re(){ie=(we=ve.now())+$e,ae=ce=0;try{dn()}finally{ae=0,pn(),ie=0}}function hn(){var e=ve.now(),n=e-we;n>Je&&($e-=n,we=e)}function pn(){for(var e,n=xe,t,o=1/0;n;)n._call?(o>n._time&&(o=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:xe=t);fe=e,je(o)}function je(e){if(!ae){ce&&(ce=clearTimeout(ce));var n=e-ie;n>24?(e<1/0&&(ce=setTimeout(Re,e-ve.now()-$e)),re&&(re=clearInterval(re))):(re||(we=ve.now(),re=setInterval(hn,Je)),ae=1,Ze(Re))}}const gn=1664525,yn=1013904223,Ue=4294967296;function _n(){let e=1;return()=>(e=(gn*e+yn)%Ue)/Ue}function mn(e){return e.x}function xn(e){return e.y}var wn=10,kn=Math.PI*(3-Math.sqrt(5));function $n(e){var n,t=1,o=.001,s=1-Math.pow(o,1/300),i=0,u=.6,l=new Map,h=et(d),a=Qe("tick","end"),c=_n();e==null&&(e=[]);function d(){m(),a.call("tick",n),t<o&&(h.stop(),a.call("end",n))}function m(f){var r,v=e.length,p;f===void 0&&(f=1);for(var z=0;z<f;++z)for(t+=(i-t)*s,l.forEach(function(C){C(t)}),r=0;r<v;++r)p=e[r],p.fx==null?p.x+=p.vx*=u:(p.x=p.fx,p.vx=0),p.fy==null?p.y+=p.vy*=u:(p.y=p.fy,p.vy=0);return n}function g(){for(var f=0,r=e.length,v;f<r;++f){if(v=e[f],v.index=f,v.fx!=null&&(v.x=v.fx),v.fy!=null&&(v.y=v.fy),isNaN(v.x)||isNaN(v.y)){var p=wn*Math.sqrt(.5+f),z=f*kn;v.x=p*Math.cos(z),v.y=p*Math.sin(z)}(isNaN(v.vx)||isNaN(v.vy))&&(v.vx=v.vy=0)}}function k(f){return f.initialize&&f.initialize(e,c),f}return g(),n={tick:m,restart:function(){return h.restart(d),n},stop:function(){return h.stop(),n},nodes:function(f){return arguments.length?(e=f,g(),l.forEach(k),n):e},alpha:function(f){return arguments.length?(t=+f,n):t},alphaMin:function(f){return arguments.length?(o=+f,n):o},alphaDecay:function(f){return arguments.length?(s=+f,n):+s},alphaTarget:function(f){return arguments.length?(i=+f,n):i},velocityDecay:function(f){return arguments.length?(u=1-f,n):1-u},randomSource:function(f){return arguments.length?(c=f,l.forEach(k),n):c},force:function(f,r){return arguments.length>1?(r==null?l.delete(f):l.set(f,k(r)),n):l.get(f)},find:function(f,r,v){var p=0,z=e.length,C,A,T,N,$;for(v==null?v=1/0:v*=v,p=0;p<z;++p)N=e[p],C=f-N.x,A=r-N.y,T=C*C+A*A,T<v&&($=N,v=T);return $},on:function(f,r){return arguments.length>1?(a.on(f,r),n):a.on(f)}}}function bn(){var e,n,t,o,s=X(-30),i,u=1,l=1/0,h=.81;function a(g){var k,f=e.length,r=Ae(e,mn,xn).visitAfter(d);for(o=g,k=0;k<f;++k)n=e[k],r.visit(m)}function c(){if(e){var g,k=e.length,f;for(i=new Array(k),g=0;g<k;++g)f=e[g],i[f.index]=+s(f,g,e)}}function d(g){var k=0,f,r,v=0,p,z,C;if(g.length){for(p=z=C=0;C<4;++C)(f=g[C])&&(r=Math.abs(f.value))&&(k+=f.value,v+=r,p+=r*f.x,z+=r*f.y);g.x=p/v,g.y=z/v}else{f=g,f.x=f.data.x,f.y=f.data.y;do k+=i[f.data.index];while(f=f.next)}g.value=k}function m(g,k,f,r){if(!g.value)return!0;var v=g.x-n.x,p=g.y-n.y,z=r-k,C=v*v+p*p;if(z*z/h<C)return C<l&&(v===0&&(v=se(t),C+=v*v),p===0&&(p=se(t),C+=p*p),C<u&&(C=Math.sqrt(u*C)),n.vx+=v*g.value*o/C,n.vy+=p*g.value*o/C),!0;if(g.length||C>=l)return;(g.data!==n||g.next)&&(v===0&&(v=se(t),C+=v*v),p===0&&(p=se(t),C+=p*p),C<u&&(C=Math.sqrt(u*C)));do g.data!==n&&(z=i[g.data.index]*o/C,n.vx+=v*z,n.vy+=p*z);while(g=g.next)}return a.initialize=function(g,k){e=g,t=k,c()},a.strength=function(g){return arguments.length?(s=typeof g=="function"?g:X(+g),c(),a):s},a.distanceMin=function(g){return arguments.length?(u=g*g,a):Math.sqrt(u)},a.distanceMax=function(g){return arguments.length?(l=g*g,a):Math.sqrt(l)},a.theta=function(g){return arguments.length?(h=g*g,a):Math.sqrt(h)},a}function Cn(e){var n=X(.1),t,o,s;typeof e!="function"&&(e=X(e==null?0:+e));function i(l){for(var h=0,a=t.length,c;h<a;++h)c=t[h],c.vx+=(s[h]-c.x)*o[h]*l}function u(){if(t){var l,h=t.length;for(o=new Array(h),s=new Array(h),l=0;l<h;++l)o[l]=isNaN(s[l]=+e(t[l],l,t))?0:+n(t[l],l,t)}}return i.initialize=function(l){t=l,u()},i.strength=function(l){return arguments.length?(n=typeof l=="function"?l:X(+l),u(),i):n},i.x=function(l){return arguments.length?(e=typeof l=="function"?l:X(+l),u(),i):e},i}function Mn(e){var n=X(.1),t,o,s;typeof e!="function"&&(e=X(e==null?0:+e));function i(l){for(var h=0,a=t.length,c;h<a;++h)c=t[h],c.vy+=(s[h]-c.y)*o[h]*l}function u(){if(t){var l,h=t.length;for(o=new Array(h),s=new Array(h),l=0;l<h;++l)o[l]=isNaN(s[l]=+e(t[l],l,t))?0:+n(t[l],l,t)}}return i.initialize=function(l){t=l,u()},i.strength=function(l){return arguments.length?(n=typeof l=="function"?l:X(+l),u(),i):n},i.y=function(l){return arguments.length?(e=typeof l=="function"?l:X(+l),u(),i):e},i}const Nn={class:"graph"},Sn=["viewBox"],In=["d","marker-end"],zn=["transform","aria-label","onMouseenter","onFocus","onClick","onKeydown"],jn={class:"node__label",y:"-16","text-anchor":"middle"},An={key:0,class:"node__dir",y:"26","text-anchor":"middle"},On={class:"graph__bar"},Ne=900,Se=560,ue=9,En=oe({__name:"CycleGraph",props:{cycles:{},selected:{}},emits:["select-cycle","open-file"],setup(e,{emit:n}){const t=e,o=n,s=L(null),i=L({x:0,y:0,w:Ne,h:Se}),u=L({x:0,y:0,w:Ne,h:Se}),l=L(null),h=L();function a(N){return N.split("/").pop()??N}function c(N){const $=N.split("/");return $.pop(),$.join("/")}const d=P(()=>{const N=new Map,$=new Map;for(const j of t.cycles)j.files.forEach((U,K)=>{const J=N.get(U)??{id:U,label:a(U),dir:c(U),cycles:new Set};J.cycles.add(j.id),N.set(U,J);const q=j.files[(K+1)%j.files.length],V=`${U}>${q}`,ee=$.get(V)??{key:V,from:U,to:q,cycles:new Set,typeOnly:!0};ee.cycles.add(j.id),j.typeOnly||(ee.typeOnly=!1),$.set(V,ee)});const S=[...N.values()];S.forEach((j,U)=>{const K=U/Math.max(S.length,1)*Math.PI*2;j.x=Math.cos(K)*160,j.y=Math.sin(K)*160});const E=[...$.values()].map(j=>({source:j.from,target:j.to})),D=$n(S).force("link",rn(E).id(j=>j.id).distance(120)).force("charge",bn().strength(-300)).force("x",Cn(0).strength(.09)).force("y",Mn(0).strength(.09)).force("center",Bt(0,0)).force("collide",ln(46)).stop(),R=Math.min(400,120+S.length*4);for(let j=0;j<R;j++)D.tick();return{nodes:S,edges:[...$.values()]}}),m=P(()=>new Map(d.value.nodes.map(N=>[N.id,{x:N.x??0,y:N.y??0}])));function g(){const N=[...m.value.values()];if(N.length===0)return;const $=90,S=Math.min(...N.map(V=>V.x))-$,E=Math.max(...N.map(V=>V.x))+$,D=Math.min(...N.map(V=>V.y))-$,R=Math.max(...N.map(V=>V.y))+$;let j=E-S,U=R-D;const K=h.value?.getBoundingClientRect(),J=K&&K.height>0?K.width/K.height:Ne/Se;j/U<J?j=U*J:U=j/J;const q={x:(S+E)/2-j/2,y:(D+R)/2-U/2,w:j,h:U};u.value=q,i.value={...q}}me(d,()=>ge(g)),ke(g);const k=P(()=>t.cycles.find(N=>N.id===t.selected));function f(N){return k.value?N.cycles.has(k.value.id):s.value?N.id===s.value||d.value.edges.some($=>$.from===s.value&&$.to===N.id||$.to===s.value&&$.from===N.id):!0}function r(N){return k.value?N.cycles.has(k.value.id):s.value?N.from===s.value||N.to===s.value:!0}function v(N){const $=m.value.get(N.from),S=m.value.get(N.to);if(!$||!S)return"";const E=S.x-$.x,D=S.y-$.y,R=Math.hypot(E,D)||1,j=E/R,U=D/R,K=$.x+j*(ue+2),J=$.y+U*(ue+2),q=S.x-j*(ue+7),V=S.y-U*(ue+7),ee=Math.min(26,R*.18),be=(K+q)/2-U*ee,Ce=(J+V)/2+j*ee;return`M ${K} ${J} Q ${be} ${Ce} ${q} ${V}`}function p(N){N.preventDefault();const $=h.value?.getBoundingClientRect();if(!$)return;const S=N.deltaY>0?1.15:1/1.15,E=Math.min(Math.max(i.value.w*S,u.value.w/8),u.value.w*4),D=E/(i.value.w/i.value.h),R=(N.clientX-$.left)/$.width,j=(N.clientY-$.top)/$.height;i.value={x:i.value.x+(i.value.w-E)*R,y:i.value.y+(i.value.h-D)*j,w:E,h:D}}function z(N){N.target.closest(".node")||(l.value={x:N.clientX,y:N.clientY},N.currentTarget.setPointerCapture(N.pointerId))}function C(N){const $=l.value,S=h.value?.getBoundingClientRect();!$||!S||(i.value={...i.value,x:i.value.x-(N.clientX-$.x)/S.width*i.value.w,y:i.value.y-(N.clientY-$.y)/S.height*i.value.h},l.value={x:N.clientX,y:N.clientY})}function A(){l.value=null}function T(N){return N.cycles.size>1?"node--hub":"node--single"}return(N,$)=>(_(),x("div",Nn,[(_(),x("svg",{ref_key:"svg",ref:h,class:H(["graph__svg",{"graph__svg--drag":l.value}]),viewBox:`${i.value.x} ${i.value.y} ${i.value.w} ${i.value.h}`,role:"img","aria-label":"Graph of the import cycles",onWheel:p,onPointerdown:z,onPointermove:C,onPointerup:A,onClick:$[2]||($[2]=Ee(S=>o("select-cycle",null),["self"]))},[$[4]||($[4]=y("defs",null,[y("marker",{id:"arrow",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"7",markerHeight:"7",orient:"auto-start-reverse"},[y("path",{d:"M 0 0 L 10 5 L 0 10 z",class:"arrow"})]),y("marker",{id:"arrow-on",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"7",markerHeight:"7",orient:"auto-start-reverse"},[y("path",{d:"M 0 0 L 10 5 L 0 10 z",class:"arrow arrow--on"})])],-1)),(_(!0),x(F,null,Q(d.value.edges,S=>(_(),x("path",{key:S.key,class:H(["edge",{"edge--dim":!r(S),"edge--on":!!k.value&&r(S),"edge--type":S.typeOnly,"edge--strong":S.cycles.size>1}]),d:v(S),"marker-end":k.value&&r(S)?"url(#arrow-on)":"url(#arrow)"},null,10,In))),128)),(_(!0),x(F,null,Q(d.value.nodes,S=>(_(),x("g",{key:S.id,class:H(["node",[T(S),{"node--dim":!f(S)}]]),transform:`translate(${S.x??0}, ${S.y??0})`,tabindex:"0",role:"button","aria-label":`${S.id}, in ${S.cycles.size} cycle${S.cycles.size===1?"":"s"}`,onMouseenter:E=>s.value=S.id,onMouseleave:$[0]||($[0]=E=>s.value=null),onFocus:E=>s.value=S.id,onBlur:$[1]||($[1]=E=>s.value=null),onClick:Ee(E=>o("open-file",S.id),["stop"]),onKeydown:st(E=>o("open-file",S.id),["enter"])},[y("title",null,w(S.id)+" — in "+w(S.cycles.size)+" cycle"+w(S.cycles.size===1?"":"s"),1),y("circle",{r:ue,class:"node__dot"}),y("text",jn,w(S.label),1),S.dir?(_(),x("text",An,w(S.dir),1)):O("",!0)],42,zn))),128))],42,Sn)),y("div",On,[$[5]||($[5]=it('<span class="legend" data-v-2ff3fdf0><i class="legend__dot legend__dot--single" data-v-2ff3fdf0></i> in one cycle</span><span class="legend" data-v-2ff3fdf0><i class="legend__dot legend__dot--hub" data-v-2ff3fdf0></i> in several cycles</span><span class="legend" data-v-2ff3fdf0><i class="legend__line legend__line--type" data-v-2ff3fdf0></i> type-only import</span><span class="spacer" data-v-2ff3fdf0></span>',4)),y("button",{class:"btn btn--small",onClick:$[3]||($[3]=S=>i.value={...u.value})},"Fit to screen")]),$[6]||($[6]=y("p",{class:"muted small"}," Scroll to zoom, drag to move. Click a file to open it, or pick a cycle in the list to light it up. ",-1))]))}}),Ln=le(En,[["__scopeId","data-v-2ff3fdf0"]]),Pn={class:"groups"},Fn=["aria-expanded","onClick"],Tn={class:"group__file"},Dn={class:"group__count"},Bn={key:0,class:"items"},Rn=["onClick"],Un={class:"item__place"},Vn=["title"],Hn={class:"item__text"},Yn={class:"item__message"},Xn={key:0,class:"item__hint muted"},Gn={class:"item__code"},Kn={key:0,class:"more"},Ve=40,Wn=oe({__name:"FindingsList",props:{findings:{}},emits:["open"],setup(e,{emit:n}){const t=e,o=n,s=L(Ve),i=L(new Set),u=P(()=>{const a=new Map;for(const c of t.findings){const d=c.file??"Project",m=a.get(d);m?m.push(c):a.set(d,[c])}return[...a.entries()].map(([c,d])=>({file:c,items:[...d].sort((m,g)=>(m.line??0)-(g.line??0))})).sort((c,d)=>c.file.localeCompare(d.file))});function l(a){const c=new Set(i.value);c.has(a)?c.delete(a):c.add(a),i.value=c}function h(a){return a.line?a.column?`${a.line}:${a.column}`:String(a.line):""}return(a,c)=>(_(),x("div",Pn,[(_(!0),x(F,null,Q(u.value.slice(0,s.value),d=>(_(),x("section",{key:d.file,class:"group"},[y("button",{class:"group__head","aria-expanded":!i.value.has(d.file),onClick:m=>l(d.file)},[y("span",{class:H(["group__caret",{"group__caret--open":!i.value.has(d.file)}])},"▸",2),y("code",Tn,w(d.file),1),y("span",Dn,w(d.items.length),1)],8,Fn),i.value.has(d.file)?O("",!0):(_(),x("ul",Bn,[(_(!0),x(F,null,Q(d.items,(m,g)=>(_(),x("li",{key:g,class:"item"},[y("button",{class:"item__main",onClick:k=>o("open",m)},[y("span",Un,w(h(m)),1),y("span",{class:H(["dot",`dot--${m.severity}`]),title:m.severity},null,10,Vn),y("span",Hn,[y("span",Yn,w(m.message),1),m.hint?(_(),x("span",Xn,w(m.hint),1)):O("",!0)]),y("span",Gn,w(m.code),1)],8,Rn)]))),128))]))]))),128)),s.value<u.value.length?(_(),x("div",Kn,[y("button",{class:"btn",onClick:c[0]||(c[0]=d=>s.value+=Ve)}," Show more files ("+w(u.value.length-s.value)+" left) ",1),y("button",{class:"btn",onClick:c[1]||(c[1]=d=>s.value=u.value.length)},"Show all")])):O("",!0)]))}}),tt=le(Wn,[["__scopeId","data-v-86eeb72c"]]),Qn={class:"cycles"},Jn={key:0,class:"split"},Zn={class:"side","aria-label":"Cycles"},qn={class:"side__title"},es={class:"side__list"},ts=["onClick"],ns={class:"cycle__head"},ss={class:"muted"},is={key:0,class:"cycle__tag"},os={class:"cycle__chain"},ls=oe({__name:"CyclesView",props:{findings:{}},emits:["open-file","open"],setup(e,{emit:n}){const t=e,o=n,s=L("graph"),i=L(null),u=P(()=>t.findings.filter(a=>a.files&&a.files.length>0).map((a,c)=>({id:c,files:a.files,typeOnly:a.code==="type-only"})));function l(a){i.value=i.value===a?null:a}function h(a){return[...a.files.map(c=>c.split("/").pop()??c),a.files[0]?.split("/").pop()].join(" → ")}return(a,c)=>(_(),x("div",Qn,[Z(rt,{modelValue:s.value,"onUpdate:modelValue":c[0]||(c[0]=d=>s.value=d),label:"View",options:[{value:"graph",label:"Graph"},{value:"list",label:"List"}]},null,8,["modelValue"]),s.value==="graph"?(_(),x("div",Jn,[Z(Ln,{cycles:u.value,selected:i.value,onSelectCycle:c[1]||(c[1]=d=>i.value=d),onOpenFile:c[2]||(c[2]=d=>o("open-file",d))},null,8,["cycles","selected"]),y("aside",Zn,[y("h3",qn,w(u.value.length)+" cycle"+w(u.value.length===1?"":"s"),1),y("ul",es,[(_(!0),x(F,null,Q(u.value,d=>(_(),x("li",{key:d.id},[y("button",{class:H(["cycle",{"cycle--on":i.value===d.id}]),onClick:m=>l(d.id)},[y("span",ns,[y("strong",null,"Cycle "+w(d.id+1),1),y("span",ss,w(d.files.length)+" files",1),d.typeOnly?(_(),x("span",is,"types only")):O("",!0)]),y("span",os,w(h(d)),1)],10,ts)]))),128))])])])):(_(),te(tt,{key:1,findings:e.findings,onOpen:c[3]||(c[3]=d=>o("open",d))},null,8,["findings"]))]))}}),as=le(ls,[["__scopeId","data-v-7482ac93"]]),rs={key:0,class:"code__note"},us=["data-focus"],cs={class:"line__text"},fs={key:0},Ie=400,vs=1500,ds=oe({__name:"UiCode",props:{text:{},lang:{},focusLine:{},focusColumn:{}},setup(e){const n=e,t=L(Fe(n.text)),o=L(!1),s=L(),i=P(()=>t.value.length),u=P(()=>!o.value&&i.value>vs),l=P(()=>{if(!u.value)return 0;const g=n.focusLine??1;return Math.max(0,Math.min(g-1-Ie/2,i.value-Ie))}),h=P(()=>u.value?Math.min(i.value,l.value+Ie):i.value),a=P(()=>t.value.slice(l.value,h.value)),c=P(()=>String(i.value).length);async function d(){t.value=Fe(n.text),t.value=await ct(n.text,n.lang),await ge(),m()}function m(){const g=s.value?.querySelector('[data-focus="true"]');if(g instanceof HTMLElement&&s.value){const k=s.value;k.scrollTop=g.offsetTop-k.clientHeight/2+g.clientHeight/2}}return me(()=>[n.text,n.lang],d),me(()=>[n.focusLine,n.focusColumn],async()=>{await ge(),m()}),ke(d),(g,k)=>(_(),x("div",{ref_key:"scroller",ref:s,class:"code",tabindex:"0",role:"region","aria-label":"Source code"},[u.value?(_(),x("p",rs,[B(" Showing lines "+w(l.value+1)+"–"+w(h.value)+" of "+w(i.value)+". ",1),y("button",{class:"code__link",onClick:k[0]||(k[0]=f=>(o.value=!0,ge().then(m)))}," Show the whole file ")])):O("",!0),(_(!0),x(F,null,Q(a.value,(f,r)=>(_(),x("div",{key:l.value+r,class:H(["line",{"line--focus":l.value+r+1===e.focusLine}]),"data-focus":l.value+r+1===e.focusLine},[y("span",{class:"line__no",style:pe({width:`${c.value+1}ch`})},w(l.value+r+1),5),y("span",cs,[(_(!0),x(F,null,Q(f,(v,p)=>(_(),x("span",{key:p,class:H(["tok",{"tok--bold":v.bold,"tok--italic":v.italic}]),style:pe({"--light":v.light||"var(--text)","--dark":v.dark||"var(--text)"})},w(v.text),7))),128)),!f.length||f.length===1&&f[0]?.text===""?(_(),x("span",fs," ")):O("",!0)]),l.value+r+1===e.focusLine&&e.focusColumn?(_(),x("span",{key:0,class:"line__marker",style:pe({left:`calc(${c.value+1}ch + ${Math.max(0,e.focusColumn-1)}ch + 12px)`})},null,4)):O("",!0)],10,us))),128))],512))}}),hs=le(ds,[["__scopeId","data-v-f2eb8c06"]]),ps={class:"muted counter"},gs=["disabled"],ys=["disabled"],_s={class:"body"},ms={class:"finding"},xs={key:0,class:"muted"},ws={key:0,class:"notice notice--error"},ks={key:1,class:"muted"},$s={key:2,class:"muted"},bs={class:"bar"},Cs={class:"path"},Ms=["href"],Ns=oe({__name:"SourceModal",props:{project:{},findings:{},index:{}},emits:["close","update:index"],setup(e,{emit:n}){const t=e,o=n,{copied:s,copy:i}=ut(),u=L(),l=L(""),h=L(!1),a=new Map,c=P(()=>t.findings[t.index]),d=P(()=>t.index>0),m=P(()=>t.index<t.findings.length-1),g=P(()=>{if(!u.value)return"";const v=[u.value.abs.replace(/\\/g,"/")];return c.value.line&&v.push(String(c.value.line)),c.value.line&&c.value.column&&v.push(String(c.value.column)),`vscode://file/${v.join(":")}`});async function k(){const v=c.value.file;if(l.value="",!v){u.value=void 0;return}const p=a.get(v);if(p){u.value=p;return}h.value=!0;try{const z=await ye.get(`/api/source?project=${encodeURIComponent(t.project)}&path=${encodeURIComponent(v)}`);a.set(v,z),u.value=z}catch(z){u.value=void 0,l.value=z instanceof Error?z.message:String(z)}finally{h.value=!1}}function f(v){const p=t.index+v;p>=0&&p<t.findings.length&&o("update:index",p)}function r(v){v.target instanceof HTMLInputElement||(v.key==="ArrowLeft"&&f(-1),v.key==="ArrowRight"&&f(1))}return me(()=>t.index,k,{immediate:!0}),ke(()=>window.addEventListener("keydown",r)),Ke(()=>window.removeEventListener("keydown",r)),(v,p)=>(_(),te(lt,{title:c.value.file??"Project",width:"1100px",onClose:p[3]||(p[3]=z=>o("close"))},{actions:Le(()=>[y("span",ps,w(e.index+1)+" / "+w(e.findings.length),1),y("button",{class:"btn btn--small",disabled:!d.value,"aria-label":"Previous finding",onClick:p[0]||(p[0]=z=>f(-1))},[Z(ne,{name:"left",size:15})],8,gs),y("button",{class:"btn btn--small",disabled:!m.value,"aria-label":"Next finding",onClick:p[1]||(p[1]=z=>f(1))},[Z(ne,{name:"right",size:15})],8,ys)]),default:Le(()=>[y("div",_s,[y("div",ms,[y("span",{class:H(["badge",`badge--${c.value.severity}`])},w(c.value.code),3),y("strong",null,w(c.value.message),1),c.value.hint?(_(),x("p",xs,w(c.value.hint),1)):O("",!0)]),l.value?(_(),x("p",ws,w(l.value),1)):h.value?(_(),x("p",ks,"Loading…")):c.value.file?u.value?(_(),x(F,{key:3},[y("div",bs,[y("code",Cs,[B(w(u.value.path),1),c.value.line?(_(),x(F,{key:0},[B(":"+w(c.value.line),1)],64)):O("",!0)]),y("button",{class:"btn btn--small",onClick:p[2]||(p[2]=z=>Me(i)("path",u.value.abs))},[Z(ne,{name:Me(s)==="path"?"check":"copy",size:14},null,8,["name"]),B(" "+w(Me(s)==="path"?"Copied":"Copy path"),1)]),y("a",{class:"btn btn--small",href:g.value},[Z(ne,{name:"external",size:14}),p[4]||(p[4]=B(" Open in VS Code ",-1))],8,Ms)]),Z(hs,{class:"viewer",text:u.value.text,lang:u.value.lang,"focus-line":c.value.line,"focus-column":c.value.column},null,8,["text","lang","focus-line","focus-column"])],64)):O("",!0):(_(),x("p",$s,"This finding is not tied to a source file."))])]),_:1},8,["title"]))}}),He=le(Ns,[["__scopeId","data-v-07a7a162"]]);function de(e){return Object.fromEntries(e.options.map(n=>[n.key,n.default]))}const Ss={class:"page"},Is={class:"page__head"},zs={class:"muted"},js={class:"project"},As=["title"],Os={key:0,class:"notice notice--error"},Es={key:1,class:"layout"},Ls={class:"menu","aria-label":"Checks"},Ps=["aria-current"],Fs={key:0,class:"menu__title"},Ts=["aria-current","onClick"],Ds={class:"menu__name"},Bs={class:"main"},Rs={key:0,class:"notice notice--error"},Us={class:"card block"},Vs={class:"head"},Hs={class:"muted"},Ys=["disabled"],Xs={key:0,class:"options"},Gs={key:0,class:"check"},Ks=["checked","onChange"],Ws={class:"muted"},Qs={key:1,class:"field"},Js={class:"muted"},Zs=["value","onInput"],qs={key:0,class:"notice notice--error"},ei={key:1,class:"card block",role:"status"},ti={key:2,class:"card block"},ni={class:"head"},si={class:"muted small"},ii={key:0,class:"notice notice--error"},oi={key:1,class:"clean"},li={class:"filters"},ai={class:"chips"},ri=["onClick"],ui={key:0,class:"muted"},ci={key:3,class:"card block empty"},Ye="devtoolz-ui.checks-project",Xe="devtoolz-ui.checks-selected",he="overview",fi=oe({__name:"ChecksPage",props:{module:{},status:{}},setup(e){const n=e,t=L([]),o=L(""),s=L(""),i=L({}),u=L({}),l=L(""),h=L(""),a=L(!1),c=L(""),d=L(""),m=L(null),g=L(null),k=L(!1),f=L(!1),r=L({done:0,total:0,current:""}),v=L();let p;const z=P(()=>o.value===he),C=P(()=>t.value.find(I=>I.id===o.value)),A=P(()=>u.value[o.value]),T=P(()=>{const I=A.value?.findings??[],b=c.value.trim().toLowerCase();return I.filter(M=>(d.value===""||M.code===d.value)&&(b===""||`${M.file??""} ${M.message} ${M.code}`.toLowerCase().includes(b)))}),N=P(()=>{const I=new Map;for(const b of A.value?.findings??[]){const M=I.get(b.code);M?M.count+=1:I.set(b.code,{count:1,severity:b.severity})}return[...I.entries()].map(([b,M])=>({code:b,...M}))}),$=P(()=>[{id:"code",title:"Code",items:t.value.filter(I=>I.group==="code")},{id:"dependencies",title:"Dependencies",items:t.value.filter(I=>I.group==="dependencies")},{id:"docs",title:"Documentation",items:t.value.filter(I=>I.group==="docs")}]);function S(I,b){try{localStorage.setItem(I,b)}catch{return}}function E(I){try{return localStorage.getItem(I)??""}catch{return""}}function D(I){o.value=I,c.value="",d.value="",m.value=null,S(Xe,I)}function R(I){a.value=!1;const b=I[0];!b||b===s.value||(s.value=b,u.value={},v.value=void 0,S(Ye,b))}function j(I){return u.value[I]?.findings.length}async function U(I){if(!(f.value||l.value)){p?.(),f.value=!0,h.value="",r.value={done:0,total:0,current:""};try{const{jobId:b}=await ye.post("/api/checks/all/run",{project:s.value,includeSlow:I});p=Pe(b,{onProgress:M=>{r.value=M},onDone:M=>{u.value={...u.value,...M.outcomes},v.value=M.tookMs,f.value=!1},onFailed:M=>{h.value=M,f.value=!1}})}catch(b){h.value=b instanceof Error?b.message:String(b),f.value=!1}}}async function K(){const I=C.value;if(!(!I||l.value)){p?.(),l.value=I.id,h.value="";try{const{jobId:b}=await ye.post(`/api/checks/${I.id}/run`,{project:s.value,options:i.value[I.id]??de(I)});p=Pe(b,{onDone:M=>{u.value={...u.value,[I.id]:M},l.value="",c.value="",d.value=""},onFailed:M=>{h.value=M,l.value=""}})}catch(b){h.value=b instanceof Error?b.message:String(b),l.value=""}}}function J(I,b){const M=C.value;M&&(i.value={...i.value,[M.id]:{...i.value[M.id]??de(M),[I]:b}})}function q(I,b){const M=C.value;M&&(i.value={...i.value,[M.id]:{...i.value[M.id]??de(M),[I]:b}})}function V(I){const b=C.value;return b?(i.value[b.id]??de(b))[I]??"":""}function ee(I){g.value=[{file:I,severity:"info",code:"file",message:I}]}function be(I){I.file&&ee(I.file)}function Ce(I){const b=T.value.indexOf(I);m.value=b>=0?b:0}return ke(async()=>{s.value=E(Ye)||n.status?.cwd||"";try{t.value=await ye.get("/api/checks");const I=E(Xe);o.value=I===he||t.value.some(b=>b.id===I)?I:he}catch(I){h.value=I instanceof Error?I.message:String(I)}}),Ke(()=>p?.()),(I,b)=>(_(),x("div",Ss,[y("header",Is,[y("h1",null,w(e.module.title),1),y("p",zs,w(e.module.description),1),y("p",js,[Z(ne,{name:"folder",size:15}),b[9]||(b[9]=y("span",{class:"muted"},"Project",-1)),y("code",{title:s.value},w(s.value),9,As),y("button",{class:"btn btn--small",onClick:b[0]||(b[0]=M=>a.value=!0)},"Change…")])]),h.value&&!C.value?(_(),x("p",Os,w(h.value),1)):O("",!0),t.value.length?(_(),x("div",Es,[y("nav",Ls,[y("button",{class:H(["menu__item",{"menu__item--on":z.value}]),"aria-current":z.value?"page":void 0,onClick:b[1]||(b[1]=M=>D(he))},[...b[10]||(b[10]=[y("span",{class:"menu__name"},"Overview",-1)])],10,Ps),(_(!0),x(F,null,Q($.value,M=>(_(),x(F,{key:M.id},[M.items.length?(_(),x("h3",Fs,w(M.title),1)):O("",!0),(_(!0),x(F,null,Q(M.items,W=>(_(),x("button",{key:W.id,class:H(["menu__item",{"menu__item--on":W.id===o.value}]),"aria-current":W.id===o.value?"page":void 0,onClick:vi=>D(W.id)},[y("span",Ds,w(W.title),1),j(W.id)!==void 0?(_(),x("span",{key:0,class:H(["menu__count",{"menu__count--clean":j(W.id)===0}])},w(j(W.id)===0?"✓":j(W.id)),3)):O("",!0)],10,Ts))),128))],64))),128))]),y("main",Bs,[h.value&&z.value?(_(),x("p",Rs,w(h.value),1)):O("",!0),z.value?(_(),te(Dt,{key:1,checks:t.value,outcomes:u.value,running:f.value,progress:r.value,"took-ms":v.value,onRunAll:U,onOpen:D},null,8,["checks","outcomes","running","progress","took-ms"])):C.value?(_(),x(F,{key:2},[y("section",Us,[y("div",Vs,[y("div",null,[y("h2",null,w(C.value.title),1),y("p",Hs,w(C.value.description),1)]),y("button",{class:"btn btn--primary",disabled:l.value!==""||s.value==="",onClick:K},[Z(ne,{name:"play",size:15}),B(" "+w(l.value===C.value.id?"Checking…":A.value?"Run again":"Run check"),1)],8,Ys)]),y("button",{class:"link",onClick:b[2]||(b[2]=M=>k.value=!k.value)},w(k.value?"Hide":"Show")+" options ",1),k.value?(_(),x("div",Xs,[(_(!0),x(F,null,Q(C.value.options,M=>(_(),x(F,{key:M.key},[M.type==="boolean"?(_(),x("label",Gs,[y("input",{type:"checkbox",checked:V(M.key)===!0,onChange:W=>J(M.key,W.target.checked)},null,40,Ks),y("span",null,[B(w(M.label)+" ",1),y("small",Ws," — "+w(M.help),1)])])):(_(),x("label",Qs,[y("span",null,[B(w(M.label)+" ",1),y("small",Js,"— "+w(M.help),1)]),y("textarea",{class:"textarea",rows:"3",spellcheck:"false",value:String(V(M.key)),onInput:W=>q(M.key,W.target.value)},null,40,Zs)]))],64))),128))])):O("",!0)]),h.value?(_(),x("p",qs,w(h.value),1)):O("",!0),l.value===C.value.id?(_(),x("section",ei,[...b[11]||(b[11]=[y("p",{class:"muted"},"Scanning the project…",-1)])])):A.value?(_(),x("section",ti,[y("div",ni,[y("div",null,[y("h2",null,w(A.value.summary),1),y("p",si,[B(w((A.value.tookMs/1e3).toFixed(1))+" s ",1),A.value.filesScanned!==void 0?(_(),x(F,{key:0},[B(" · "+w(A.value.filesScanned)+" files scanned",1)],64)):O("",!0)])])]),(_(!0),x(F,null,Q(A.value.notes??[],M=>(_(),x("p",{key:M,class:"notice notice--warn"},w(M),1))),128)),A.value.error?(_(),x("p",ii,w(A.value.error),1)):O("",!0),A.value.findings.length===0&&!A.value.error?(_(),x("p",oi,[Z(ne,{name:"check",size:18}),b[12]||(b[12]=B(" Nothing to report. This check is clean. ",-1))])):O("",!0),C.value.id==="circular-imports"&&A.value.findings.length?(_(),te(as,{key:2,findings:A.value.findings,onOpenFile:ee,onOpen:be},null,8,["findings"])):A.value.findings.length?(_(),x(F,{key:3},[y("div",li,[Ge(y("input",{"onUpdate:modelValue":b[3]||(b[3]=M=>c.value=M),class:"input search",placeholder:"Filter by file or text","aria-label":"Filter findings"},null,512),[[ot,c.value]]),y("div",ai,[y("button",{class:H(["chip",{"chip--on":d.value===""}]),onClick:b[4]||(b[4]=M=>d.value="")}," all "+w(A.value.findings.length),3),(_(!0),x(F,null,Q(N.value,M=>(_(),x("button",{key:M.code,class:H(["chip",[`chip--${M.severity}`,{"chip--on":d.value===M.code}]]),onClick:W=>d.value=d.value===M.code?"":M.code},w(M.code)+" "+w(M.count),11,ri))),128))])]),T.value.length===0?(_(),x("p",ui,"No findings match the filter.")):(_(),te(tt,{key:1,findings:T.value,onOpen:Ce},null,8,["findings"]))],64)):O("",!0)])):l.value?O("",!0):(_(),x("section",ci,[...b[13]||(b[13]=[y("p",{class:"muted"},"Press “Run check” to scan the project.",-1)])]))],64)):O("",!0)])])):O("",!0),g.value?(_(),te(He,{key:2,index:0,project:s.value,findings:g.value,onClose:b[5]||(b[5]=M=>g.value=null)},null,8,["project","findings"])):O("",!0),m.value!==null&&T.value.length?(_(),te(He,{key:3,index:m.value,"onUpdate:index":b[6]||(b[6]=M=>m.value=M),project:s.value,findings:T.value,onClose:b[7]||(b[7]=M=>m.value=null)},null,8,["index","project","findings"])):O("",!0),a.value?(_(),te(at,{key:4,start:s.value||e.status?.cwd||"",mode:"folder",title:"Choose the project folder",onClose:b[8]||(b[8]=M=>a.value=!1),onConfirm:R},null,8,["start"])):O("",!0)]))}}),_i=le(fi,[["__scopeId","data-v-3c25da8b"]]);export{_i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.overview[data-v-0b1b992d]{display:flex;flex-direction:column;gap:16px}.block[data-v-0b1b992d]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-0b1b992d]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.small[data-v-0b1b992d]{font-size:12px}.progress-wrap[data-v-0b1b992d]{display:flex;flex-direction:column;gap:8px}.progress[data-v-0b1b992d]{height:8px;overflow:hidden;border-radius:999px;background:var(--surface-2)}.progress__bar[data-v-0b1b992d]{height:100%;background:var(--accent);transition:width .15s}.chips[data-v-0b1b992d]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.sev[data-v-0b1b992d]{padding:2px 10px;border-radius:999px;background:var(--surface-2);font-size:12px}.sev--error[data-v-0b1b992d]{background:var(--danger-soft);color:var(--danger)}.sev--warning[data-v-0b1b992d]{background:var(--warn-soft);color:var(--warn)}.sev--ok[data-v-0b1b992d]{background:color-mix(in srgb,var(--ok) 18%,transparent);color:var(--ok)}.group[data-v-0b1b992d]{display:flex;flex-direction:column;gap:8px}.group__title[data-v-0b1b992d]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase}.cards[data-v-0b1b992d]{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px}.tile[data-v-0b1b992d]{display:flex;flex-direction:column;gap:8px;background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--shadow);padding:12px 16px;text-align:left;cursor:pointer;transition:border-color .15s}.tile[data-v-0b1b992d]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.tile[data-v-0b1b992d]:hover{border-color:var(--accent)}.tile--clean[data-v-0b1b992d]{border-left:3px solid var(--ok)}.tile--found[data-v-0b1b992d]{border-left:3px solid var(--warn)}.tile--broken[data-v-0b1b992d]{border-left:3px solid var(--danger)}.tile__top[data-v-0b1b992d]{display:flex;align-items:center;justify-content:space-between;gap:8px}.tile__state[data-v-0b1b992d]{color:var(--muted);font-size:12px;font-weight:600}.tile--clean .tile__state[data-v-0b1b992d]{color:var(--ok)}.tile--found .tile__state[data-v-0b1b992d]{color:var(--warn)}.tile--broken .tile__state[data-v-0b1b992d]{color:var(--danger)}.tile__text[data-v-0b1b992d]{font-size:12px}.tile__sev[data-v-0b1b992d]{display:flex;flex-wrap:wrap;align-items:center;gap:4px}.tile__slow[data-v-0b1b992d]{font-size:11px}.graph[data-v-2ff3fdf0]{display:flex;flex-direction:column;gap:8px}.graph__svg[data-v-2ff3fdf0]{width:100%;height:520px;border:1px solid var(--border);border-radius:9px;background:var(--surface-2);cursor:grab;touch-action:none}.graph__svg--drag[data-v-2ff3fdf0]{cursor:grabbing}.graph__bar[data-v-2ff3fdf0]{display:flex;flex-wrap:wrap;align-items:center;gap:16px;font-size:12px}.spacer[data-v-2ff3fdf0]{flex:1}.small[data-v-2ff3fdf0]{font-size:12px}.edge[data-v-2ff3fdf0]{fill:none;stroke:var(--muted);stroke-width:1.4;opacity:.75;transition:opacity .15s}.edge--strong[data-v-2ff3fdf0]{stroke-width:2.2}.edge--type[data-v-2ff3fdf0]{stroke-dasharray:5 4}.edge--on[data-v-2ff3fdf0]{stroke:var(--accent);stroke-width:2.6;opacity:1}.edge--dim[data-v-2ff3fdf0]{opacity:.12}.arrow[data-v-2ff3fdf0]{fill:var(--muted)}.arrow--on[data-v-2ff3fdf0]{fill:var(--accent)}.node[data-v-2ff3fdf0]{cursor:pointer;outline:none;transition:opacity .15s}.node__dot[data-v-2ff3fdf0]{stroke:var(--surface);stroke-width:2}.node--single .node__dot[data-v-2ff3fdf0]{fill:var(--warn)}.node--hub .node__dot[data-v-2ff3fdf0]{fill:var(--danger)}.node:hover .node__dot[data-v-2ff3fdf0],.node:focus-visible .node__dot[data-v-2ff3fdf0]{stroke:var(--accent);stroke-width:3}.node--dim[data-v-2ff3fdf0]{opacity:.2}.node__label[data-v-2ff3fdf0]{fill:var(--text);font-size:13px;font-weight:600;paint-order:stroke;stroke:var(--surface-2);stroke-width:4px;stroke-linejoin:round}.node__dir[data-v-2ff3fdf0]{fill:var(--muted);font-size:10px;paint-order:stroke;stroke:var(--surface-2);stroke-width:3px}.legend[data-v-2ff3fdf0]{display:inline-flex;align-items:center;gap:6px}.legend__dot[data-v-2ff3fdf0]{width:10px;height:10px;border-radius:50%}.legend__dot--single[data-v-2ff3fdf0]{background:var(--warn)}.legend__dot--hub[data-v-2ff3fdf0]{background:var(--danger)}.legend__line[data-v-2ff3fdf0]{width:22px;border-top:2px dashed var(--muted)}.legend__line--type[data-v-2ff3fdf0]{border-top-style:dashed}.groups[data-v-86eeb72c]{display:flex;flex-direction:column;gap:8px}.group[data-v-86eeb72c]{border:1px solid var(--border);border-radius:9px;overflow:hidden}.group__head[data-v-86eeb72c]{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:0;background:var(--surface-2);text-align:left;cursor:pointer}.group__head[data-v-86eeb72c]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.group__caret[data-v-86eeb72c]{flex:none;color:var(--muted);transition:transform .15s}.group__caret--open[data-v-86eeb72c]{transform:rotate(90deg)}.group__file[data-v-86eeb72c]{flex:1;min-width:0;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group__count[data-v-86eeb72c]{flex:none;padding:0 8px;border-radius:999px;background:var(--surface);color:var(--muted);font-size:11px}.items[data-v-86eeb72c]{margin:0;padding:0;list-style:none}.item[data-v-86eeb72c]{border-top:1px solid var(--border)}.item__main[data-v-86eeb72c]{display:flex;align-items:flex-start;gap:12px;width:100%;padding:8px 12px;border:0;background:transparent;text-align:left;cursor:pointer;transition:background .15s}.item__main[data-v-86eeb72c]:hover:not(:disabled){background:var(--surface-2)}.item__main[data-v-86eeb72c]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.item__place[data-v-86eeb72c]{flex:none;width:56px;color:var(--muted);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;text-align:right}.item__text[data-v-86eeb72c]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.item__hint[data-v-86eeb72c]{font-size:12px}.item__code[data-v-86eeb72c]{flex:none;padding:1px 8px;border-radius:999px;background:var(--surface-2);color:var(--muted);font-size:11px}.dot[data-v-86eeb72c]{flex:none;width:8px;height:8px;margin-top:7px;border-radius:50%;background:var(--muted)}.dot--error[data-v-86eeb72c]{background:var(--danger)}.dot--warning[data-v-86eeb72c]{background:var(--warn)}.more[data-v-86eeb72c]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;justify-content:center}.cycles[data-v-7482ac93]{display:flex;flex-direction:column;gap:12px}.split[data-v-7482ac93]{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:16px;align-items:start}@media(max-width:1100px){.split[data-v-7482ac93]{grid-template-columns:1fr}}.side[data-v-7482ac93]{display:flex;flex-direction:column;gap:8px;max-height:600px;overflow-y:auto}.side__title[data-v-7482ac93]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase}.side__list[data-v-7482ac93]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.cycle[data-v-7482ac93]{display:flex;flex-direction:column;gap:2px;width:100%;padding:8px 12px;border:1px solid var(--border);border-radius:9px;background:var(--surface);text-align:left;cursor:pointer}.cycle[data-v-7482ac93]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.cycle--on[data-v-7482ac93]{border-color:var(--accent);background:var(--accent-soft)}.cycle__head[data-v-7482ac93]{display:flex;align-items:center;gap:8px;font-size:12px}.cycle__tag[data-v-7482ac93]{padding:0 8px;border-radius:999px;background:var(--surface-2);font-size:11px}.cycle__chain[data-v-7482ac93]{color:var(--muted);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:11px;word-break:break-all}.code[data-v-f2eb8c06]{position:relative;overflow:auto;border:1px solid var(--border);border-radius:9px;background:var(--surface-2);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;line-height:1.6;tab-size:2}.code[data-v-f2eb8c06]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.code__note[data-v-f2eb8c06]{position:sticky;top:0;z-index:1;padding:6px 12px;background:var(--warn-soft);color:var(--warn)}.code__link[data-v-f2eb8c06]{padding:0;border:0;background:transparent;color:inherit;text-decoration:underline;cursor:pointer}.line[data-v-f2eb8c06]{position:relative;display:flex;min-width:max-content}.line--focus[data-v-f2eb8c06]{background:color-mix(in srgb,var(--warn) 22%,transparent);box-shadow:inset 3px 0 0 var(--warn)}.line__no[data-v-f2eb8c06]{flex:none;padding:0 12px;color:var(--muted);text-align:right;user-select:none;box-sizing:content-box}.line__text[data-v-f2eb8c06]{white-space:pre;padding-right:16px}.line__marker[data-v-f2eb8c06]{position:absolute;bottom:0;width:1ch;height:2px;background:var(--danger);pointer-events:none}.tok[data-v-f2eb8c06]{color:var(--light)}.tok--bold[data-v-f2eb8c06]{font-weight:600}.tok--italic[data-v-f2eb8c06]{font-style:italic}@media(prefers-color-scheme:dark){.tok[data-v-f2eb8c06]{color:var(--dark)}}.counter[data-v-07a7a162]{font-size:12px}.body[data-v-07a7a162]{display:flex;flex-direction:column;gap:12px;padding:16px;min-height:0}.finding[data-v-07a7a162]{display:flex;flex-direction:column;gap:4px}.bar[data-v-07a7a162]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.path[data-v-07a7a162]{flex:1;min-width:0;font-size:12px;word-break:break-all}.viewer[data-v-07a7a162]{max-height:58vh}.badge[data-v-07a7a162]{align-self:flex-start;padding:1px 8px;border-radius:999px;background:var(--surface-2);font-size:11px;text-transform:uppercase;letter-spacing:.03em}.badge--error[data-v-07a7a162]{background:var(--danger-soft);color:var(--danger)}.badge--warning[data-v-07a7a162]{background:var(--warn-soft);color:var(--warn)}a.btn[data-v-07a7a162]{text-decoration:none}.page[data-v-3c25da8b]{display:flex;flex-direction:column;gap:16px;padding:28px 28px 60px}@media(max-width:760px){.page[data-v-3c25da8b]{padding:18px 14px 40px}}.page__head p[data-v-3c25da8b]{margin-top:4px}.project[data-v-3c25da8b]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px;font-size:12px}.project code[data-v-3c25da8b]{padding:2px 8px;border-radius:6px;background:var(--surface-2);word-break:break-all}.layout[data-v-3c25da8b]{display:grid;grid-template-columns:250px minmax(0,1fr);gap:20px;align-items:start}@media(max-width:760px){.layout[data-v-3c25da8b]{grid-template-columns:1fr}}.menu[data-v-3c25da8b]{display:flex;flex-direction:column;gap:2px}.menu__title[data-v-3c25da8b]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase;margin:12px 0 4px 8px}.menu__item[data-v-3c25da8b]{display:flex;align-items:center;gap:8px;padding:9px 10px;border:0;border-radius:9px;background:transparent;text-align:left;cursor:pointer;transition:background .15s}.menu__item[data-v-3c25da8b]:hover:not(:disabled){background:var(--surface-2)}.menu__item[data-v-3c25da8b]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.menu__item--on[data-v-3c25da8b]{background:var(--accent-soft);color:var(--accent);font-weight:600}.menu__name[data-v-3c25da8b]{flex:1}.menu__count[data-v-3c25da8b]{padding:0 8px;border-radius:999px;background:var(--warn-soft);color:var(--warn);font-size:11px;font-weight:600}.menu__count--clean[data-v-3c25da8b]{background:color-mix(in srgb,var(--ok) 18%,transparent);color:var(--ok)}.main[data-v-3c25da8b]{display:flex;flex-direction:column;gap:16px;min-width:0}.block[data-v-3c25da8b]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-3c25da8b]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.small[data-v-3c25da8b]{font-size:12px}.link[data-v-3c25da8b]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-3c25da8b]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.options[data-v-3c25da8b]{display:flex;flex-direction:column;gap:12px}.textarea[data-v-3c25da8b]{padding:8px 12px;border:1px solid var(--border);border-radius:9px;background:var(--surface);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.textarea[data-v-3c25da8b]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.filters[data-v-3c25da8b]{display:flex;flex-direction:column;gap:8px}.search[data-v-3c25da8b]{max-width:420px}.chips[data-v-3c25da8b]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.chip[data-v-3c25da8b]{padding:2px 10px;border:1px solid var(--border);border-radius:999px;background:var(--surface);font-size:12px;cursor:pointer}.chip[data-v-3c25da8b]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.chip--on[data-v-3c25da8b]{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}.clean[data-v-3c25da8b]{display:flex;align-items:center;gap:8px;color:var(--ok);font-weight:600}.empty[data-v-3c25da8b]{text-align:center}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{d as se,r,w as me,x as le,o as n,c as o,F as p,a as $,f as l,t as a,n as T,y as ge,i as b,p as h,b as ae,s as z,e as ye,g as G,h as Z,j as be,z as we,q as ee,A as D,B as xe}from"./index-pDKL0Y31.js";import{F as Ce}from"./FolderBrowser-BX3-y8sM.js";import{U as Se}from"./UiSegmented-YV1YATxM.js";import{h as $e}from"./highlight-CsAszz7F.js";const Ne={class:"diff",role:"region","aria-label":"Changes in this file"},je={class:"hunk__head"},Ee={class:"row__no"},Ie={class:"row__no"},Be={class:"row__sign"},Fe={class:"row__text"},Oe={key:2},Pe=se({__name:"DiffView",props:{diff:{},lang:{}},setup(I){const N=I;function R(k){const g=[];let f,v=0,c=0;for(const u of k.split(`
|
|
2
|
+
`)){const d=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@(.*)$/.exec(u);if(d){v=Number(d[1]),c=Number(d[2]),f={header:u,lines:[]},g.push(f);continue}if(!f||u.startsWith("\\"))continue;const m=u[0];m==="+"?f.lines.push({type:"add",text:u.slice(1),oldNo:null,newNo:c++}):m==="-"?f.lines.push({type:"del",text:u.slice(1),oldNo:v++,newNo:null}):m===" "&&f.lines.push({type:"ctx",text:u.slice(1),oldNo:v++,newNo:c++})}return g}const C=r(R(N.diff));async function w(){const k=R(N.diff);C.value=k;for(const g of k){const f=await $e(g.lines.map(v=>v.text).join(`
|
|
3
|
+
`),N.lang);g.lines.forEach((v,c)=>{v.tokens=f[c]})}C.value=[...k]}me(()=>[N.diff,N.lang],w),le(w);function _(k){return k==="add"?"+":k==="del"?"−":" "}return(k,g)=>(n(),o("div",Ne,[(n(!0),o(p,null,$(C.value,(f,v)=>(n(),o("section",{key:v,class:"hunk"},[l("div",je,a(f.header),1),(n(!0),o(p,null,$(f.lines,(c,u)=>(n(),o("div",{key:u,class:T(["row",`row--${c.type}`])},[l("span",Ee,a(c.oldNo??""),1),l("span",Ie,a(c.newNo??""),1),l("span",Be,a(_(c.type)),1),l("span",Fe,[c.tokens?(n(!0),o(p,{key:0},$(c.tokens,(d,m)=>(n(),o("span",{key:m,class:"tok",style:ge({"--light":d.light||"var(--text)","--dark":d.dark||"var(--text)"})},a(d.text),5))),128)):(n(),o(p,{key:1},[b(a(c.text),1)],64)),c.text===""?(n(),o("span",Oe," ")):h("",!0)])],2))),128))]))),128))]))}}),Ue=ae(Pe,[["__scopeId","data-v-9a9e1464"]]),Ve={class:"page"},ze={class:"page__head"},De={class:"muted"},Re={class:"project"},Ae=["title"],Le={key:0,class:"card block"},We={class:"head"},Te=["disabled"],Me={class:"muted"},qe={key:0,class:"options"},He={key:0,class:"check"},Je=["checked","onChange"],Ge={class:"muted"},Ke={key:1,class:"field"},Ye={class:"muted"},Qe=["value","onInput"],Xe={key:1,class:"notice notice--error"},Ze={key:2,class:"notice"},et={key:3,class:"card block"},tt={class:"results"},st={class:"muted"},lt={key:0,class:"actions"},at={key:4,class:"card block",role:"status"},nt={key:5,class:"card block"},ot={class:"head"},ut={class:"muted small"},it={key:0,class:"notice notice--warn"},ct={class:"skipped"},rt={class:"toolbar"},dt=["disabled"],vt={class:"files"},ft={class:"file__row"},ht=["checked","disabled","aria-label","onChange"],pt=["aria-expanded","onClick"],_t={class:"file__name"},kt={class:"file__count"},mt={class:"file__stat file__stat--del"},gt={key:0,class:"file__stat file__stat--add"},yt={key:1,class:"file__done"},bt={key:0,class:"actions"},wt={key:6,class:"card block"},xt={class:"history"},Ct={class:"muted"},St=["onClick"],te="devtoolz-ui.checks-project",K=40,$t=se({__name:"CleanupPage",props:{module:{},status:{}},setup(I){const N=I,R={"embedded-in-expression":"inside a larger expression","braceless-body":"the only statement of an if/loop without braces"},C=r([]),w=r("strip-comments"),_=r(""),k=r({}),g=r(!1),f=r(!1),v=r(!1),c=r(!1),u=r(),d=r(new Set),m=r(new Set),S=r(new Set),M=r(""),x=r(""),O=r(""),P=r([]),j=r(""),A=r([]),B=r(K);let q;const E=D(()=>C.value.find(s=>s.id===w.value)),U=D(()=>{const s=M.value.trim().toLowerCase();return(u.value?.files??[]).filter(t=>s===""||t.file.toLowerCase().includes(s))}),ne=D(()=>U.value.slice(0,B.value)),F=D(()=>d.value.size),Y=D(()=>(u.value?.files??[]).filter(s=>d.value.has(s.file)).reduce((s,t)=>s+t.count,0));function oe(s){try{localStorage.setItem(te,s)}catch{return}}function ue(){try{return localStorage.getItem(te)??""}catch{return""}}function V(){const s=E.value;return s?{...Object.fromEntries(s.options.map(e=>[e.key,e.default])),...k.value[s.id]??{}}:{}}function Q(s,t){k.value={...k.value,[w.value]:{...V(),[s]:t}}}function ie(s){const t=s.slice(s.lastIndexOf(".")+1).toLowerCase();return t==="ts"?"ts":t==="tsx"?"tsx":t==="vue"?"vue":t==="jsx"?"jsx":"js"}function H(s){let t=0,e=0;for(const i of(s??"").split(`
|
|
4
|
+
`))i.startsWith("+")&&!i.startsWith("+++")?t+=1:i.startsWith("-")&&!i.startsWith("---")&&(e+=1);return{added:t,removed:e}}function ce(s){const t=new Set(d.value);t.has(s)?t.delete(s):t.add(s),d.value=t}function re(s){const t=new Set(m.value);t.has(s)?t.delete(s):t.add(s),m.value=t}function de(){d.value=new Set(U.value.filter(s=>!S.value.has(s.file)).map(s=>s.file))}function ve(){d.value=new Set}function fe(s){f.value=!1;const t=s[0];!t||t===_.value||(_.value=t,oe(t),J(),L())}function J(){u.value=void 0,d.value=new Set,m.value=new Set,S.value=new Set,P.value=[],j.value="",O.value="",x.value=""}function he(s){w.value=s,J()}async function pe(){if(!v.value){q?.(),J(),v.value=!0,B.value=K;try{const{jobId:s}=await z.post(`/api/cleanup/${w.value}/scan`,{project:_.value,options:V()});q=xe(s,{onDone:t=>{u.value=t,v.value=!1},onFailed:t=>{x.value=t,v.value=!1}})}catch(s){x.value=s instanceof Error?s.message:String(s),v.value=!1}}}async function L(){try{const s=await z.get(`/api/cleanup/history?project=${encodeURIComponent(_.value)}`);A.value=s.backups}catch{A.value=[]}}async function _e(){const s=u.value;if(!(!s||F.value===0||c.value||!window.confirm(`Change ${F.value} file${F.value===1?"":"s"}? ${Y.value} ${E.value?.verb??"item"}${Y.value===1?"":"s"} will be removed. A backup is saved first, and you can undo this afterwards.`))){c.value=!0,x.value="";try{const e=s.files.filter(y=>d.value.has(y.file)),i=await z.post(`/api/cleanup/${w.value}/apply`,{project:_.value,options:V(),files:e.map(y=>({file:y.file,hash:y.hash}))});P.value=i.results,j.value=i.backupDir??"";const W=i.results.filter(y=>y.status==="applied").map(y=>y.file);S.value=new Set([...S.value,...W]),d.value=new Set([...d.value].filter(y=>!W.includes(y))),O.value=`${W.length} file${W.length===1?"":"s"} changed.`,await L()}catch(e){x.value=e instanceof Error?e.message:String(e)}finally{c.value=!1}}}async function X(s){if(window.confirm("Put the files back as they were before this cleanup?"))try{const t=await z.post("/api/cleanup/undo",{project:_.value,dir:s}),e=t.counts.restored??0,i=t.counts.modified??0;O.value=`Restored ${e} file${e===1?"":"s"}.`+(i?` ${i} changed since and were left alone.`:""),s===j.value&&(j.value="",P.value=[],S.value=new Set),await L()}catch(t){x.value=t instanceof Error?t.message:String(t)}}function ke(s){const t=new Date(s);return Number.isNaN(t.getTime())?s:t.toLocaleString()}return le(async()=>{_.value=ue()||N.status?.cwd||"";try{C.value=await z.get("/api/cleanup/tools")}catch(s){x.value=s instanceof Error?s.message:String(s)}await L()}),ye(()=>q?.()),(s,t)=>(n(),o("div",Ve,[l("header",ze,[l("h1",null,a(I.module.title),1),l("p",De,a(I.module.description),1),l("p",Re,[G(Z,{name:"folder",size:15}),t[7]||(t[7]=l("span",{class:"muted"},"Project",-1)),l("code",{title:_.value},a(_.value),9,Ae),l("button",{class:"btn btn--small",onClick:t[0]||(t[0]=e=>f.value=!0)},"Change…")])]),E.value?(n(),o("section",Le,[l("div",We,[G(Se,{"model-value":w.value,label:"What to remove",options:C.value.map(e=>({value:e.id,label:e.title})),"onUpdate:modelValue":he},null,8,["model-value","options"]),l("button",{class:"btn btn--primary",disabled:v.value||c.value||_.value==="",onClick:pe},[G(Z,{name:"search",size:15}),b(" "+a(v.value?"Scanning…":u.value?"Scan again":"Scan the project"),1)],8,Te)]),l("p",Me,a(E.value.description)+" Nothing is changed until you choose the files and confirm. ",1),l("button",{class:"link",onClick:t[1]||(t[1]=e=>g.value=!g.value)},a(g.value?"Hide":"Show")+" options ",1),g.value?(n(),o("div",qe,[(n(!0),o(p,null,$(E.value.options,e=>(n(),o(p,{key:e.key},[e.type==="boolean"?(n(),o("label",He,[l("input",{type:"checkbox",checked:V()[e.key]===!0,onChange:i=>Q(e.key,i.target.checked)},null,40,Je),l("span",null,[b(a(e.label)+" ",1),l("small",Ge,"— "+a(e.help),1)])])):(n(),o("label",Ke,[l("span",null,[b(a(e.label)+" ",1),l("small",Ye,"— "+a(e.help),1)]),l("textarea",{class:"textarea",rows:"3",spellcheck:"false",value:String(V()[e.key]??""),onInput:i=>Q(e.key,i.target.value)},null,40,Qe)]))],64))),128))])):h("",!0)])):h("",!0),x.value?(n(),o("p",Xe,a(x.value),1)):h("",!0),O.value?(n(),o("p",Ze,a(O.value),1)):h("",!0),j.value||P.value.length?(n(),o("section",et,[t[8]||(t[8]=l("h2",null,"Result",-1)),l("ul",tt,[(n(!0),o(p,null,$(P.value,e=>(n(),o("li",{key:e.file,class:T(["result",`result--${e.status}`])},[l("code",null,a(e.file),1),l("span",st,[e.status==="applied"?(n(),o(p,{key:0},[b("changed, "+a(e.count)+" removed",1)],64)):(n(),o(p,{key:1},[b(a(e.message??e.status),1)],64))])],2))),128))]),j.value?(n(),o("div",lt,[l("button",{class:"btn",onClick:t[2]||(t[2]=e=>X(j.value))},"Undo this cleanup")])):h("",!0)])):h("",!0),v.value?(n(),o("section",at,[...t[9]||(t[9]=[l("p",{class:"muted"},"Scanning the project…",-1)])])):u.value?(n(),o("section",nt,[l("div",ot,[l("div",null,[l("h2",null,[u.value.files.length===0?(n(),o(p,{key:0},[b("Nothing to remove")],64)):(n(),o(p,{key:1},[b(a(u.value.total)+" "+a(E.value?.verb)+a(u.value.total===1?"":"s")+" in "+a(u.value.files.length)+" file"+a(u.value.files.length===1?"":"s"),1)],64))]),l("p",ut,a(u.value.filesScanned)+" files scanned · "+a((u.value.tookMs/1e3).toFixed(1))+" s ",1)])]),u.value.skipped.length?(n(),o("div",it,[l("strong",null,a(u.value.skipped.length)+" call"+a(u.value.skipped.length===1?"":"s")+" left alone",1),t[10]||(t[10]=b(", because removing them is not safe: ",-1)),l("ul",ct,[(n(!0),o(p,null,$(u.value.skipped,(e,i)=>(n(),o("li",{key:i},[l("code",null,a(e.file)+":"+a(e.line),1),b(" — "+a(R[e.reason]??e.reason),1)]))),128))])])):h("",!0),u.value.files.length?(n(),o(p,{key:1},[l("div",rt,[be(l("input",{"onUpdate:modelValue":t[3]||(t[3]=e=>M.value=e),class:"input search",placeholder:"Filter files","aria-label":"Filter files"},null,512),[[we,M.value]]),l("button",{class:"btn btn--small",onClick:de},"Select all"),l("button",{class:"btn btn--small",onClick:ve},"Select none"),t[11]||(t[11]=l("span",{class:"spacer"},null,-1)),l("button",{class:"btn btn--primary",disabled:F.value===0||c.value,onClick:_e},a(c.value?"Changing…":`Change ${F.value} file${F.value===1?"":"s"}`),9,dt)]),l("ul",vt,[(n(!0),o(p,null,$(ne.value,e=>(n(),o("li",{key:e.file,class:T(["file",{"file--done":S.value.has(e.file)}])},[l("div",ft,[l("input",{type:"checkbox",checked:d.value.has(e.file),disabled:S.value.has(e.file),"aria-label":`Change ${e.file}`,onChange:i=>ce(e.file)},null,40,ht),l("button",{class:"file__main","aria-expanded":m.value.has(e.file),onClick:i=>re(e.file)},[l("span",{class:T(["file__caret",{"file__caret--open":m.value.has(e.file)}])},"▸",2),l("code",_t,a(e.file),1),l("span",kt,a(e.count)+" "+a(E.value?.verb)+a(e.count===1?"":"s"),1),l("span",mt,"−"+a(H(e.diff).removed),1),H(e.diff).added?(n(),o("span",gt,"+"+a(H(e.diff).added),1)):h("",!0),S.value.has(e.file)?(n(),o("span",yt,"✓ changed")):h("",!0)],8,pt)]),m.value.has(e.file)&&e.diff?(n(),ee(Ue,{key:0,diff:e.diff,lang:ie(e.file)},null,8,["diff","lang"])):h("",!0)],2))),128))]),B.value<U.value.length?(n(),o("div",bt,[l("button",{class:"btn",onClick:t[4]||(t[4]=e=>B.value+=K)}," Show more ("+a(U.value.length-B.value)+" left) ",1),l("button",{class:"btn",onClick:t[5]||(t[5]=e=>B.value=U.value.length)},"Show all")])):h("",!0)],64)):h("",!0)])):h("",!0),A.value.length?(n(),o("section",wt,[t[12]||(t[12]=l("h2",null,"Recent cleanups",-1)),l("ul",xt,[(n(!0),o(p,null,$(A.value,e=>(n(),o("li",{key:e.dir,class:"history__row"},[l("span",null,[l("strong",null,a(C.value.find(i=>i.id===e.tool)?.title??e.tool),1),l("span",Ct," · "+a(e.files)+" file"+a(e.files===1?"":"s")+" · "+a(ke(e.createdAt)),1)]),l("button",{class:"btn btn--small",onClick:i=>X(e.dir)},"Undo",8,St)]))),128))])])):h("",!0),f.value?(n(),ee(Ce,{key:7,start:_.value||I.status?.cwd||"",mode:"folder",title:"Choose the project folder",onClose:t[6]||(t[6]=e=>f.value=!1),onConfirm:fe},null,8,["start"])):h("",!0)]))}}),Bt=ae($t,[["__scopeId","data-v-8279376c"]]);export{Bt as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.diff[data-v-9a9e1464]{overflow:auto;border:1px solid var(--border);border-radius:9px;background:var(--surface-2);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;line-height:1.6;max-height:460px}.hunk[data-v-9a9e1464]{min-width:max-content}.hunk__head[data-v-9a9e1464]{padding:2px 12px;background:var(--accent-soft);color:var(--accent);font-size:11px}.row[data-v-9a9e1464]{display:flex}.row--add[data-v-9a9e1464]{background:color-mix(in srgb,var(--ok) 16%,transparent)}.row--del[data-v-9a9e1464]{background:color-mix(in srgb,var(--danger) 16%,transparent)}.row__no[data-v-9a9e1464]{flex:none;width:4ch;padding:0 6px;color:var(--muted);text-align:right;user-select:none}.row__sign[data-v-9a9e1464]{flex:none;width:2ch;color:var(--muted);user-select:none}.row--add .row__sign[data-v-9a9e1464]{color:var(--ok)}.row--del .row__sign[data-v-9a9e1464]{color:var(--danger)}.row__text[data-v-9a9e1464]{white-space:pre;padding-right:16px}.tok[data-v-9a9e1464]{color:var(--light)}@media(prefers-color-scheme:dark){.tok[data-v-9a9e1464]{color:var(--dark)}}.page[data-v-8279376c]{display:flex;flex-direction:column;gap:16px;padding:28px 28px 60px}@media(max-width:760px){.page[data-v-8279376c]{padding:18px 14px 40px}}.page__head p[data-v-8279376c]{margin-top:4px}.project[data-v-8279376c]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px;font-size:12px}.project code[data-v-8279376c]{padding:2px 8px;border-radius:6px;background:var(--surface-2);word-break:break-all}.block[data-v-8279376c]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-8279376c]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.small[data-v-8279376c]{font-size:12px}.link[data-v-8279376c]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-8279376c]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.options[data-v-8279376c]{display:flex;flex-direction:column;gap:12px}.textarea[data-v-8279376c]{padding:8px 12px;border:1px solid var(--border);border-radius:9px;background:var(--surface);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.textarea[data-v-8279376c]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.toolbar[data-v-8279376c]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.search[data-v-8279376c]{width:260px}.spacer[data-v-8279376c]{flex:1}.actions[data-v-8279376c]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;justify-content:center}.skipped[data-v-8279376c]{margin:8px 0 0;padding-left:20px;font-size:12px}.files[data-v-8279376c]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.file[data-v-8279376c]{display:flex;flex-direction:column;gap:8px;padding:4px 12px 8px;border:1px solid var(--border);border-radius:9px}.file--done[data-v-8279376c]{opacity:.6}.file__row[data-v-8279376c]{display:flex;align-items:center;gap:12px}.file__main[data-v-8279376c]{display:flex;flex:1;align-items:center;gap:8px;min-width:0;padding:8px 0;border:0;background:transparent;text-align:left;cursor:pointer}.file__main[data-v-8279376c]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.file__caret[data-v-8279376c]{flex:none;color:var(--muted);transition:transform .15s}.file__caret--open[data-v-8279376c]{transform:rotate(90deg)}.file__name[data-v-8279376c]{flex:1;min-width:0;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file__count[data-v-8279376c]{flex:none;color:var(--muted);font-size:12px}.file__stat[data-v-8279376c]{flex:none;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:11px}.file__stat--del[data-v-8279376c]{color:var(--danger)}.file__stat--add[data-v-8279376c]{color:var(--ok)}.file__done[data-v-8279376c]{flex:none;color:var(--ok);font-size:12px}.results[data-v-8279376c]{display:flex;flex-direction:column;gap:4px;margin:0;padding:0;list-style:none}.result[data-v-8279376c]{display:flex;gap:12px;font-size:12px}.result--changed[data-v-8279376c],.result--error[data-v-8279376c],.result--refused[data-v-8279376c]{color:var(--danger)}.history[data-v-8279376c]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.history__row[data-v-8279376c]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:8px 12px;border:1px solid var(--border);border-radius:9px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as N,x as W,e as O,o as l,c as n,C as L,f as a,t as u,D as S,g as y,h as C,p as c,y as J,n as M,r as b,b as j,q as Q,E as T,i as U,F as V,a as I,j as A,z as X,v as Y,k as D,G as Z,l as ee,A as B,s as te,H as se}from"./index-pDKL0Y31.js";const oe=["aria-label"],ae={class:"dialog__head"},le={class:"dialog__title"},ne={class:"dialog__body"},ie={key:0,class:"dialog__foot"},de=N({__name:"UiModal",props:{title:{},width:{default:"820px"},fixedHeight:{type:Boolean,default:!1}},emits:["close"],setup(i,{emit:$}){const r=i,v=$,s=b();function h(d){d.key==="Escape"&&v("close")}return W(()=>{window.addEventListener("keydown",h),document.body.style.overflow="hidden",s.value?.focus()}),O(()=>{window.removeEventListener("keydown",h),document.body.style.overflow=""}),(d,m)=>(l(),n("div",{class:"overlay",onMousedown:m[1]||(m[1]=L(k=>v("close"),["self"]))},[a("div",{ref_key:"dialog",ref:s,class:M(["dialog",{"dialog--fixed":r.fixedHeight}]),style:J({"--dialog-width":r.width}),role:"dialog","aria-modal":"true","aria-label":r.title,tabindex:"-1"},[a("header",ae,[a("h2",le,u(r.title),1),S(d.$slots,"actions",{},void 0),a("button",{class:"btn btn--ghost btn--small","aria-label":"Close",onClick:m[0]||(m[0]=k=>v("close"))},[y(C,{name:"close"})])]),a("div",ne,[S(d.$slots,"default",{},void 0)]),d.$slots.footer?(l(),n("footer",ie,[S(d.$slots,"footer",{},void 0)])):c("",!0)],14,oe)],32))}}),re=j(de,[["__scopeId","data-v-e779e4b0"]]),ue={class:"bar"},ce=["disabled"],ve=["value"],me=["value"],fe={class:"check muted"},be={key:0,class:"notice notice--error notice-inset"},he=["aria-busy"],pe={key:0,class:"muted empty"},ke=["checked","aria-label","onChange"],ge=["onClick"],_e={key:0,class:"row__icon"},we=["src"],ye={class:"row__name"},Ce={key:2,class:"muted"},$e={key:1,class:"muted empty"},xe={class:"muted"},ze=["disabled"],Se=["disabled"],Ue=N({__name:"FolderBrowser",props:{start:{},mode:{default:"sources"},title:{default:""}},emits:["close","confirm"],setup(i,{emit:$}){const r=i,v=$,s=b(),h=b(r.start),d=b(!1),m=b(!1),k=b(""),p=b(new Set),x=b(),_=new Map,z=B(()=>s.value?.path.includes("\\")?"\\":"/"),H=B(()=>(s.value?.entries??[]).filter(o=>r.mode!=="folder"||o.kind==="dir")),E=B(()=>s.value?.entries.filter(o=>o.kind==="image").length??0);function g(o){const e=s.value?.path??"";return e.endsWith(z.value)?e+o:e+z.value+o}function G(o,e){const t=e.endsWith("\\")||e.endsWith("/")?e:e+z.value;return o!==e&&o.startsWith(t)}async function f(o){const e=s.value?.path;e!==void 0&&_.set(e,x.value?.scrollTop??0),m.value=!0,k.value="";try{const t=await te.get(`/api/fs/list?path=${encodeURIComponent(o)}&hidden=${d.value?1:0}`);s.value=t,h.value=t.path;for(const w of[..._.keys()])G(w,t.path)&&_.delete(w);await se(),x.value?.scrollTo({top:_.get(t.path)??0})}catch(t){k.value=t instanceof Error?t.message:String(t)}finally{m.value=!1}}function P(o){o.kind==="dir"&&f(g(o.name))}function F(o){const e=g(o.name),t=new Set(p.value);t.has(e)?t.delete(e):t.add(e),p.value=t}function R(o){o.kind==="dir"?P(o):r.mode==="image"?v("confirm",[g(o.name)]):F(o)}function q(){s.value&&v("confirm",[s.value.path])}function K(){v("confirm",[...p.value])}return W(()=>{f(r.start)}),(o,e)=>(l(),Q(re,{title:i.title||(i.mode==="folder"?"Choose a folder":i.mode==="image"?"Choose an image":"Add folders or images"),"fixed-height":"",onClose:e[8]||(e[8]=t=>v("close"))},{footer:T(()=>[a("span",xe,u(E.value)+" image"+u(E.value===1?"":"s")+" here",1),e[13]||(e[13]=a("span",{class:"spacer"},null,-1)),i.mode!=="image"?(l(),n("button",{key:0,class:M(["btn",{"btn--primary":i.mode==="folder"}]),disabled:!s.value,onClick:q},u(i.mode==="folder"?"Use this folder":"Add this folder"),11,ze)):c("",!0),i.mode==="sources"?(l(),n("button",{key:1,class:"btn btn--primary",disabled:p.value.size===0,onClick:K}," Add "+u(p.value.size)+" selected ",9,Se)):c("",!0)]),default:T(()=>[a("div",ue,[a("button",{class:"btn btn--small",disabled:!s.value?.parent,title:"Parent folder",onClick:e[0]||(e[0]=t=>s.value?.parent&&f(s.value.parent))},[y(C,{name:"up",size:15}),e[9]||(e[9]=U(" Up ",-1))],8,ce),a("button",{class:"btn btn--small",title:"Home folder",onClick:e[1]||(e[1]=t=>s.value&&f(s.value.home))},[y(C,{name:"home",size:15}),e[10]||(e[10]=U(" Home ",-1))]),a("button",{class:"btn btn--small",title:"Start folder",onClick:e[2]||(e[2]=t=>s.value&&f(s.value.cwd))}," Start folder "),(s.value?.roots.length??0)>1?(l(),n("select",{key:0,class:"select bar__roots",value:s.value?.root,"aria-label":"Drive",onChange:e[3]||(e[3]=t=>f(t.target.value))},[(l(!0),n(V,null,I(s.value?.roots,t=>(l(),n("option",{key:t,value:t},u(t),9,me))),128))],40,ve)):c("",!0),a("form",{class:"bar__path",onSubmit:e[5]||(e[5]=L(t=>f(h.value),["prevent"]))},[A(a("input",{"onUpdate:modelValue":e[4]||(e[4]=t=>h.value=t),class:"input",spellcheck:"false","aria-label":"Folder path"},null,512),[[X,h.value]]),e[11]||(e[11]=a("button",{class:"btn btn--small",type:"submit"},"Go",-1))],32),a("label",fe,[A(a("input",{"onUpdate:modelValue":e[6]||(e[6]=t=>d.value=t),type:"checkbox",onChange:e[7]||(e[7]=t=>s.value&&f(s.value.path))},null,544),[[Y,d.value]]),e[12]||(e[12]=U(" Hidden ",-1))])]),k.value?(l(),n("div",be,u(k.value),1)):c("",!0),a("div",{ref_key:"list",ref:x,class:"list","aria-busy":m.value},[s.value&&H.value.length===0?(l(),n("div",pe," This folder has no subfolders or images. ")):c("",!0),(l(!0),n(V,null,I(H.value,t=>(l(),n("div",{key:t.name,class:M(["row",{"row--picked":p.value.has(g(t.name))}])},[i.mode==="sources"?(l(),n("input",{key:0,type:"checkbox",checked:p.value.has(g(t.name)),"aria-label":`Select ${t.name}`,onChange:w=>F(t)},null,40,ke)):c("",!0),a("button",{class:"row__main",onClick:w=>R(t)},[t.kind==="dir"?(l(),n("span",_e,[y(C,{name:"folder"})])):(l(),n("img",{key:1,class:"row__thumb",loading:"lazy",alt:"",src:D(Z)(g(t.name),96)},null,8,we)),a("span",ye,u(t.name),1),t.size!==void 0?(l(),n("span",Ce,u(D(ee)(t.size)),1)):c("",!0)],8,ge)],2))),128)),s.value?.truncated?(l(),n("div",$e,"Only the first entries are shown.")):c("",!0)],8,he)]),_:1},8,["title"]))}}),Me=j(Ue,[["__scopeId","data-v-1908c9a0"]]);export{Me as F,re as U};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.overlay[data-v-e779e4b0]{position:fixed;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;padding:20px;overflow:hidden;background:var(--backdrop)}.dialog[data-v-e779e4b0]{background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--shadow);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;width:min(var(--dialog-width),100%);max-height:100%;outline:none}.dialog--fixed[data-v-e779e4b0]{height:min(680px,100%)}.dialog__head[data-v-e779e4b0],.dialog__foot[data-v-e779e4b0]{display:flex;align-items:center;gap:10px;padding:12px 16px}.dialog__head[data-v-e779e4b0]{border-bottom:1px solid var(--border)}.dialog__title[data-v-e779e4b0]{flex:1;font-size:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dialog__body[data-v-e779e4b0]{flex:1;min-height:0;display:flex;flex-direction:column}.dialog__foot[data-v-e779e4b0]{border-top:1px solid var(--border)}.bar[data-v-1908c9a0]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:12px 16px}.bar__path[data-v-1908c9a0]{display:flex;flex:1;gap:6px;min-width:200px}.bar__path .input[data-v-1908c9a0]{flex:1;height:28px;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.bar__roots[data-v-1908c9a0]{height:28px}.notice-inset[data-v-1908c9a0]{margin:0 16px 12px}.spacer[data-v-1908c9a0]{flex:1}.list[data-v-1908c9a0]{flex:1;min-height:0;padding:0 8px 8px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--border) transparent}.empty[data-v-1908c9a0]{padding:24px;text-align:center}.row[data-v-1908c9a0]{display:flex;align-items:center;gap:8px;padding:2px 8px;border-radius:9px}.row[data-v-1908c9a0]:hover{background:var(--surface-2)}.row--picked[data-v-1908c9a0]{background:var(--accent-soft)}.row__main[data-v-1908c9a0]{display:flex;flex:1;align-items:center;gap:10px;min-width:0;padding:4px 0;border:0;background:transparent;text-align:left;cursor:pointer}.row__icon[data-v-1908c9a0]{display:grid;place-items:center;width:40px;height:40px;color:var(--accent)}.row__thumb[data-v-1908c9a0]{width:40px;height:40px;border-radius:6px;background:var(--surface-2);object-fit:cover}.row__name[data-v-1908c9a0]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{d as ne,x as pe,o as t,c as s,f as e,t as a,p as d,i as A,F as S,a as L,k as G,l as ce,C as Ge,j as R,z as se,g as q,h as Y,n as ae,v as fe,G as be,q as le,r as v,A as U,s as Q,M as Qe,b as oe,N as he,u as Ye,m as Ze,w as ye,e as Se,K as ve,L as Ie,y as Ce,B as Xe,O as ze}from"./index-pDKL0Y31.js";import{U as ge}from"./UiSegmented-YV1YATxM.js";import{F as Ve}from"./FolderBrowser-BX3-y8sM.js";import{S as et}from"./SourcePicker-CVgtCk78.js";const tt={class:"view"},st={key:0,class:"card block"},lt={key:0,class:"notice"},at={key:1,class:"notice notice--error"},nt={key:2,class:"muted"},ot={class:"list"},it={class:"item__main"},ut={class:"muted"},rt=["title"],dt={class:"item__actions"},ct=["onClick"],vt=["onClick"],pt={class:"custom"},mt=["disabled"],ft={key:1,class:"card block"},gt={class:"head"},ht={class:"muted"},bt={class:"item__path"},yt={key:0,class:"notice"},kt={key:1,class:"notice notice--error"},$t={class:"chips"},_t={key:2,class:"notice notice--warn"},wt={class:"actions"},Ct=["disabled"],St={key:0,class:"check"},Vt={class:"rows"},xt=["src"],Et=["src"],zt={class:"row__text"},At=["title"],Nt={class:"muted small"},Ot={key:0,class:"small row__message"},Bt={key:3,class:"actions"},jt={key:4,class:"muted small"},Ae="devtoolz-ui.open-backup",we=30,Tt=ne({__name:"BackupsView",props:{cwd:{}},setup(n){const k={restored:"restored","would-restore":"can be restored",modified:"changed since","missing-backup":"copy missing","damaged-backup":"copy damaged",error:"error"},i=v(""),g=v([]),f=v(),N=v(""),b=v(""),z=v(!1),j=v(!1),I=v(we),D=v(""),O=v(!1),C=U(()=>{const V=f.value?.counts;return V?V.modified+V["missing-backup"]+V["damaged-backup"]+V.error:0}),h=U(()=>f.value?.counts["would-restore"]??0),p=U(()=>f.value?.entries.slice(0,I.value)??[]);function r(V){const w=new Date(V);return Number.isNaN(w.getTime())?V:w.toLocaleString()}function _(V){return V==="would-restore"||V==="restored"?"good":V==="modified"?"warn":"bad"}function $(V){N.value=V instanceof Error?V.message:String(V)}async function F(){try{const V=await Q.get("/api/image-batch/backups");i.value=V.root,g.value=V.backups}catch(V){$(V)}}async function K(V){N.value="",b.value="",j.value=!1,I.value=we;try{f.value=await Q.get(`/api/image-batch/backup?dir=${encodeURIComponent(V)}`)}catch(w){f.value=void 0,$(w)}}function P(V){const w=V?.[0]??D.value;O.value=!1,w.trim()!==""&&(D.value=w,K(w))}async function M(){const V=f.value;if(!V)return;const w=j.value?V.files:h.value;if(window.confirm(`Put back ${w} original file${w===1?"":"s"} from this backup?`+(j.value?" Files changed after the replacement will be overwritten too.":""))){z.value=!0;try{const J=await Q.post("/api/image-batch/backup/restore",{dir:V.dir,force:j.value});b.value=`Restored ${J.counts.restored} file${J.counts.restored===1?"":"s"}.`,await K(V.dir)}catch(J){$(J)}finally{z.value=!1}}}async function te(V){if(window.confirm("Delete this backup for good? The saved originals cannot be recovered afterwards."))try{await Q.post("/api/image-batch/backup/delete",{dir:V}),b.value="The backup was deleted.",f.value?.dir===V&&(f.value=void 0),await F()}catch(w){$(w)}}return pe(async()=>{await F();try{const V=localStorage.getItem(Ae);V&&(localStorage.removeItem(Ae),await K(V))}catch{f.value=void 0}}),(V,w)=>(t(),s("div",tt,[f.value?(t(),s("section",ft,[e("div",gt,[e("div",null,[e("h2",null,"Backup of "+a(r(f.value.createdAt)),1),e("p",ht,a(f.value.files)+" file"+a(f.value.files===1?"":"s")+" · "+a(G(ce)(f.value.bytesBefore))+" originals, "+a(G(ce)(f.value.bytesAfter))+" after the replacement ",1),e("code",bt,a(f.value.dir),1)]),e("button",{class:"btn btn--ghost",onClick:w[3]||(w[3]=x=>(f.value=void 0,F()))},[q(Y,{name:"close",size:16}),w[15]||(w[15]=A(" Back to the list ",-1))])]),b.value?(t(),s("p",yt,a(b.value),1)):d("",!0),N.value?(t(),s("p",kt,a(N.value),1)):d("",!0),e("div",$t,[(t(!0),s(S,null,L(f.value.counts,(x,J)=>R((t(),s("span",{key:J,class:ae(["chip",`chip--${_(J)}`])},a(x)+" "+a(k[J]),3)),[[Qe,x>0]])),128))]),f.value.counts.modified?(t(),s("p",_t,a(f.value.counts.modified)+" file"+a(f.value.counts.modified===1?" was":"s were")+" changed after the replacement. They are left alone unless you tick the box below. ",1)):d("",!0),e("div",wt,[e("button",{class:"btn btn--primary",disabled:z.value||h.value===0&&!j.value,onClick:M}," Restore "+a(j.value?"everything":`${h.value} file${h.value===1?"":"s"}`),9,Ct),f.value.counts.modified?(t(),s("label",St,[R(e("input",{"onUpdate:modelValue":w[4]||(w[4]=x=>j.value=x),type:"checkbox"},null,512),[[fe,j.value]]),w[16]||(w[16]=A(" Overwrite files that changed since ",-1))])):d("",!0),e("button",{class:"btn btn--danger",onClick:w[5]||(w[5]=x=>te(f.value.dir))},"Delete this backup")]),e("ul",Vt,[(t(!0),s(S,null,L(p.value,x=>(t(),s("li",{key:x.path,class:"row"},[e("img",{class:"row__thumb",loading:"lazy",alt:"Original",src:G(be)(x.backup,120)},null,8,xt),w[17]||(w[17]=e("span",{class:"row__arrow muted"},"⇄",-1)),e("img",{class:"row__thumb",loading:"lazy",alt:"Now",src:G(be)(x.path,120)},null,8,Et),e("div",zt,[e("span",{class:"row__name",title:x.path},a(x.path),9,At),e("span",Nt," original "+a(G(ce)(x.bytesBefore))+" · replaced with "+a(G(ce)(x.bytesAfter)),1),x.message?(t(),s("span",Ot,a(x.message),1)):d("",!0)]),e("span",{class:ae(["chip",`chip--${_(x.status)}`])},a(k[x.status]),3)]))),128))]),f.value&&I.value<f.value.entries.length?(t(),s("div",Bt,[e("button",{class:"btn",onClick:w[6]||(w[6]=x=>I.value+=we)}," Show more ("+a(f.value.entries.length-I.value)+" left) ",1),e("button",{class:"btn",onClick:w[7]||(w[7]=x=>I.value=f.value.entries.length)}," Show all ("+a(f.value.entries.length)+") ",1)])):d("",!0),C.value?(t(),s("p",jt," The left picture is the saved original, the right one is the file as it is now on disk. ")):d("",!0)])):(t(),s("section",st,[w[14]||(w[14]=e("div",{class:"head"},[e("div",null,[e("h2",null,"Backups"),e("p",{class:"muted"}," “Replace the originals” copies each file here first, so a replacement can be undone. ")])],-1)),b.value?(t(),s("p",lt,a(b.value),1)):d("",!0),N.value?(t(),s("p",at,a(N.value),1)):d("",!0),g.value.length===0?(t(),s("p",nt,[w[9]||(w[9]=A(" No backups in ",-1)),e("code",null,a(i.value),1),w[10]||(w[10]=A(" yet. ",-1))])):d("",!0),e("ul",ot,[(t(!0),s(S,null,L(g.value,x=>(t(),s("li",{key:x.dir,class:"item"},[e("div",it,[e("strong",null,a(r(x.createdAt)),1),e("span",ut,a(x.files)+" file"+a(x.files===1?"":"s")+" · "+a(G(ce)(x.bytesBefore))+" → "+a(G(ce)(x.bytesAfter)),1),e("code",{class:"item__path",title:x.dir},a(x.dir),9,rt)]),e("div",dt,[e("button",{class:"btn btn--small",onClick:J=>K(x.dir)},"Open",8,ct),e("button",{class:"btn btn--small btn--danger",onClick:J=>te(x.dir)},"Delete",8,vt)])]))),128))]),e("div",pt,[w[12]||(w[12]=e("h3",null,"Another backup folder",-1)),w[13]||(w[13]=e("p",{class:"muted small"},[A(" If you chose your own backup folder, pick the dated folder inside it (the one with a "),e("code",null,"journal.json"),A("). ")],-1)),e("form",{class:"pathrow",onSubmit:w[2]||(w[2]=Ge(x=>P(),["prevent"]))},[R(e("input",{"onUpdate:modelValue":w[0]||(w[0]=x=>D.value=x),class:"input",spellcheck:"false",placeholder:"Path to the dated backup folder"},null,512),[[se,D.value]]),e("button",{class:"btn",type:"button",onClick:w[1]||(w[1]=x=>O.value=!0)},[q(Y,{name:"folder",size:16}),w[11]||(w[11]=A(" Browse ",-1))]),e("button",{class:"btn btn--primary",type:"submit",disabled:D.value.trim()===""}," Open ",8,mt)],32)])])),O.value?(t(),le(Ve,{key:2,start:n.cwd,mode:"folder",title:"Choose the backup folder",onClose:w[8]||(w[8]=x=>O.value=!1),onConfirm:P},null,8,["start"])):d("",!0)]))}}),Ut=oe(Tt,[["__scopeId","data-v-aa574981"]]),ke=Symbol("image-batch-navigate"),xe=Symbol("image-batch-project"),De={cwd:"",name:"this project",home:""};function It(n,k){const i=n.split(/[\\/]/).filter(Boolean);return{cwd:n,home:k,name:i[i.length-1]??n}}const Dt={class:"sharpen"},Mt={key:0,class:"grid"},Lt={class:"field"},Rt=["value"],Ft=["value"],Pt={key:1,class:"hint muted"},qt={class:"grid"},Jt={class:"field"},Kt=["value"],Wt=["value"],Ht={class:"field"},Gt=["value"],Qt=["value"],Yt={key:0,class:"grid"},Zt={class:"muted"},Xt=["value","onInput"],es=ne({__name:"SharpenSettings",props:Ze({options:{},manage:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(n){const k=n,i=he(ke,()=>{}),g=Ye(n,"modelValue"),f=v([]),N=v(!1),b=U(()=>f.value.filter(C=>!C.error)),z=U(()=>f.value.find(C=>C.name===g.value.preset));function j(C){const h=C.fields??{};return Object.entries(h).map(([p,r])=>`${p} ${r}`).join(", ")}function I(C){g.value={...g.value,mode:C},C==="preset"&&!g.value.preset&&b.value[0]&&(g.value={...g.value,mode:C,preset:b.value[0].name})}function D(C,h){g.value={...g.value,fine:{...g.value.fine,[C]:h}}}function O(C){const h=k.options.sharpen.fine.find(p=>p.key===C);return h?`${h.range[0]}–${h.range[1]}`:""}return pe(async()=>{try{f.value=await Q.get("/api/image-batch/sharpen-presets")}catch{f.value=[]}}),(C,h)=>(t(),s("div",Dt,[q(ge,{"model-value":g.value.mode,label:"Sharpening",options:[{value:"none",label:"None"},{value:"preset",label:"Saved preset"},{value:"custom",label:"Custom"}],"onUpdate:modelValue":I},null,8,["model-value"]),g.value.mode==="preset"?(t(),s("div",Mt,[e("label",Lt,[h[5]||(h[5]=e("span",null,"Preset",-1)),e("select",{class:"select",value:g.value.preset,onChange:h[0]||(h[0]=p=>g.value={...g.value,preset:p.target.value})},[(t(!0),s(S,null,L(b.value,p=>(t(),s("option",{key:p.name,value:p.name},a(p.name)+" · "+a(p.scope),9,Ft))),128))],40,Rt)]),n.manage?(t(),s("button",{key:0,class:"link",onClick:h[1]||(h[1]=p=>G(i)("sharpen"))},"Manage presets")):d("",!0),z.value?(t(),s("p",Pt,[z.value.description?(t(),s(S,{key:0},[A(a(z.value.description)+" — ",1)],64)):d("",!0),A(" "+a(j(z.value)),1)])):d("",!0)])):d("",!0),g.value.mode==="custom"?(t(),s(S,{key:1},[e("div",qt,[e("label",Jt,[h[6]||(h[6]=e("span",null,"Sharpen for",-1)),e("select",{class:"select",value:g.value.for,onChange:h[2]||(h[2]=p=>g.value={...g.value,for:p.target.value})},[(t(!0),s(S,null,L(n.options.sharpen.targets,p=>(t(),s("option",{key:p,value:p},a(p),9,Wt))),128))],40,Kt)]),e("label",Ht,[h[7]||(h[7]=e("span",null,"Amount",-1)),e("select",{class:"select",value:g.value.amount,onChange:h[3]||(h[3]=p=>g.value={...g.value,amount:p.target.value})},[(t(!0),s(S,null,L(n.options.sharpen.amounts,p=>(t(),s("option",{key:p,value:p},a(p),9,Qt))),128))],40,Gt)])]),e("button",{class:"link",onClick:h[4]||(h[4]=p=>N.value=!N.value)},a(N.value?"Hide":"Show")+" fine settings ",1),N.value?(t(),s("div",Yt,[(t(!0),s(S,null,L(n.options.sharpen.fine,p=>(t(),s("label",{key:p.key,class:"field"},[e("span",null,[A(a(p.key)+" ",1),e("small",Zt,"("+a(O(p.key))+")",1)]),e("input",{class:"input",inputmode:"decimal",placeholder:"table value",value:g.value.fine[p.key],onInput:r=>D(p.key,r.target.value)},null,40,Xt)]))),128))])):d("",!0)],64)):d("",!0)]))}}),Me=oe(es,[["__scopeId","data-v-1d132e3d"]]);function Le(){return{mode:"none",preset:"",for:"screen",amount:"standard",fine:{radius:"",flat:"",jagged:"",threshold:""}}}function ts(n){if(n.mode==="none")return;if(n.mode==="preset")return n.preset?{preset:n.preset}:void 0;const k={for:n.for,amount:n.amount};for(const[i,g]of Object.entries(n.fine))g.trim()!==""&&(k[i]=Number(g));return k}const Re=["widths","heights","size","longEdge","shortEdge","megapixels","percent"],ss={widths:[800,1600],heights:[600],size:"1920x1080",longEdge:[1600],shortEdge:[1080],megapixels:[2],percent:[50]};function ls(n,k,i){const g={...n};return i===void 0||i===""||Array.isArray(i)&&i.length===0||typeof i=="number"&&Number.isNaN(i)?delete g[k]:g[k]=i,g}function as(n){for(const k of Re)if(n[k]!==void 0)return k;return"original"}function ns(n,k){const i={...n};for(const g of Re)delete i[g];return delete i.matchOrientation,k!=="original"&&(i[k]=ss[k]),i}function os(n,k){if(k==="original")return"";const i=n[k];return Array.isArray(i)?i.join(", "):String(i??"")}function is(n){const k=n.split(/[,\s]+/).filter(Boolean);if(k.length===0)return[];const i=k.map(Number);return i.some(g=>!Number.isFinite(g))?void 0:i}function Ne(n){const k=Le();if(n==null)return{state:k,lossy:!1};if(typeof n=="string")return{state:{...k,mode:"preset",preset:n},lossy:!1};if(typeof n!="object"||Array.isArray(n))return{state:k,lossy:!0};const i=n;if(typeof i.preset=="string")return Object.keys(i).filter(N=>N!=="preset").length===0?{state:{...k,mode:"preset",preset:i.preset},lossy:!1}:{state:{...k,mode:"preset",preset:i.preset},lossy:!0};const g={...k,mode:"custom"};typeof i.for=="string"&&(g.for=i.for),typeof i.amount=="string"&&(g.amount=i.amount);for(const f of["radius","flat","jagged","threshold"])i[f]!==void 0&&(g.fine[f]=String(i[f]));return{state:g,lossy:!1}}function Oe(n){if(n.mode==="none")return;if(n.mode==="preset")return n.preset||void 0;const k={for:n.for,amount:n.amount};for(const[i,g]of Object.entries(n.fine))g.trim()!==""&&(k[i]=Number(g));return k}function us(){return{name:"New config",outputs:[{id:"responsive",widths:[400,800,1200],formats:["webp","jpg"],quality:"high"}]}}function rs(n){return{id:`recipe-${n}`,widths:[800],formats:["webp"],quality:"high"}}const ds={class:"recipe"},cs={key:0,class:"grid"},vs={class:"field"},ps=["value"],ms={key:0,class:"field"},fs=["value"],gs=["value"],hs={class:"group"},bs={class:"grid"},ys={class:"field"},ks=["value"],$s=["value"],_s={key:0,class:"field"},ws=["value"],Cs={key:1,class:"field"},Ss=["value"],Vs={key:2,class:"field"},xs=["value"],Es=["value"],zs={key:0,class:"check"},As=["checked"],Ns={class:"group"},Os={key:0,class:"notice notice--warn"},Bs={key:1,class:"pills"},js=["checked","onChange"],Ts={key:0,class:"muted small"},Us={class:"grid"},Is={key:0,class:"field"},Ds=["value"],Ms=["value"],Ls={key:1,class:"field"},Rs=["value"],Fs={key:2,class:"notice notice--warn"},Ps={class:"field"},qs=["value"],Js={class:"group"},Ks=["value","placeholder"],Ws={class:"pills"},Hs=["onClick"],Gs={class:"group"},Qs={key:0,class:"notice notice--warn"},Ys={class:"group"},Zs={key:0,class:"grid"},Xs=["value","onChange"],el=["value"],tl=["value","onChange"],sl={class:"field"},ll=["value"],al={class:"field"},nl=["value"],ol=ne({__name:"RecipeForm",props:{modelValue:{},options:{},presetNames:{},isDefaults:{type:Boolean}},emits:["update:modelValue"],setup(n,{emit:k}){const i=n,g=k,f={original:"Keep the original size",widths:"By width (px)",heights:"By height (px)",size:"Fit into a box",longEdge:"By the long side (px)",shortEdge:"By the short side (px)",megapixels:"By area (megapixels)",percent:"By percentage"},N=[{key:"metadata",label:"Metadata",options:["strip","keep","keep-icc"]},{key:"rotate",label:"Rotate (degrees)",options:["90","180","270"]}],b=[{key:"withoutEnlargement",label:"Never enlarge"},{key:"autoOrient",label:"Turn by EXIF orientation"},{key:"grayscale",label:"Grayscale"},{key:"flip",label:"Flip vertically"},{key:"flop",label:"Mirror horizontally"}],z=v(""),j=v(!1),I=v(!1),D=v(!1),O=v(Ne(i.modelValue.sharpen).state),C=U(()=>as(i.modelValue)),h=U(()=>Array.isArray(i.modelValue.formats)?i.modelValue.formats:void 0),p=U(()=>i.modelValue.formats!==void 0&&h.value===void 0),r=U(()=>i.modelValue.quality),_=U(()=>r.value!==void 0&&typeof r.value=="object"),$=U(()=>{const y=r.value;return y===void 0?"":typeof y=="number"?"custom":String(y)}),F=U(()=>typeof i.modelValue.name=="string"?i.modelValue.name:""),K=U(()=>i.modelValue.maxBytes===void 0?"":String(i.modelValue.maxBytes)),P=U(()=>{const y=i.modelValue.sharpen;return y!==void 0&&typeof y!="string"&&typeof y!="object"});function M(y,l){g("update:modelValue",ls(i.modelValue,y,l))}function te(){z.value=os(i.modelValue,C.value),j.value=!1}ye(C,te,{immediate:!0}),ye(()=>i.modelValue.sharpen,y=>{const l=Ne(y);D.value=l.lossy,JSON.stringify(Oe(O.value))!==JSON.stringify(y)&&(O.value=l.state)},{immediate:!0});function V(y){g("update:modelValue",ns(i.modelValue,y.target.value))}function w(y){z.value=y;const l=is(y);j.value=l===void 0,l&&l.length>0&&C.value!=="original"&&C.value!=="size"&&M(C.value,l)}function x(y){const l=h.value??[];M("formats",l.includes(y)?l.filter(u=>u!==y):[...l,y])}function J(y){y===""?M("quality",void 0):y==="custom"?M("quality",82):M("quality",y)}function de(y){const l=y.trim();l===""?M("maxBytes",void 0):M("maxBytes",/^\d+$/.test(l)?Number(l):l)}function ie(y){O.value=y,M("sharpen",Oe(y))}function Z(y){const l=i.modelValue[y];return l===void 0?"":String(l)}function ue(y,l){M(y,l===""?void 0:l==="true")}function X(y){M("name",(F.value||"{dir}/{name}")+"{"+y+"}")}function ee(y){return"{"+y+"}"}return(y,l)=>(t(),s("div",ds,[n.isDefaults?d("",!0):(t(),s("div",cs,[e("label",vs,[l[13]||(l[13]=e("span",null,"Recipe name",-1)),e("input",{class:"input",spellcheck:"false",value:String(n.modelValue.id??""),onInput:l[0]||(l[0]=u=>M("id",u.target.value))},null,40,ps)]),n.presetNames&&n.presetNames.length?(t(),s("label",ms,[l[15]||(l[15]=e("span",null,"Based on preset",-1)),e("select",{class:"select",value:String(n.modelValue.preset??""),onChange:l[1]||(l[1]=u=>M("preset",u.target.value))},[l[14]||(l[14]=e("option",{value:""},"None",-1)),(t(!0),s(S,null,L(n.presetNames,u=>(t(),s("option",{key:u,value:u},a(u),9,gs))),128))],40,fs)])):d("",!0)])),e("div",hs,[l[21]||(l[21]=e("h4",null,"Size",-1)),e("div",bs,[e("label",ys,[l[16]||(l[16]=e("span",null,"Method",-1)),e("select",{class:"select",value:C.value,onChange:V},[(t(!0),s(S,null,L(n.options.sizeMethods,u=>(t(),s("option",{key:u,value:u},a(f[u]),9,$s))),128))],40,ks)]),C.value==="size"?(t(),s("label",_s,[l[17]||(l[17]=e("span",null,"Box (width × height)",-1)),e("input",{class:"input",spellcheck:"false",value:String(n.modelValue.size??""),onInput:l[2]||(l[2]=u=>M("size",u.target.value))},null,40,ws)])):C.value!=="original"?(t(),s("label",Cs,[l[18]||(l[18]=e("span",null,"Values (comma-separated)",-1)),e("input",{class:ae(["input",{"input--bad":j.value}]),spellcheck:"false",value:z.value,onInput:l[3]||(l[3]=u=>w(u.target.value))},null,42,Ss)])):d("",!0),C.value==="size"?(t(),s("label",Vs,[l[19]||(l[19]=e("span",null,"How it fills the box",-1)),e("select",{class:"select",value:String(n.modelValue.fit??"inside"),onChange:l[4]||(l[4]=u=>M("fit",u.target.value))},[(t(!0),s(S,null,L(n.options.fitModes,u=>(t(),s("option",{key:u,value:u},a(u),9,Es))),128))],40,xs)])):d("",!0)]),C.value==="size"?(t(),s("label",zs,[e("input",{type:"checkbox",checked:n.modelValue.matchOrientation===!0,onChange:l[5]||(l[5]=u=>M("matchOrientation",u.target.checked||void 0))},null,40,As),l[20]||(l[20]=A(" Turn the box around for portrait images ",-1))])):d("",!0)]),e("div",Ns,[l[27]||(l[27]=e("h4",null,"Formats and quality",-1)),p.value?(t(),s("p",Os," The formats of this recipe are set in a form the editor cannot show. Use the JSON tab. ")):(t(),s("div",Bs,[(t(!0),s(S,null,L(n.options.formats,u=>(t(),s("label",{key:u,class:ae(["pill",{"pill--on":h.value?.includes(u)}])},[e("input",{type:"checkbox",checked:h.value?.includes(u),onChange:H=>x(u)},null,40,js),A(" "+a(u),1)],2))),128)),h.value?d("",!0):(t(),s("span",Ts,"none chosen — inherited from the defaults"))])),e("div",Us,[_.value?d("",!0):(t(),s("label",Is,[l[24]||(l[24]=e("span",null,"Quality",-1)),e("select",{class:"select",value:$.value,onChange:l[6]||(l[6]=u=>J(u.target.value))},[l[22]||(l[22]=e("option",{value:""},"Default (high)",-1)),(t(!0),s(S,null,L(n.options.qualityLevels,u=>(t(),s("option",{key:u,value:u},a(u),9,Ms))),128)),l[23]||(l[23]=e("option",{value:"custom"},"A number…",-1))],40,Ds)])),$.value==="custom"?(t(),s("label",Ls,[l[25]||(l[25]=e("span",null,"Quality (1–100)",-1)),e("input",{class:"input",inputmode:"numeric",value:String(n.modelValue.quality),onInput:l[7]||(l[7]=u=>M("quality",Number(u.target.value)))},null,40,Rs)])):d("",!0),_.value?(t(),s("p",Fs," Quality is set per format here. Use the JSON tab to change it. ")):d("",!0),e("label",Ps,[l[26]||(l[26]=e("span",null,"Largest file size",-1)),e("input",{class:"input",spellcheck:"false",placeholder:"e.g. 200KB (optional)",value:K.value,onInput:l[8]||(l[8]=u=>de(u.target.value))},null,40,qs)])])]),e("div",Js,[l[28]||(l[28]=e("h4",null,"File names",-1)),e("input",{class:"input",spellcheck:"false",value:F.value,placeholder:n.options.defaultTemplates[C.value],"aria-label":"File name template",onInput:l[9]||(l[9]=u=>M("name",u.target.value))},null,40,Ks),e("div",Ws,[(t(!0),s(S,null,L(n.options.templateVariables,u=>(t(),s("button",{key:u,class:"pill pill--button",onClick:H=>X(u)},a(ee(u)),9,Hs))),128))])]),e("div",Gs,[l[29]||(l[29]=e("h4",null,"Sharpening",-1)),D.value||P.value?(t(),s("p",Qs," This sharpening combines a preset with extra values. Use the JSON tab to edit it. ")):(t(),le(Me,{key:1,"model-value":O.value,options:n.options,"onUpdate:modelValue":ie},null,8,["model-value","options"]))]),e("div",Ys,[e("button",{class:"link",onClick:l[10]||(l[10]=u=>I.value=!I.value)},a(I.value?"Hide":"Show")+" advanced settings ",1),I.value?(t(),s("div",Zs,[(t(),s(S,null,L(N,u=>e("label",{key:u.key,class:"field"},[e("span",null,a(u.label),1),e("select",{class:"select",value:u.key==="rotate"?String(n.modelValue.rotate??""):String(n.modelValue[u.key]??""),onChange:H=>M(u.key,u.key==="rotate"&&H.target.value?Number(H.target.value):H.target.value)},[l[30]||(l[30]=e("option",{value:""},"Default",-1)),(t(!0),s(S,null,L(u.options,H=>(t(),s("option",{key:H,value:H},a(H),9,el))),128))],40,Xs)])),64)),(t(),s(S,null,L(b,u=>e("label",{key:u.key,class:"field"},[e("span",null,a(u.label),1),e("select",{class:"select",value:Z(u.key),onChange:H=>ue(u.key,H.target.value)},[...l[31]||(l[31]=[e("option",{value:""},"Default",-1),e("option",{value:"true"},"Yes",-1),e("option",{value:"false"},"No",-1)])],40,tl)])),64)),e("label",sl,[l[32]||(l[32]=e("span",null,"Blur (sigma)",-1)),e("input",{class:"input",inputmode:"decimal",value:n.modelValue.blur===void 0?"":String(n.modelValue.blur),onInput:l[11]||(l[11]=u=>M("blur",u.target.value===""?void 0:Number(u.target.value)))},null,40,ll)]),e("label",al,[l[33]||(l[33]=e("span",null,"Background (#rrggbb)",-1)),e("input",{class:"input",spellcheck:"false",value:String(n.modelValue.background??""),onInput:l[12]||(l[12]=u=>M("background",u.target.value))},null,40,nl)])])):d("",!0)])]))}}),Be=oe(ol,[["__scopeId","data-v-6d67983e"]]),il={class:"card block"},ul={class:"head"},rl={key:0,class:"muted"},dl={class:"grid"},cl={class:"field"},vl={class:"field"},pl={value:"project"},ml={class:"field"},fl=["value"],gl={class:"field"},hl=["value"],bl={key:0,class:"notice"},yl={class:"panel"},kl={class:"panel__body"},$l={class:"recipes"},_l={class:"panel__head"},wl=["onClick"],Cl={class:"muted small"},Sl={class:"panel__actions"},Vl=["disabled","onClick"],xl=["disabled","onClick"],El=["onClick"],zl=["onClick"],Al={key:0,class:"panel__body"},Nl=["value"],Ol={key:0,class:"notice notice--error"},Bl={key:0,class:"lines"},jl={key:3,class:"notice notice--error"},Tl={class:"actions"},Ul=["disabled"],Il=ne({__name:"ConfigEditor",props:{options:{},initial:{},copyOf:{}},emits:["saved","cancel"],setup(n,{emit:k}){const i=n,g=k,f=he(xe,De),N=v(i.initial!==void 0),b=v(i.copyOf?structuredClone(i.copyOf.raw):us()),z=v(i.initial?i.initial.name:i.copyOf?`${i.copyOf.name}-copy`:""),j=v(i.initial?.scope??"project"),I=v("form"),D=v(""),O=v(""),C=v(),h=v(""),p=v(!1),r=v(0);let _;const $=U(()=>Array.isArray(b.value.outputs)?b.value.outputs:[]),F=U(()=>b.value.defaults&&typeof b.value.defaults=="object"?b.value.defaults:{}),K=U(()=>b.value.presets&&typeof b.value.presets=="object"?Object.keys(b.value.presets):[]),P=U(()=>{const E=[];return K.value.length&&E.push(`${K.value.length} preset(s)`),Array.isArray(b.value.match)&&b.value.match.length&&E.push(`${b.value.match.length} rule(s)`),b.value.placeholders&&E.push("placeholders"),E}),M=U(()=>(C.value?.lines??[]).join(`
|
|
2
|
+
`)),te=U(()=>!p.value&&z.value.trim()!==""&&C.value?.ok===!0&&O.value==="");function V(E){b.value=E}function w(E,c){const B={...b.value};c.trim()===""?delete B[E]:B[E]=c,V(B)}function x(E){const c={...b.value};Object.keys(E).length===0?delete c.defaults:c.defaults=E,V(c)}function J(E,c){const B=[...$.value];B[E]=c,V({...b.value,outputs:B})}function de(){V({...b.value,outputs:[...$.value,rs($.value.length+1)]}),r.value=$.value.length}function ie(E){V({...b.value,outputs:$.value.filter((c,B)=>B!==E)}),r.value=Math.max(0,r.value-1)}function Z(E){const c=structuredClone($.value[E]??{});typeof c.id=="string"&&(c.id=`${c.id}-copy`);const B=[...$.value];B.splice(E+1,0,c),V({...b.value,outputs:B}),r.value=E+1}function ue(E,c){const B=E+c;if(B<0||B>=$.value.length)return;const W=[...$.value],[re]=W.splice(E,1);W.splice(B,0,re),V({...b.value,outputs:W}),r.value=B}function X(E,c){return typeof E.id=="string"&&E.id?E.id:`Recipe ${c+1}`}function ee(E){const c=[];for(const B of["widths","heights","longEdge","shortEdge","megapixels","percent"])Array.isArray(E[B])&&c.push(`${B} ${E[B].join(", ")}`);return typeof E.size=="string"&&c.push(`box ${E.size}`),Array.isArray(E.formats)&&c.push(E.formats.join("/")),c.join(" · ")}function y(E){D.value=E;try{const c=JSON.parse(E);if(c===null||typeof c!="object"||Array.isArray(c)){O.value="A config is a JSON object.";return}O.value="",b.value=c}catch(c){O.value=c instanceof Error?c.message:String(c)}}function l(E){if(E==="json"){D.value=JSON.stringify(b.value,null,2),O.value="",I.value="json";return}O.value||(I.value="form")}async function u(){try{C.value=await Q.post("/api/image-batch/config/validate",{raw:b.value})}catch(E){C.value={ok:!1,error:E instanceof Error?E.message:String(E)}}}ye(b,()=>{clearTimeout(_),_=setTimeout(()=>{u()},350)},{deep:!0});async function H(E=!1){p.value=!0,h.value="";try{await Q.post("/api/image-batch/config/save",{name:z.value,scope:j.value,raw:b.value,overwrite:E,...i.initial?{originalName:i.initial.name,originalScope:i.initial.scope}:{}}),g("saved",z.value)}catch(c){if(c instanceof Ie&&c.status===409&&c.body.exists===!0){if(window.confirm(`${c.message}. Replace it?`)){await H(!0);return}}else h.value=c instanceof Error?c.message:String(c)}finally{p.value=!1}}return pe(async()=>{if(i.initial)try{const E=await Q.get(`/api/image-batch/config?name=${encodeURIComponent(i.initial.name)}&scope=${i.initial.scope}`);b.value=E.raw}catch(E){h.value=E instanceof Error?E.message:String(E)}finally{N.value=!1}u()}),Se(()=>clearTimeout(_)),(E,c)=>(t(),s("section",il,[e("div",ul,[e("h2",null,a(n.initial?`Edit ${n.initial.name}`:n.copyOf?"Copy of a config":"New config"),1),e("button",{class:"btn btn--ghost",onClick:c[0]||(c[0]=B=>g("cancel"))},[q(Y,{name:"close",size:16}),c[8]||(c[8]=A(" Close ",-1))])]),N.value?(t(),s("p",rl,"Loading…")):(t(),s(S,{key:1},[e("div",dl,[e("label",cl,[c[9]||(c[9]=e("span",null,"File name",-1)),R(e("input",{"onUpdate:modelValue":c[1]||(c[1]=B=>z.value=B),class:"input",spellcheck:"false",placeholder:"web"},null,512),[[se,z.value]])]),e("label",vl,[c[11]||(c[11]=e("span",null,"Where to keep it",-1)),R(e("select",{"onUpdate:modelValue":c[2]||(c[2]=B=>j.value=B),class:"select"},[e("option",pl,"This project ("+a(G(f).name)+")",1),c[10]||(c[10]=e("option",{value:"global"},"All projects (your home folder)",-1))],512),[[ve,j.value]])]),e("label",ml,[c[12]||(c[12]=e("span",null,"Title",-1)),e("input",{class:"input",value:String(b.value.name??""),onInput:c[3]||(c[3]=B=>w("name",B.target.value))},null,40,fl)]),e("label",gl,[c[13]||(c[13]=e("span",null,"Description",-1)),e("input",{class:"input",value:String(b.value.description??""),onInput:c[4]||(c[4]=B=>w("description",B.target.value))},null,40,hl)])]),q(ge,{"model-value":I.value,label:"Editor mode",options:[{value:"form",label:"Form"},{value:"json",label:"JSON"}],"onUpdate:modelValue":l},null,8,["model-value"]),I.value==="form"?(t(),s(S,{key:0},[P.value.length?(t(),s("p",bl," This config also has "+a(P.value.join(", "))+". They are kept as they are; edit them in the JSON tab. ",1)):d("",!0),e("details",yl,[c[14]||(c[14]=e("summary",null,"Defaults for every recipe",-1)),e("div",kl,[q(Be,{"model-value":F.value,options:n.options,"preset-names":K.value,"is-defaults":"","onUpdate:modelValue":x},null,8,["model-value","options","preset-names"])])]),e("div",$l,[(t(!0),s(S,null,L($.value,(B,W)=>(t(),s("div",{key:W,class:ae(["panel",{"panel--open":r.value===W}])},[e("div",_l,[e("button",{class:"panel__title",onClick:re=>r.value=r.value===W?-1:W},[e("strong",null,a(X(B,W)),1),e("span",Cl,a(ee(B)),1)],8,wl),e("div",Sl,[e("button",{class:"btn btn--ghost btn--small",disabled:W===0,"aria-label":"Move up",onClick:re=>ue(W,-1)},[q(Y,{name:"up",size:14})],8,Vl),e("button",{class:"btn btn--ghost btn--small",disabled:W===$.value.length-1,"aria-label":"Move down",onClick:re=>ue(W,1)},[q(Y,{name:"down",size:14})],8,xl),e("button",{class:"btn btn--ghost btn--small","aria-label":"Duplicate recipe",onClick:re=>Z(W)},[q(Y,{name:"copy",size:14})],8,El),e("button",{class:"btn btn--ghost btn--small btn--danger","aria-label":"Remove recipe",onClick:re=>ie(W)},[q(Y,{name:"close",size:14})],8,zl)])]),r.value===W?(t(),s("div",Al,[q(Be,{"model-value":B,options:n.options,"preset-names":K.value,"onUpdate:modelValue":re=>J(W,re)},null,8,["model-value","options","preset-names","onUpdate:modelValue"])])):d("",!0)],2))),128))]),e("button",{class:"btn",onClick:de},[q(Y,{name:"plus",size:16}),c[15]||(c[15]=A(" Add a recipe",-1))])],64)):(t(),s(S,{key:1},[e("textarea",{class:"json",spellcheck:"false",value:D.value,"aria-label":"Config JSON",onInput:c[5]||(c[5]=B=>y(B.target.value))},null,40,Nl),O.value?(t(),s("p",Ol,a(O.value),1)):d("",!0)],64)),C.value?(t(),s("div",{key:2,class:ae(["check-panel",C.value.ok?"check-panel--ok":"check-panel--bad"]),role:"status"},[C.value.ok?(t(),s(S,{key:0},[c[16]||(c[16]=e("strong",null,"The config is valid.",-1)),C.value.lines?.length?(t(),s("pre",Bl,a(M.value),1)):d("",!0)],64)):(t(),s(S,{key:1},[A(a(C.value.error),1)],64))],2)):d("",!0),h.value?(t(),s("p",jl,a(h.value),1)):d("",!0),e("div",Tl,[e("button",{class:"btn btn--primary",disabled:!te.value,onClick:c[6]||(c[6]=B=>H(!1))},[q(Y,{name:"save",size:15}),c[17]||(c[17]=A(" Save config ",-1))],8,Ul),e("button",{class:"btn",onClick:c[7]||(c[7]=B=>g("cancel"))},"Cancel")])],64))]))}}),Dl=oe(Il,[["__scopeId","data-v-5992429e"]]),Ml={class:"view"},Ll={key:1,class:"card block"},Rl={class:"head"},Fl={key:0,class:"notice"},Pl={key:1,class:"notice notice--error"},ql={key:2,class:"muted"},Jl={class:"list"},Kl={class:"item__main"},Wl={class:"item__title"},Hl={class:"tag"},Gl={key:0,class:"tag"},Ql={key:0,class:"item__error"},Yl={key:1,class:"muted"},Zl=["title"],Xl={class:"item__actions"},ea=["onClick"],ta=["onClick"],sa=["onClick"],la=ne({__name:"ConfigsView",props:{options:{}},setup(n){const k=v([]),i=v(""),g=v(""),f=v("list"),N=v(),b=v();async function z(){try{k.value=await Q.get("/api/image-batch/configs")}catch(h){i.value=h instanceof Error?h.message:String(h)}}function j(){N.value=void 0,b.value=void 0,f.value="edit"}function I(h){N.value=h,b.value=void 0,f.value="edit"}async function D(h){try{const p=await Q.get(`/api/image-batch/config?name=${encodeURIComponent(h.name)}&scope=${h.scope}`);N.value=void 0,b.value={name:h.name,raw:p.raw},f.value="edit"}catch(p){i.value=p instanceof Error?p.message:String(p)}}async function O(h){if(window.confirm(`Delete the config “${h.name}”? A .bak copy is kept next to it.`))try{await Q.post("/api/image-batch/config/delete",{name:h.name,scope:h.scope}),g.value=`Deleted ${h.name}.`,await z()}catch(p){i.value=p instanceof Error?p.message:String(p)}}async function C(h){f.value="list",g.value=`Saved ${h}.`,await z()}return pe(z),(h,p)=>(t(),s("div",Ml,[f.value==="edit"?(t(),le(Dl,{key:0,options:n.options,initial:N.value?{name:N.value.name,scope:N.value.scope}:void 0,"copy-of":b.value,onSaved:C,onCancel:p[0]||(p[0]=r=>f.value="list")},null,8,["options","initial","copy-of"])):(t(),s("section",Ll,[e("div",Rl,[p[2]||(p[2]=e("div",null,[e("h2",null,"Configs"),e("p",{class:"muted"}," A config is a reusable set of rules: sizes, formats, quality, names, sharpening. Apply it to any folder from the Convert tab. ")],-1)),e("button",{class:"btn btn--primary",onClick:j},[q(Y,{name:"plus",size:16}),p[1]||(p[1]=A(" New config ",-1))])]),g.value?(t(),s("p",Fl,a(g.value),1)):d("",!0),i.value?(t(),s("p",Pl,a(i.value),1)):d("",!0),k.value.length===0&&!i.value?(t(),s("p",ql," No configs yet. Create the first one, or use quick settings on the Convert tab. ")):d("",!0),e("ul",Jl,[(t(!0),s(S,null,L(k.value,r=>(t(),s("li",{key:r.scope+r.name+r.path,class:"item"},[e("div",Kl,[e("div",Wl,[e("strong",null,a(r.name),1),e("span",Hl,a(r.scope),1),r.kind!=="json"?(t(),s("span",Gl,"."+a(r.kind),1)):d("",!0)]),r.error?(t(),s("p",Ql,a(r.error),1)):(t(),s("p",Yl,[r.title?(t(),s(S,{key:0},[A(a(r.title)+" — ",1)],64)):d("",!0),A(" "+a(r.recipes)+" recipe"+a(r.recipes===1?"":"s")+" ",1),r.rules?(t(),s(S,{key:1},[A(", "+a(r.rules)+" rule"+a(r.rules===1?"":"s"),1)],64)):d("",!0),r.description?(t(),s(S,{key:2},[A(" · "+a(r.description),1)],64)):d("",!0)])),e("code",{class:"item__path",title:r.path},a(r.path),9,Zl)]),e("div",Xl,[r.editable?(t(),s("button",{key:0,class:"btn btn--small",onClick:_=>I(r)},"Edit",8,ea)):d("",!0),r.editable&&!r.error?(t(),s("button",{key:1,class:"btn btn--small",onClick:_=>D(r)}," Duplicate ",8,ta)):d("",!0),e("button",{class:"btn btn--small btn--danger",onClick:_=>O(r)},"Delete",8,sa)])]))),128))])]))]))}}),aa=oe(la,[["__scopeId","data-v-5b011a56"]]),na={class:"card block"},oa={class:"head"},ia={class:"muted"},ua={class:"chips"},ra={key:0,class:"chip"},da={key:1,class:"chip chip--good"},ca={key:0,class:"notice"},va={key:1,class:"notice"},pa={key:2,class:"muted small"},ma={key:3,class:"muted small"},fa={key:4,class:"errors"},ga={class:"rows"},ha=["src"],ba=["src"],ya={key:1,class:"row__thumb row__thumb--empty muted"},ka={class:"row__text"},$a=["title"],_a={class:"muted small"},wa={key:0,class:"small row__message"},Ca={class:"row__sizes"},Sa={key:0},Va={key:1,class:"muted"},xa={key:2},Ea={key:5,class:"more"},je=30,za=ne({__name:"BatchResults",props:{report:{}},setup(n){const k=n,i=he(ke,()=>{});function g(){try{k.report.backupDir&&localStorage.setItem("devtoolz-ui.open-backup",k.report.backupDir)}catch{i("backups");return}i("backups")}const f=v(je),N={written:"written","up-to-date":"up to date",skipped:"skipped",conflict:"conflict","would-write":"would write","would-overwrite":"would overwrite",replaced:"replaced",kept:"kept original","already-processed":"already processed","would-replace":"would replace","would-keep":"would keep",error:"error"},b=new Set(["written","replaced","up-to-date"]),z=new Set(["error","conflict"]),j=new Set(["written","replaced","up-to-date","skipped","kept"]),I=U(()=>Object.entries(k.report.counts).filter(([,r])=>r>0)),D=U(()=>{const{bytesIn:r,bytesOut:_}=k.report;if(!(k.report.dryRun||r<=0||_<=0))return{bytes:r-_,percent:Math.round((1-_/r)*100)}}),O=U(()=>k.report.results.slice(0,f.value));function C(r){return b.has(r)?"good":z.has(r)?"bad":"neutral"}function h(r){if(r.before===void 0||r.bytes===void 0||r.before<=0)return"";const _=Math.round((r.bytes/r.before-1)*100);return`${_>0?"+":""}${_}%`}function p(r){return!k.report.dryRun&&j.has(r.status)&&r.status!=="skipped"}return(r,_)=>(t(),s("section",na,[e("div",oa,[e("h2",null,a(n.report.dryRun?"Plan":"Result"),1),e("span",ia,[A(a(n.report.results.length)+" file"+a(n.report.results.length===1?"":"s")+" ",1),n.report.configLabel?(t(),s(S,{key:0},[A(" · config "+a(n.report.configLabel),1)],64)):d("",!0)])]),e("div",ua,[(t(!0),s(S,null,L(I.value,([$,F])=>(t(),s("span",{key:$,class:ae(["chip",`chip--${C($)}`])},a(F)+" "+a(N[$]),3))),128)),n.report.deduped?(t(),s("span",ra,a(n.report.deduped)+" merged (same result)",1)):d("",!0),D.value?(t(),s("span",da,[A(" saved "+a(G(ce)(Math.max(D.value.bytes,0)))+" ",1),D.value.percent>0?(t(),s(S,{key:0},[A("(−"+a(D.value.percent)+"%)",1)],64)):d("",!0)])):d("",!0)]),n.report.dryRun?(t(),s("p",ca," This is a preview: nothing was written. Press “Convert” to do it. ")):d("",!0),n.report.backupDir&&!n.report.dryRun?(t(),s("p",va,[_[2]||(_[2]=A(" Originals were copied to ",-1)),e("code",null,a(n.report.backupDir),1),_[3]||(_[3]=A(" first. ",-1)),e("button",{class:"link",onClick:g},"View or restore this backup")])):d("",!0),n.report.derived.length?(t(),s("p",pa,a(n.report.derived.length)+" earlier result"+a(n.report.derived.length===1?" was":"s were")+" not treated as sources. ",1)):d("",!0),n.report.vectors.length?(t(),s("p",ma,a(n.report.vectors.length)+" SVG file"+a(n.report.vectors.length===1?" was":"s were")+" left out of the replacement. ",1)):d("",!0),n.report.failures.length?(t(),s("ul",fa,[(t(!0),s(S,null,L(n.report.failures,$=>(t(),s("li",{key:$.file},[e("code",null,a($.file),1),A(" — "+a($.message),1)]))),128))])):d("",!0),e("ul",ga,[(t(!0),s(S,null,L(O.value,$=>(t(),s("li",{key:`${$.sourceAbs}|${$.outputAbs}|${$.recipe}`,class:"row"},[e("img",{class:"row__thumb",loading:"lazy",alt:"",src:G(be)($.sourceAbs,120)},null,8,ha),_[4]||(_[4]=e("span",{class:"row__arrow muted"},"→",-1)),p($)?(t(),s("img",{key:0,class:"row__thumb",loading:"lazy",alt:"",src:G(be)($.outputAbs,120)},null,8,ba)):(t(),s("span",ya,a(n.report.dryRun?"plan":"—"),1)),e("div",ka,[e("span",{class:"row__name",title:$.outputAbs},a($.output),9,$a),e("span",_a,[A(" from "+a($.source)+" · "+a($.width)+"×"+a($.height)+" · "+a($.format)+" ",1),$.recipe?(t(),s(S,{key:0},[A(" · "+a($.recipe),1)],64)):d("",!0)]),$.message?(t(),s("span",wa,a($.message),1)):d("",!0)]),e("div",Ca,[$.before!==void 0?(t(),s("span",Sa,a(G(ce)($.before)),1)):d("",!0),$.before!==void 0&&$.bytes!==void 0?(t(),s("span",Va,"→")):d("",!0),$.bytes!==void 0?(t(),s("strong",xa,a(G(ce)($.bytes)),1)):d("",!0),h($)?(t(),s("span",{key:3,class:ae(["row__delta",{"row__delta--down":h($).startsWith("-")}])},a(h($)),3)):d("",!0)]),e("span",{class:ae(["chip",`chip--${C($.status)}`])},a(N[$.status]),3)]))),128))]),f.value<n.report.results.length?(t(),s("div",Ea,[e("button",{class:"btn",onClick:_[0]||(_[0]=$=>f.value+=je)}," Show more ("+a(n.report.results.length-f.value)+" left) ",1),e("button",{class:"btn",onClick:_[1]||(_[1]=$=>f.value=n.report.results.length)}," Show all ("+a(n.report.results.length)+") ",1)])):d("",!0)]))}}),Aa=oe(za,[["__scopeId","data-v-b00b9955"]]),Na={class:"view"},Oa={key:0,class:"notice notice--warn"},Ba={class:"card block"},ja={class:"pathrow"},Ta={class:"check"},Ua={key:1,class:"muted"},Ia={class:"check"},Da={class:"check"},Ma={key:3,class:"field narrow"},La={class:"card block"},Ra={class:"head"},Fa={key:0,class:"muted"},Pa={class:"field narrow"},qa=["value","disabled"],Ja={key:0,class:"muted"},Ka={class:"group"},Wa={class:"grid"},Ha={class:"field"},Ga=["value"],Qa={key:0,class:"field"},Ya={key:1,class:"field"},Za=["placeholder"],Xa={key:2,class:"field"},en=["value"],tn={key:0,class:"check"},sn={key:1,class:"muted small"},ln={class:"group"},an={key:0,class:"muted small"},nn={key:1,class:"pills"},on=["checked","onChange"],un={class:"grid"},rn={class:"field"},dn=["value"],cn={key:0,class:"field"},vn={class:"field"},pn={key:0,class:"group"},mn=["placeholder"],fn={class:"pills"},gn=["onClick"],hn={class:"muted small"},bn={class:"group"},yn={class:"runbar"},kn=["disabled"],$n=["disabled"],_n={key:0,class:"muted"},wn={key:1,class:"card block",role:"status"},Cn={class:"progress"},Sn={class:"muted"},Vn={key:2,class:"notice notice--error"},xn=ne({__name:"ConvertView",props:{cwd:{},options:{}},setup(n){const k=n,i=he(ke,()=>{}),g={original:"Keep the original size",widths:"By width (px)",heights:"By height (px)",size:"Fit into a box",longEdge:"By the long side (px)",shortEdge:"By the short side (px)",megapixels:"By area (megapixels)",percent:"By percentage"},f={original:"",widths:"e.g. 400, 800, 1200 — one file per size",heights:"e.g. 300, 600",size:"",longEdge:"e.g. 1600 — the same for landscape and portrait",shortEdge:"e.g. 1080",megapixels:"e.g. 2, 0.5",percent:"e.g. 50, 25"},N={name:"photo",ext:"jpg",orig:"photo.jpg",dir:"trips/2026",format:"webp",width:"800",height:"600",size:"800x600",long:"800",short:"600",mp:"0.48",percent:"50",scale:"2",index:"001",hash:"a1b2c3d4",date:"2026-10-08"},b=U(()=>k.options),z=v([]),j=v([]),I=v(!0),D=v(0),O=v("out"),C=v(""),h=v(!1),p=v("skip"),r=v(!0),_=v(!0),$=v(!1),F=v("quick"),K=v(""),P=v("widths"),M=v("800, 1600"),te=v("1920x1080"),V=v("inside"),w=v(!1),x=v(["webp"]),J=v(""),de=v("82"),ie=v(""),Z=v(""),ue=v(Le()),X=v("idle"),ee=v({done:0,total:0}),y=v(""),l=v();let u;const H=U(()=>k.cwd.includes("\\")?"\\":"/"),E=U(()=>y.value.toLowerCase().includes("sharp")),c=U(()=>z.value.find(T=>T.name===K.value)),B=U(()=>ee.value.total>0?Math.round(ee.value.done/ee.value.total*100):0),W=U(()=>b.value?.defaultTemplates[P.value]??"{dir}/{name}.{format}"),re=U(()=>(Z.value.trim()||W.value).replace(/\{([a-zA-Z]+)(?::(\d+))?\}/g,(o,m)=>N[m]??`{${m}}`)),$e=U(()=>j.value.length===0?"Add at least one folder or image.":D.value===0&&j.value.length>0?"No images found in the added sources.":O.value==="out"&&C.value.trim()===""?"Choose the folder for the results.":F.value==="config"&&K.value===""?"Choose a saved config.":F.value==="quick"&&O.value!=="replace"&&x.value.length===0?"Pick at least one format.":""),Ee=U(()=>$e.value===""&&X.value!=="running");function Fe(T){D.value=T?.total.files??0,j.value.length>0&&T===void 0&&(D.value=1)}function Pe(T){x.value=x.value.includes(T)?x.value.filter(o=>o!==T):[...x.value,T]}function qe(T){return"{"+T+"}"}function Je(T){C.value=T[0]??C.value,$.value=!1}function Ke(T){Z.value=(Z.value||W.value)+`{${T}}`}function We(){const T=j.value[0];if(C.value!==""||!T)return;const o=T.replace(/[\\/]+$/,"");C.value=`${o}${H.value}converted`}function He(){const T={sizeMethod:P.value};P.value==="size"?(T.box=te.value,T.fit=V.value,T.matchOrientation=w.value):P.value!=="original"&&(T.values=M.value.split(/[,\s]+/).filter(Boolean).map(Number)),T.formats=O.value==="replace"?["original"]:x.value,J.value==="custom"?T.quality=Number(de.value):J.value&&(T.quality=J.value),ie.value.trim()&&(T.maxBytes=ie.value.trim()),O.value!=="replace"&&Z.value.trim()&&(T.name=Z.value.trim());const o=ts(ue.value);return o&&(T.sharpen=o),T}async function _e(T,o=!1){if(!(!T&&O.value==="replace"&&!window.confirm(`This rewrites ${D.value} original file${D.value===1?"":"s"} in place.`+(r.value?" The originals are copied to a backup folder first.":" No backup will be made.")+`
|
|
3
|
+
|
|
4
|
+
Continue?`))){u?.(),X.value="running",y.value="",l.value=void 0,ee.value={done:0,total:0};try{const{jobId:m}=await Q.post("/api/image-batch/run",{paths:j.value,recursive:I.value,placement:O.value,out:C.value,flat:h.value,overwrite:p.value,backup:r.value,onlyIfSmaller:_.value,config:F.value==="config"?K.value:void 0,settings:F.value==="quick"?He():void 0,dryRun:T,installSharp:o});u=Xe(m,{onProgress:me=>{ee.value=me},onDone:me=>{l.value=me,X.value="done"},onFailed:me=>{y.value=me,X.value="failed"}})}catch(m){y.value=m instanceof Error?m.message:String(m),X.value="failed"}}}return pe(async()=>{try{z.value=await Q.get("/api/image-batch/configs")}catch(T){y.value=T instanceof Error?T.message:String(T),X.value="failed"}}),Se(()=>u?.()),(T,o)=>(t(),s("div",Na,[b.value&&!b.value.sharp?(t(),s("div",Oa," The sharp image library is not installed yet. Previews are limited, and the first run will offer to install it. ")):d("",!0),q(et,{sources:j.value,"onUpdate:sources":o[0]||(o[0]=m=>j.value=m),recursive:I.value,"onUpdate:recursive":o[1]||(o[1]=m=>I.value=m),"scan-url":"/api/image-batch/scan",start:n.cwd,onScanned:Fe},null,8,["sources","recursive","start"]),e("section",Ba,[o[34]||(o[34]=e("h2",null,"Where the results go",-1)),q(ge,{modelValue:O.value,"onUpdate:modelValue":[o[2]||(o[2]=m=>O.value=m),We],label:"Placement",options:[{value:"out",label:"A separate folder",hint:"the sources are not touched"},{value:"beside",label:"Next to each original",hint:"new files beside the sources"},{value:"replace",label:"Replace the originals",hint:"rewrites the files, with a backup"}]},null,8,["modelValue"]),O.value==="out"?(t(),s(S,{key:0},[e("div",ja,[R(e("input",{"onUpdate:modelValue":o[3]||(o[3]=m=>C.value=m),class:"input",spellcheck:"false",placeholder:"Folder for the results","aria-label":"Folder for the results"},null,512),[[se,C.value]]),e("button",{class:"btn",onClick:o[4]||(o[4]=m=>$.value=!0)},[q(Y,{name:"folder",size:16}),o[27]||(o[27]=A(" Browse ",-1))])]),e("label",Ta,[R(e("input",{"onUpdate:modelValue":o[5]||(o[5]=m=>h.value=m),type:"checkbox"},null,512),[[fe,h.value]]),o[28]||(o[28]=A(" Put everything in one folder (no subfolders) ",-1))])],64)):O.value==="beside"?(t(),s("p",Ua," Each result is written next to its original, with the size or format in the name. ")):(t(),s(S,{key:2},[o[31]||(o[31]=e("p",{class:"notice notice--warn"}," Each original is overwritten with its converted version, keeping its own format. Use the preview first. ",-1)),e("label",Ia,[R(e("input",{"onUpdate:modelValue":o[6]||(o[6]=m=>r.value=m),type:"checkbox"},null,512),[[fe,r.value]]),o[29]||(o[29]=A(" Copy the originals to a backup folder first",-1))]),e("label",Da,[R(e("input",{"onUpdate:modelValue":o[7]||(o[7]=m=>_.value=m),type:"checkbox"},null,512),[[fe,_.value]]),o[30]||(o[30]=A(" Replace a file only when the result is smaller ",-1))])],64)),O.value!=="replace"?(t(),s("label",Ma,[o[33]||(o[33]=e("span",null,"If a result already exists",-1)),R(e("select",{"onUpdate:modelValue":o[8]||(o[8]=m=>p.value=m),class:"select"},[...o[32]||(o[32]=[e("option",{value:"skip"},"Skip it",-1),e("option",{value:"overwrite"},"Overwrite it",-1),e("option",{value:"error"},"Stop and report it",-1)])],512),[[ve,p.value]])])):d("",!0)]),e("section",La,[e("div",Ra,[o[35]||(o[35]=e("h2",null,"What to do",-1)),q(ge,{modelValue:F.value,"onUpdate:modelValue":o[9]||(o[9]=m=>F.value=m),label:"Settings source",options:[{value:"quick",label:"Quick settings"},{value:"config",label:"Saved config"}]},null,8,["modelValue"])]),F.value==="config"?(t(),s(S,{key:0},[z.value.length===0?(t(),s("p",Fa,[o[36]||(o[36]=A(" No configs yet. ",-1)),e("button",{class:"link",onClick:o[10]||(o[10]=m=>G(i)("configs"))},"Create the first one"),o[37]||(o[37]=A(" or use quick settings. ",-1))])):(t(),s(S,{key:1},[e("label",Pa,[o[39]||(o[39]=e("span",null,"Config",-1)),R(e("select",{"onUpdate:modelValue":o[11]||(o[11]=m=>K.value=m),class:"select"},[o[38]||(o[38]=e("option",{value:"",disabled:""},"Choose a config…",-1)),(t(!0),s(S,null,L(z.value,m=>(t(),s("option",{key:m.name+m.scope,value:m.name,disabled:!!m.error},a(m.name)+" · "+a(m.scope),9,qa))),128))],512),[[ve,K.value]])]),e("button",{class:"link",onClick:o[12]||(o[12]=m=>G(i)("configs"))},"Manage configs"),c.value?(t(),s("p",Ja,[c.value.title?(t(),s(S,{key:0},[A(a(c.value.title)+" — ",1)],64)):d("",!0),A(" "+a(c.value.recipes)+" recipe"+a(c.value.recipes===1?"":"s")+" ",1),c.value.rules?(t(),s(S,{key:1},[A(", "+a(c.value.rules)+" rule"+a(c.value.rules===1?"":"s"),1)],64)):d("",!0),c.value.description?(t(),s(S,{key:2},[A(" · "+a(c.value.description),1)],64)):d("",!0)])):d("",!0)],64))],64)):b.value?(t(),s(S,{key:1},[e("div",Ka,[o[45]||(o[45]=e("h3",null,"Size",-1)),e("div",Wa,[e("label",Ha,[o[40]||(o[40]=e("span",null,"Method",-1)),R(e("select",{"onUpdate:modelValue":o[13]||(o[13]=m=>P.value=m),class:"select"},[(t(!0),s(S,null,L(b.value.sizeMethods,m=>(t(),s("option",{key:m,value:m},a(g[m]),9,Ga))),128))],512),[[ve,P.value]])]),P.value==="size"?(t(),s("label",Qa,[o[41]||(o[41]=e("span",null,"Box (width × height)",-1)),R(e("input",{"onUpdate:modelValue":o[14]||(o[14]=m=>te.value=m),class:"input",spellcheck:"false",placeholder:"1920x1080"},null,512),[[se,te.value]])])):P.value!=="original"?(t(),s("label",Ya,[o[42]||(o[42]=e("span",null,"Values",-1)),R(e("input",{"onUpdate:modelValue":o[15]||(o[15]=m=>M.value=m),class:"input",spellcheck:"false",placeholder:f[P.value]},null,8,Za),[[se,M.value]])])):d("",!0),P.value==="size"?(t(),s("label",Xa,[o[43]||(o[43]=e("span",null,"How it fills the box",-1)),R(e("select",{"onUpdate:modelValue":o[16]||(o[16]=m=>V.value=m),class:"select"},[(t(!0),s(S,null,L(b.value.fitModes,m=>(t(),s("option",{key:m,value:m},a(m),9,en))),128))],512),[[ve,V.value]])])):d("",!0)]),P.value==="size"?(t(),s("label",tn,[R(e("input",{"onUpdate:modelValue":o[17]||(o[17]=m=>w.value=m),type:"checkbox"},null,512),[[fe,w.value]]),o[44]||(o[44]=A(" Turn the box around for portrait images ",-1))])):f[P.value]?(t(),s("p",sn,a(f[P.value])+". Images are never enlarged. ",1)):d("",!0)]),e("div",ln,[o[51]||(o[51]=e("h3",null,"Formats",-1)),O.value==="replace"?(t(),s("p",an," Each file keeps its own format when the originals are replaced. ")):(t(),s("div",nn,[(t(!0),s(S,null,L(b.value.formats,m=>(t(),s("label",{key:m,class:ae(["pill",{"pill--on":x.value.includes(m)}])},[e("input",{type:"checkbox",checked:x.value.includes(m),onChange:me=>Pe(m)},null,40,on),A(" "+a(m),1)],2))),128))])),e("div",un,[e("label",rn,[o[48]||(o[48]=e("span",null,"Quality",-1)),R(e("select",{"onUpdate:modelValue":o[18]||(o[18]=m=>J.value=m),class:"select"},[o[46]||(o[46]=e("option",{value:""},"Default (high)",-1)),(t(!0),s(S,null,L(b.value.qualityLevels,m=>(t(),s("option",{key:m,value:m},a(m),9,dn))),128)),o[47]||(o[47]=e("option",{value:"custom"},"A number…",-1))],512),[[ve,J.value]])]),J.value==="custom"?(t(),s("label",cn,[o[49]||(o[49]=e("span",null,"Quality (1–100)",-1)),R(e("input",{"onUpdate:modelValue":o[19]||(o[19]=m=>de.value=m),class:"input",inputmode:"numeric"},null,512),[[se,de.value]])])):d("",!0),e("label",vn,[o[50]||(o[50]=e("span",null,"Largest file size",-1)),R(e("input",{"onUpdate:modelValue":o[20]||(o[20]=m=>ie.value=m),class:"input",spellcheck:"false",placeholder:"e.g. 200KB (optional)"},null,512),[[se,ie.value]])])])]),O.value!=="replace"?(t(),s("div",pn,[o[53]||(o[53]=e("h3",null,"File names",-1)),R(e("input",{"onUpdate:modelValue":o[21]||(o[21]=m=>Z.value=m),class:"input",spellcheck:"false",placeholder:W.value,"aria-label":"File name template"},null,8,mn),[[se,Z.value]]),e("div",fn,[(t(!0),s(S,null,L(b.value.templateVariables,m=>(t(),s("button",{key:m,class:"pill pill--button",onClick:me=>Ke(m)},a(qe(m)),9,gn))),128))]),e("p",hn,[o[52]||(o[52]=A(" Example: ",-1)),e("code",null,a(re.value),1),Z.value.trim()?d("",!0):(t(),s(S,{key:0},[A(" (the default for this size method)")],64))])])):d("",!0),e("div",bn,[o[54]||(o[54]=e("h3",null,"Sharpening",-1)),q(Me,{modelValue:ue.value,"onUpdate:modelValue":o[22]||(o[22]=m=>ue.value=m),options:b.value,manage:""},null,8,["modelValue","options"])])],64)):d("",!0)]),e("div",yn,[e("button",{class:"btn",disabled:!Ee.value,onClick:o[23]||(o[23]=m=>_e(!0))},"Preview",8,kn),e("button",{class:"btn btn--primary",disabled:!Ee.value,onClick:o[24]||(o[24]=m=>_e(!1))},[q(Y,{name:"play",size:15}),A(" "+a(X.value==="running"?"Working…":"Convert"),1)],8,$n),$e.value?(t(),s("span",_n,a($e.value),1)):d("",!0)]),X.value==="running"?(t(),s("div",wn,[e("div",Cn,[e("div",{class:"progress__bar",style:Ce({width:`${B.value}%`})},null,4)]),e("span",Sn,a(ee.value.done)+" of "+a(ee.value.total||"…")+" files",1)])):d("",!0),X.value==="failed"?(t(),s("div",Vn,[e("p",null,a(y.value),1),E.value?(t(),s("button",{key:0,class:"btn btn--small",onClick:o[25]||(o[25]=m=>_e(!1,!0))}," Install sharp and retry ")):d("",!0)])):d("",!0),l.value?(t(),le(Aa,{key:3,report:l.value},null,8,["report"])):d("",!0),$.value?(t(),le(Ve,{key:4,start:C.value||j.value[0]||n.cwd,mode:"folder",title:"Choose the folder for the results",onClose:o[26]||(o[26]=m=>$.value=!1),onConfirm:Je},null,8,["start"])):d("",!0)]))}}),En=oe(xn,[["__scopeId","data-v-ecb5fab6"]]),zn=["aria-busy"],An={class:"compare__scroll"},Nn={class:"compare__stage"},On=["src"],Bn=["src"],jn={class:"compare__tag compare__tag--left"},Tn={class:"compare__tag compare__tag--right"},Un=ne({__name:"UiCompare",props:{before:{},after:{},beforeLabel:{},afterLabel:{}},setup(n){const k=v(50),i=v(!0);return(g,f)=>(t(),s("div",{class:"compare","aria-busy":i.value},[e("div",An,[e("div",Nn,[e("img",{class:"compare__img",alt:"Before",src:n.before,onLoad:f[0]||(f[0]=N=>i.value=!1)},null,40,On),e("img",{class:"compare__img compare__img--top",alt:"After",src:n.after,style:Ce({clipPath:`inset(0 0 0 ${k.value}%)`})},null,12,Bn),e("span",{class:"compare__line",style:Ce({left:`${k.value}%`})},null,4),e("span",jn,a(n.beforeLabel??"Before"),1),e("span",Tn,a(n.afterLabel??"After"),1)])]),R(e("input",{"onUpdate:modelValue":f[1]||(f[1]=N=>k.value=N),class:"compare__range",type:"range",min:"0",max:"100","aria-label":"Comparison position"},null,512),[[se,k.value,void 0,{number:!0}]])],8,zn))}}),In=oe(Un,[["__scopeId","data-v-0ee1b3e3"]]),Dn={class:"card block"},Mn={class:"head"},Ln={class:"grid"},Rn={class:"field"},Fn={class:"field"},Pn={value:"project"},qn={class:"field wide"},Jn={class:"grid"},Kn={class:"field"},Wn=["value"],Hn={class:"field"},Gn=["value"],Qn={class:"grid"},Yn={class:"muted"},Zn=["onUpdate:modelValue"],Xn={key:0,class:"notice notice--error"},eo={key:1,class:"muted small"},to={class:"preview"},so={class:"head"},lo={class:"previewbar"},ao={class:"field inline"},no={key:0,class:"muted"},oo={key:2,class:"muted small"},io={key:2,class:"notice notice--error"},uo={class:"actions"},ro=["disabled"],Te="devtoolz-ui.sharpen-sample",co=ne({__name:"SharpenEditor",props:{options:{},cwd:{},initial:{},copyOf:{}},emits:["saved","cancel"],setup(n,{emit:k}){const i=n,g=k,f=he(xe,De),N=["radius","flat","jagged","threshold"];function b(){return i.initial??i.copyOf}function z(y){const l=b()?.fields?.[y];return l===void 0?"":String(l)}const j=U(()=>i.initial!==void 0),I=v(i.initial?i.initial.name:i.copyOf?.name??""),D=v(i.initial&&i.initial.scope!=="built-in"?i.initial.scope:"project"),O=v(b()?.description??""),C=v(String(b()?.fields?.for??"")),h=v(String(b()?.fields?.amount??"")),p=v({radius:z("radius"),flat:z("flat"),jagged:z("jagged"),threshold:z("threshold")}),r=v(""),_=v("800"),$=v(!1),F=v(),K=v(""),P=v(""),M=v(!1),te=v("");let V;const w=U(()=>Object.fromEntries(i.options.sharpen.fine.map(y=>[y.key,y.range])));function x(){const y={};C.value&&(y.for=C.value),h.value&&(y.amount=h.value);for(const l of N)p.value[l].trim()!==""&&(y[l]=Number(p.value[l]));return y}function J(y){const l=new URLSearchParams({path:r.value,width:_.value||"800"});if(y){l.set("sharpen","1");for(const[u,H]of Object.entries(x()))l.set(u,String(H))}return`/api/image-batch/sharpen-preview?${l.toString()}&v=${te.value}`}const de=U(()=>r.value?J(!1):""),ie=U(()=>r.value?J(!0):"");async function Z(){try{const y=await Q.post("/api/image-batch/sharpen-preset/params",{fields:x()});F.value=y.params,K.value=""}catch(y){F.value=void 0,K.value=y instanceof Error?y.message:String(y)}te.value=JSON.stringify(x())+_.value}function ue(){clearTimeout(V),V=setTimeout(()=>{Z()},300)}ye([C,h,p,_],ue,{deep:!0});function X(y){r.value=y[0]??"",$.value=!1;try{localStorage.setItem(Te,r.value)}catch{r.value=y[0]??""}}async function ee(y=!1){M.value=!0,P.value="";try{await Q.post("/api/image-batch/sharpen-preset/save",{name:I.value,scope:D.value,description:O.value,fields:x(),overwrite:y,...i.initial?{originalName:i.initial.name,originalScope:i.initial.scope}:{}}),g("saved",I.value)}catch(l){if(l instanceof Ie&&l.status===409){if(window.confirm(`${l.message}. Replace it?`)){await ee(!0);return}}else P.value=l instanceof Error?l.message:String(l)}finally{M.value=!1}}return pe(()=>{try{r.value=localStorage.getItem(Te)??""}catch{r.value=""}Z()}),Se(()=>clearTimeout(V)),(y,l)=>(t(),s("section",Dn,[e("div",Mn,[e("h2",null,a(j.value?"Edit preset":n.copyOf?"Copy of a built-in preset":"New sharpening preset"),1),e("button",{class:"btn btn--ghost",onClick:l[0]||(l[0]=u=>g("cancel"))},[q(Y,{name:"close",size:16}),l[11]||(l[11]=A(" Close ",-1))])]),e("div",Ln,[e("label",Rn,[l[12]||(l[12]=e("span",null,"Name",-1)),R(e("input",{"onUpdate:modelValue":l[1]||(l[1]=u=>I.value=u),class:"input",spellcheck:"false",placeholder:"web-crisp"},null,512),[[se,I.value]])]),e("label",Fn,[l[14]||(l[14]=e("span",null,"Where to keep it",-1)),R(e("select",{"onUpdate:modelValue":l[2]||(l[2]=u=>D.value=u),class:"select"},[e("option",Pn,"This project ("+a(G(f).name)+")",1),l[13]||(l[13]=e("option",{value:"global"},"All projects (your home folder)",-1))],512),[[ve,D.value]])]),e("label",qn,[l[15]||(l[15]=e("span",null,"Note (optional)",-1)),R(e("input",{"onUpdate:modelValue":l[3]||(l[3]=u=>O.value=u),class:"input",placeholder:"What it is for"},null,512),[[se,O.value]])])]),e("div",Jn,[e("label",Kn,[l[17]||(l[17]=e("span",null,"Sharpen for",-1)),R(e("select",{"onUpdate:modelValue":l[4]||(l[4]=u=>C.value=u),class:"select"},[l[16]||(l[16]=e("option",{value:""},"Default (screen)",-1)),(t(!0),s(S,null,L(n.options.sharpen.targets,u=>(t(),s("option",{key:u,value:u},a(u),9,Wn))),128))],512),[[ve,C.value]])]),e("label",Hn,[l[19]||(l[19]=e("span",null,"Amount",-1)),R(e("select",{"onUpdate:modelValue":l[5]||(l[5]=u=>h.value=u),class:"select"},[l[18]||(l[18]=e("option",{value:""},"Default (standard)",-1)),(t(!0),s(S,null,L(n.options.sharpen.amounts,u=>(t(),s("option",{key:u,value:u},a(u),9,Gn))),128))],512),[[ve,h.value]])])]),e("div",Qn,[(t(),s(S,null,L(N,u=>e("label",{key:u,class:"field"},[e("span",null,[A(a(u)+" ",1),e("small",Yn,"("+a(w.value[u]?.[0])+"–"+a(w.value[u]?.[1])+")",1)]),R(e("input",{"onUpdate:modelValue":H=>p.value[u]=H,class:"input",inputmode:"decimal",placeholder:"value from the table"},null,8,Zn),[[se,p.value[u]]])])),64))]),K.value?(t(),s("p",Xn,a(K.value),1)):F.value?(t(),s("p",eo,[A(" sharp receives: sigma "+a(F.value.sigma)+", flat "+a(F.value.m1)+", jagged "+a(F.value.m2),1),F.value.x1!==void 0?(t(),s(S,{key:0},[A(", threshold "+a(F.value.x1),1)],64)):d("",!0)])):d("",!0),e("div",to,[e("div",so,[l[21]||(l[21]=e("h3",null,"Preview",-1)),e("div",lo,[e("label",ao,[l[20]||(l[20]=e("span",null,"Width",-1)),R(e("input",{"onUpdate:modelValue":l[6]||(l[6]=u=>_.value=u),class:"input narrow",inputmode:"numeric","aria-label":"Preview width"},null,512),[[se,_.value]])]),e("button",{class:"btn btn--small",onClick:l[7]||(l[7]=u=>$.value=!0)},[q(Y,{name:"image",size:15}),A(" "+a(r.value?"Change image":"Choose an image"),1)])])]),r.value?K.value?d("",!0):(t(),le(In,{key:r.value,before:de.value,after:ie.value,"before-label":"Without sharpening","after-label":"Sharpened"},null,8,["before","after"])):(t(),s("p",no," Pick any photo to see the preset applied at the output size. Drag the slider to compare. ")),r.value?(t(),s("p",oo,a(r.value)+" — resized to "+a(_.value||800)+" px wide, then sharpened, as it would be at the output size. ",1)):d("",!0)]),P.value?(t(),s("p",io,a(P.value),1)):d("",!0),e("div",uo,[e("button",{class:"btn btn--primary",disabled:M.value||I.value.trim()==="",onClick:l[8]||(l[8]=u=>ee(!1))},[q(Y,{name:"save",size:15}),l[22]||(l[22]=A(" Save preset ",-1))],8,ro),e("button",{class:"btn",onClick:l[9]||(l[9]=u=>g("cancel"))},"Cancel")]),$.value?(t(),le(Ve,{key:3,start:r.value?r.value.replace(/[\\/][^\\/]*$/,""):n.cwd,mode:"image",onClose:l[10]||(l[10]=u=>$.value=!1),onConfirm:X},null,8,["start"])):d("",!0)]))}}),vo=oe(co,[["__scopeId","data-v-8e3f1eea"]]),po={class:"view"},mo={key:1,class:"card block"},fo={class:"head"},go={key:0,class:"notice"},ho={key:1,class:"notice notice--error"},bo={class:"list"},yo={class:"item__main"},ko={class:"item__title"},$o={key:0,class:"item__error"},_o={key:0,class:"muted"},wo={class:"item__facts"},Co={key:0,class:"muted"},So={class:"item__actions"},Vo=["onClick"],xo=["onClick"],Eo=["onClick"],zo=ne({__name:"SharpenView",props:{options:{},cwd:{}},setup(n){const k=v([]),i=v(""),g=v(""),f=v("list"),N=v(),b=v();async function z(){try{k.value=await Q.get("/api/image-batch/sharpen-presets")}catch(p){i.value=p instanceof Error?p.message:String(p)}}function j(){N.value=void 0,b.value=void 0,f.value="edit"}function I(p){N.value=p,b.value=void 0,f.value="edit"}function D(p){N.value=void 0,b.value=p,f.value="edit"}async function O(p){if(window.confirm(`Delete the preset “${p.name}”? A .bak copy is kept next to it.`))try{await Q.post("/api/image-batch/sharpen-preset/delete",{name:p.name,scope:p.scope}),g.value=`Deleted ${p.name}.`,await z()}catch(r){i.value=r instanceof Error?r.message:String(r)}}async function C(p){f.value="list",g.value=`Saved ${p}.`,await z()}function h(p){return Object.entries(p.fields??{}).map(([r,_])=>`${r} ${_}`).join(" · ")}return pe(z),(p,r)=>(t(),s("div",po,[f.value==="edit"?(t(),le(vo,{key:0,options:n.options,cwd:n.cwd,initial:N.value,"copy-of":b.value,onSaved:C,onCancel:r[0]||(r[0]=_=>f.value="list")},null,8,["options","cwd","initial","copy-of"])):(t(),s("section",mo,[e("div",fo,[r[2]||(r[2]=e("div",null,[e("h2",null,"Sharpening presets"),e("p",{class:"muted"}," Save a set of sharpening values once and use it by name in any config or run. ")],-1)),e("button",{class:"btn btn--primary",onClick:j},[q(Y,{name:"plus",size:16}),r[1]||(r[1]=A(" New preset ",-1))])]),g.value?(t(),s("p",go,a(g.value),1)):d("",!0),i.value?(t(),s("p",ho,a(i.value),1)):d("",!0),e("ul",bo,[(t(!0),s(S,null,L(k.value,_=>(t(),s("li",{key:_.scope+_.name,class:"item"},[e("div",yo,[e("div",ko,[e("strong",null,a(_.name),1),e("span",{class:ae(["tag",{"tag--builtin":_.scope==="built-in"}])},a(_.scope),3)]),_.error?(t(),s("p",$o,a(_.error),1)):(t(),s(S,{key:1},[_.description?(t(),s("p",_o,a(_.description),1)):d("",!0),e("p",wo,[A(a(h(_))+" ",1),_.params?(t(),s("span",Co," — sigma "+a(_.params.sigma)+", flat "+a(_.params.m1)+", jagged "+a(_.params.m2),1)):d("",!0)])],64))]),e("div",So,[_.scope!=="built-in"&&!_.error?(t(),s("button",{key:0,class:"btn btn--small",onClick:$=>I(_)}," Edit ",8,Vo)):d("",!0),_.error?d("",!0):(t(),s("button",{key:1,class:"btn btn--small",onClick:$=>D(_)},a(_.scope==="built-in"?"Copy to my presets":"Duplicate"),9,xo)),_.scope!=="built-in"?(t(),s("button",{key:2,class:"btn btn--small btn--danger",onClick:$=>O(_)}," Delete ",8,Eo)):d("",!0)])]))),128))])]))]))}}),Ao=oe(zo,[["__scopeId","data-v-519b182c"]]),No={class:"page"},Oo={class:"page__head"},Bo={class:"muted"},jo=["title"],To={key:0,class:"notice notice--error"},Ue="devtoolz-ui.image-batch-tab",Uo=ne({__name:"ImageBatchPage",props:{module:{},status:{}},setup(n){const k=n;function i(){try{const z=localStorage.getItem(Ue);if(z==="convert"||z==="configs"||z==="sharpen"||z==="backups")return z}catch{return"convert"}return"convert"}const g=v(i()),f=v(),N=v("");function b(z){g.value=z;try{localStorage.setItem(Ue,z)}catch{g.value=z}}return ze(ke,b),ze(xe,U(()=>It(k.status?.cwd??"",k.status?.home??"")).value),pe(async()=>{try{f.value=await Q.get("/api/image-batch/options")}catch(z){N.value=z instanceof Error?z.message:String(z)}}),(z,j)=>(t(),s("div",No,[e("header",Oo,[e("h1",null,a(n.module.title),1),e("p",Bo,a(n.module.description),1),n.status?.cwd?(t(),s("p",{key:0,class:"context",title:`Everything marked “This project” lives in ${n.status.cwd}`},[q(Y,{name:"folder",size:15}),j[0]||(j[0]=e("span",{class:"muted"},"Project folder",-1)),e("code",null,a(n.status.cwd),1)],8,jo)):d("",!0)]),q(ge,{"model-value":g.value,label:"Image Batch sections",options:[{value:"convert",label:"Convert"},{value:"configs",label:"Configs"},{value:"sharpen",label:"Sharpening"},{value:"backups",label:"Backups"}],"onUpdate:modelValue":b},null,8,["model-value"]),N.value?(t(),s("p",To,a(N.value),1)):f.value?(t(),s(S,{key:1},[g.value==="convert"?(t(),le(En,{key:0,cwd:k.status?.cwd??"",options:f.value},null,8,["cwd","options"])):g.value==="configs"?(t(),le(aa,{key:1,options:f.value},null,8,["options"])):g.value==="sharpen"?(t(),le(Ao,{key:2,options:f.value,cwd:k.status?.cwd??""},null,8,["options","cwd"])):(t(),le(Ut,{key:3,cwd:k.status?.cwd??""},null,8,["cwd"]))],64)):d("",!0)]))}}),Ro=oe(Uo,[["__scopeId","data-v-85ee2fe2"]]);export{Ro as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.view[data-v-aa574981]{display:flex;flex-direction:column;gap:16px}.block[data-v-aa574981]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.small[data-v-aa574981]{font-size:12px}.list[data-v-aa574981]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.item[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:12px;border:1px solid var(--border);border-radius:9px}.item__main[data-v-aa574981]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:260px}.item__path[data-v-aa574981]{color:var(--muted);font-size:11px;word-break:break-all}.item__actions[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.custom[data-v-aa574981]{display:flex;flex-direction:column;gap:8px;padding-top:12px;border-top:1px solid var(--border)}.custom h3[data-v-aa574981]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase}.pathrow[data-v-aa574981]{display:flex;flex-wrap:wrap;gap:8px}.pathrow .input[data-v-aa574981]{flex:1;min-width:220px;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.actions[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.chips[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.chip[data-v-aa574981]{padding:2px 10px;border-radius:999px;background:var(--surface-2);font-size:12px;white-space:nowrap}.chip--good[data-v-aa574981]{background:color-mix(in srgb,var(--ok) 18%,transparent);color:var(--ok)}.chip--warn[data-v-aa574981]{background:var(--warn-soft);color:var(--warn)}.chip--bad[data-v-aa574981]{background:var(--danger-soft);color:var(--danger)}.rows[data-v-aa574981]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.row[data-v-aa574981]{display:flex;align-items:center;gap:12px;padding:8px;border:1px solid var(--border);border-radius:9px}.row__thumb[data-v-aa574981]{flex:none;width:64px;height:64px;border-radius:6px;background:var(--surface-2);object-fit:cover}.row__text[data-v-aa574981]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.row__name[data-v-aa574981]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row__message[data-v-aa574981]{color:var(--danger)}.sharpen[data-v-1d132e3d]{display:flex;flex-direction:column;gap:12px}.grid[data-v-1d132e3d]{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}.hint[data-v-1d132e3d]{align-self:end;font-size:12px}.link[data-v-1d132e3d]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-1d132e3d]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.recipe[data-v-6d67983e]{display:flex;flex-direction:column;gap:16px}.group[data-v-6d67983e]{display:flex;flex-direction:column;gap:10px}.group h4[data-v-6d67983e]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase;margin:0}.grid[data-v-6d67983e]{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:14px}.small[data-v-6d67983e]{font-size:12px}.input--bad[data-v-6d67983e]{border-color:var(--danger)}.pills[data-v-6d67983e]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.pill[data-v-6d67983e]{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border:1px solid var(--border);border-radius:999px;background:var(--surface);font-size:12px;cursor:pointer}.pill input[data-v-6d67983e]{display:none}.pill--on[data-v-6d67983e]{border-color:var(--accent);background:var(--accent-soft);color:var(--accent);font-weight:600}.pill--button[data-v-6d67983e]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace}.pill--button[data-v-6d67983e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.link[data-v-6d67983e]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-6d67983e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.block[data-v-5992429e]{display:flex;flex-direction:column;gap:16px;padding:18px}.head[data-v-5992429e]{display:flex;align-items:center;justify-content:space-between;gap:12px}.grid[data-v-5992429e]{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}.small[data-v-5992429e]{font-size:12px}.recipes[data-v-5992429e]{display:flex;flex-direction:column;gap:8px}.panel[data-v-5992429e]{border:1px solid var(--border);border-radius:9px}.panel--open[data-v-5992429e]{border-color:var(--accent)}.panel__head[data-v-5992429e]{display:flex;align-items:center;gap:8px;padding:4px 8px 4px 12px}.panel__title[data-v-5992429e]{display:flex;flex-direction:column;gap:0;flex:1;min-width:0;padding:8px 0;border:0;background:transparent;text-align:left;cursor:pointer}.panel__title[data-v-5992429e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.panel__title .small[data-v-5992429e]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.panel__actions[data-v-5992429e]{display:flex;flex-wrap:wrap;align-items:center;gap:2px;flex:none}.panel__body[data-v-5992429e]{padding:12px 16px 16px;border-top:1px solid var(--border)}.panel summary[data-v-5992429e]{padding:12px;cursor:pointer;font-weight:600}details.panel>.panel__body[data-v-5992429e]{border-top:1px solid var(--border)}.json[data-v-5992429e]{min-height:420px;padding:12px;border:1px solid var(--border);border-radius:9px;background:var(--surface-2);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;resize:vertical;tab-size:2}.json[data-v-5992429e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.check-panel[data-v-5992429e]{padding:10px 14px;border-radius:9px}.check-panel--ok[data-v-5992429e]{background:color-mix(in srgb,var(--ok) 14%,transparent)}.check-panel--bad[data-v-5992429e]{background:var(--danger-soft);color:var(--danger)}.lines[data-v-5992429e]{margin:8px 0 0;font-size:12px;white-space:pre-wrap}.actions[data-v-5992429e]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.view[data-v-5b011a56]{display:flex;flex-direction:column;gap:16px}.block[data-v-5b011a56]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-5b011a56]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.list[data-v-5b011a56]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.item[data-v-5b011a56]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:12px;border:1px solid var(--border);border-radius:9px}.item__main[data-v-5b011a56]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:260px}.item__title[data-v-5b011a56]{display:flex;align-items:center;gap:8px}.item__path[data-v-5b011a56]{color:var(--muted);font-size:11px;word-break:break-all}.item__error[data-v-5b011a56]{color:var(--danger);font-size:12px}.item__actions[data-v-5b011a56]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.tag[data-v-5b011a56]{padding:1px 8px;border-radius:999px;background:var(--surface-2);color:var(--muted);font-size:11px}.block[data-v-b00b9955]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-b00b9955]{display:flex;align-items:center;justify-content:space-between;gap:12px}.small[data-v-b00b9955]{font-size:12px}.chips[data-v-b00b9955]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.chip[data-v-b00b9955]{padding:2px 10px;border-radius:999px;background:var(--surface-2);font-size:12px;white-space:nowrap}.chip--good[data-v-b00b9955]{background:color-mix(in srgb,var(--ok) 18%,transparent);color:var(--ok)}.chip--bad[data-v-b00b9955]{background:var(--danger-soft);color:var(--danger)}.errors[data-v-b00b9955]{margin:0;padding:10px 14px 10px 28px;border-radius:10px;background:var(--danger-soft);color:var(--danger)}.rows[data-v-b00b9955]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.row[data-v-b00b9955]{display:flex;align-items:center;gap:12px;padding:8px;border:1px solid var(--border);border-radius:9px}.row__thumb[data-v-b00b9955]{flex:none;width:64px;height:64px;border-radius:6px;background:var(--surface-2);object-fit:cover}.row__thumb--empty[data-v-b00b9955]{display:grid;place-items:center;font-size:11px}.row__text[data-v-b00b9955]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.row__name[data-v-b00b9955]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row__message[data-v-b00b9955]{color:var(--danger)}.row__sizes[data-v-b00b9955]{display:flex;align-items:baseline;gap:6px;flex:none;font-size:12px}.row__delta[data-v-b00b9955]{color:var(--muted)}.row__delta--down[data-v-b00b9955]{color:var(--ok)}@media(max-width:760px){.row[data-v-b00b9955]{flex-wrap:wrap}.row__text[data-v-b00b9955]{flex-basis:60%}}.link[data-v-b00b9955]{padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer;text-decoration:underline}.more[data-v-b00b9955]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;justify-content:center}.view[data-v-ecb5fab6]{display:flex;flex-direction:column;gap:16px}.block[data-v-ecb5fab6]{display:flex;flex-direction:column;gap:14px;padding:18px}.head[data-v-ecb5fab6]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px}.group[data-v-ecb5fab6]{display:flex;flex-direction:column;gap:10px}.group h3[data-v-ecb5fab6]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase}.grid[data-v-ecb5fab6]{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}.narrow[data-v-ecb5fab6]{max-width:320px}.small[data-v-ecb5fab6]{font-size:12px}.pathrow[data-v-ecb5fab6]{display:flex;gap:8px}.pathrow .input[data-v-ecb5fab6]{flex:1;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.pills[data-v-ecb5fab6]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.pill[data-v-ecb5fab6]{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border:1px solid var(--border);border-radius:999px;background:var(--surface);font-size:12px;cursor:pointer}.pill input[data-v-ecb5fab6]{display:none}.pill--on[data-v-ecb5fab6]{border-color:var(--accent);background:var(--accent-soft);color:var(--accent);font-weight:600}.pill--button[data-v-ecb5fab6]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace}.pill--button[data-v-ecb5fab6]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.runbar[data-v-ecb5fab6]{display:flex;flex-wrap:wrap;align-items:center;gap:14px}.link[data-v-ecb5fab6]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-ecb5fab6]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.progress[data-v-ecb5fab6]{height:8px;overflow:hidden;border-radius:999px;background:var(--surface-2)}.progress__bar[data-v-ecb5fab6]{height:100%;background:var(--accent);transition:width .15s}.compare[data-v-0ee1b3e3]{display:flex;flex-direction:column;gap:8px}.compare__scroll[data-v-0ee1b3e3]{overflow:auto;border-radius:9px;background:var(--surface-2);max-height:70vh}.compare__stage[data-v-0ee1b3e3]{position:relative;width:fit-content;margin:0 auto;line-height:0}.compare__img[data-v-0ee1b3e3]{display:block;max-width:none}.compare__img--top[data-v-0ee1b3e3]{position:absolute;inset:0}.compare__line[data-v-0ee1b3e3]{position:absolute;top:0;bottom:0;width:2px;background:var(--accent);pointer-events:none}.compare__tag[data-v-0ee1b3e3]{position:absolute;top:8px;padding:2px 8px;border-radius:6px;background:#0009;color:#fff;font-size:11px;line-height:1.4}.compare__tag--left[data-v-0ee1b3e3]{left:8px}.compare__tag--right[data-v-0ee1b3e3]{right:8px}.compare__range[data-v-0ee1b3e3]{width:100%}.block[data-v-8e3f1eea]{display:flex;flex-direction:column;gap:16px;padding:18px}.head[data-v-8e3f1eea]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px}.grid[data-v-8e3f1eea]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px}.wide[data-v-8e3f1eea]{grid-column:1/-1}.small[data-v-8e3f1eea]{font-size:12px}.preview[data-v-8e3f1eea]{display:flex;flex-direction:column;gap:12px}.previewbar[data-v-8e3f1eea]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.inline[data-v-8e3f1eea]{flex-direction:row;align-items:center}.narrow[data-v-8e3f1eea]{width:90px}.actions[data-v-8e3f1eea]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.view[data-v-519b182c]{display:flex;flex-direction:column;gap:16px}.block[data-v-519b182c]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-519b182c]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.list[data-v-519b182c]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.item[data-v-519b182c]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:12px;border:1px solid var(--border);border-radius:9px}.item__main[data-v-519b182c]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:260px}.item__title[data-v-519b182c]{display:flex;align-items:center;gap:8px}.item__facts[data-v-519b182c]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.item__error[data-v-519b182c]{color:var(--danger);font-size:12px}.item__actions[data-v-519b182c]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.tag[data-v-519b182c]{padding:1px 8px;border-radius:999px;background:var(--surface-2);color:var(--muted);font-size:11px}.tag--builtin[data-v-519b182c]{background:var(--accent-soft);color:var(--accent)}.page[data-v-85ee2fe2]{display:flex;flex-direction:column;gap:16px;padding:28px 28px 60px}@media(max-width:760px){.page[data-v-85ee2fe2]{padding:18px 14px 40px}}.page__head p[data-v-85ee2fe2]{margin-top:4px}.context[data-v-85ee2fe2]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px;font-size:12px}.context code[data-v-85ee2fe2]{padding:2px 8px;border-radius:6px;background:var(--surface-2);word-break:break-all}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as ke,I as Xe,x as Ce,w as Ve,e as Ge,J as Me,r as R,A as G,o as x,c as M,b as $e,f,y as me,k as pe,G as rt,F as oe,a as de,g as J,t as I,p as O,i as le,h as fe,q as it,E as He,s as Le,n as Re,j as ye,z as Oe,K as Ye,B as yt,L as gt}from"./index-pDKL0Y31.js";import{S as bt}from"./SourcePicker-CVgtCk78.js";import{u as ut}from"./useCopy-vCfkPGWW.js";import{U as wt}from"./FolderBrowser-BX3-y8sM.js";function _t(e,t,a,s){if(e==="auto")return Math.max(1,Math.floor((t+s)/(a+s)));if(typeof e=="number")return Math.max(1,Math.floor(e));const o=Object.keys(e).filter(c=>c!=="default").map(Number).sort((c,m)=>c-m);for(const c of o)if(t<=c)return Math.max(1,Math.floor(e[c]));return Math.max(1,Math.floor(e.default))}function kt(e,t,a){return Math.max(0,(e-(t-1)*a)/t)}function xt(e,t){return t!==void 0?Math.max(1,Math.floor(t)):e===void 0||e==="auto"?2:typeof e=="number"?Math.max(1,Math.floor(e)):Math.max(1,Math.floor(e.default))}function Mt(e,t,a,s="balanced"){const o=Math.max(1,Math.floor(t)||1),c=new Array(o).fill(0),m=[];let r=0;for(const $ of e){const y=Math.min(Math.max(1,Math.floor($.span)||1),o);let v;if(s==="ordered")v=r+y<=o?r:0,r=v+y,r>=o&&(r=0);else{let b=0,_=1/0;for(let i=0;i<=o-y;i++){let p=0;for(let A=i;A<i+y;A++)p=Math.max(p,c[A]);p<_&&(_=p,b=i)}v=b}let d=0;for(let b=v;b<v+y;b++)d=Math.max(d,c[b]);m.push({id:$.id,laneIndex:v,span:y,mainPos:d});const S=d+$.mainSize+a;for(let b=v;b<v+y;b++)c[b]=S}const w=m.length?Math.max(0,Math.max(...c)-a):0;return{items:m,totalMainSize:w}}function St(e){const t=new Set;let a=!1;function s(){a||(a=!0,requestAnimationFrame(()=>{a=!1,e()}))}const o=typeof ResizeObserver>"u"?null:new ResizeObserver(s);return{observe(c){t.has(c)||(t.add(c),o?.observe(c))},unobserveAll(){for(const c of t)o?.unobserve(c);t.clear()},scheduleNow:s,destroy(){o?.disconnect(),t.clear()}}}var Ct=240,Je=16,Ze=600,$t=250,It="cubic-bezier(0.2, 0, 0, 1)";function Te(e){return typeof e.el=="function"?e.el():e.el??null}function zt(e){return(e instanceof HTMLImageElement?[e]:Array.from(e.querySelectorAll("img"))).filter(a=>!a.complete)}function At(e,t={}){const a=t.direction??"vertical",s=t.minLaneSize??Ct,o=t.placement??"balanced",c=typeof t.gap=="number"?t.gap:t.gap?.main??Je,m=typeof t.gap=="number"?t.gap:t.gap?.cross??Je,r=a==="horizontal"?t.rows??"auto":t.columns??"auto",w=!!t.virtualize,$=typeof t.virtualize=="object"?t.virtualize.overscan??Ze:Ze,y=t.scrollContainer??(a==="vertical"?"window":"self"),v=t.estimateSize,d=t.animate??!0,S=t.transitionDuration??$t,b=t.transitionEasing??It,_=`transform ${S}ms ${b}, opacity ${S}ms ${b}`;e.style.position="relative",d&&(e.style.setProperty("--mk-transition-duration",`${S}ms`),e.style.setProperty("--mk-transition-easing",b));let i=null;a==="horizontal"?(e.style.overflowX="auto",e.style.overflowY="hidden",i=document.createElement("div"),i.setAttribute("aria-hidden","true"),i.style.position="absolute",i.style.top="0",i.style.left="0",i.style.width="1px",i.style.height="1px",i.style.visibility="hidden",i.style.pointerEvents="none",e.appendChild(i)):e.style.overflowX="clip";const p=new Map;let A=[],L=[],N=[];const T=new Map,B=new WeakSet;let re=!1,Z=null;const ne=new Map;function ie(l,h){for(const g of ne.get(l)??[])g(h)}const V=St(n);function F(){V.scheduleNow()}const Q=w?y==="window"?window:y==="self"?e:y:null;Q?.addEventListener("scroll",F,{passive:!0});function ee(){return A.map((l,h)=>({id:l,key:p.get(l)?.order??h})).sort((l,h)=>l.key-h.key).map(l=>l.id)}function W(){V.unobserveAll(),V.observe(e);for(const l of A){const h=Te(p.get(l));h&&V.observe(h)}}function K(l){if(!d)return;const h=p.get(l),g=h?Te(h):null;g&&(g.classList.add("mk-item-leave"),g.style.transition=_,g.style.opacity="0")}function q(l){const h=g=>{g.target===l&&(l.style.willChange="auto",l.classList.remove("mk-item-moving"),l.removeEventListener("transitionend",h))};l.style.willChange="transform",l.addEventListener("transitionend",h)}function D(l,h,g){const P=`translate(${h}px, ${g}px)`;return l.style.transform===""?d?(l.style.transition="none",l.style.transform=P,l.style.opacity="0",l.classList.add("mk-item-enter"),!0):(l.style.transform=P,!1):(l.style.transform===P||(d&&(l.style.transition=_,l.classList.add("mk-item-moving"),q(l)),l.style.transform=P),!1)}function z(){if(y==="self"){const C=a==="vertical"?e.scrollTop:e.scrollLeft,j=a==="vertical"?e.clientHeight:e.clientWidth;return[C-$,C+j+$]}const l=e.getBoundingClientRect(),h=a==="vertical"?l.top:l.left;let g,P;if(y==="window")g=0,P=a==="vertical"?window.innerHeight:window.innerWidth;else{const C=y.getBoundingClientRect();g=a==="vertical"?C.top:C.left,P=a==="vertical"?y.clientHeight:y.clientWidth}return[g-h-$,g+P-h+$]}function u(l,h){if(w&&l.estimatedSize!==void 0)return l.estimatedSize;if(l.aspectRatio)return a==="vertical"?h/l.aspectRatio:h*l.aspectRatio;if(!w)return;if(v)return v(l);re||(re=!0,console.warn("[masonry-kit] `virtualize` is on but an item has no `estimatedSize`, no `aspectRatio`, and `estimateSize` returned nothing — falling back to a guessed size. Set one of these for accurate initial positions."));const g=[...T.values()];return g.length>0?g.reduce((P,C)=>P+C,0)/g.length:h}function n(){const l=e.getBoundingClientRect(),h=a==="vertical"?l.width:l.height,g=_t(r,h,s,m),P=kt(h,g,m),C=ee().filter(E=>E!==Z),j=new Map,U=new Map,te=new Map;for(const E of C){const ue=p.get(E),ve=a==="vertical"?ue.colSpan??1:ue.rowSpan??1,se=Math.min(Math.max(1,Math.floor(ve)||1),g);U.set(E,se);const H=se*P+(se-1)*m;te.set(E,H);const X=Te(ue);X&&(j.set(E,X),X.style.position="absolute",X.style.top="0",X.style.left="0",a==="vertical"?X.style.width=`${H}px`:X.style.height=`${H}px`)}const he=new Map,Ke=[];for(const E of C){const ue=p.get(E),ve=te.get(E),se=j.get(E);let H;if(se){const X=zt(se);if(X.length===0){const ae=a==="vertical"?se.getBoundingClientRect().height:se.getBoundingClientRect().width;ae>0&&(H=ae,T.set(E,ae))}else for(const ae of X)B.has(ae)||(B.add(ae),ae.addEventListener("load",n,{once:!0}),ae.addEventListener("error",n,{once:!0}))}H===void 0&&(H=T.get(E)),H===void 0&&(H=u(ue,ve)),H!==void 0&&(he.set(E,H),Ke.push({id:E,span:U.get(E),mainSize:H}))}const{items:mt,totalMainSize:qe}=Mt(Ke,g,c,o),Ie=w?z():null,ze=[],Ae=[],xe=[];for(const E of mt){const ue=te.get(E.id),ve=he.get(E.id),se=E.laneIndex*(P+m),H=a==="vertical"?se:E.mainPos,X=a==="vertical"?E.mainPos:se,ae=a==="vertical"?ue:ve,pt=a==="vertical"?ve:ue,Ee=j.get(E.id);Ee&&D(Ee,H,X)&&xe.push(Ee),ze.push({id:E.id,x:H,y:X,width:ae,height:pt}),(!Ie||E.mainPos+ve>=Ie[0]&&E.mainPos<=Ie[1])&&Ae.push(E.id)}if(a==="vertical"?e.style.height=`${qe}px`:i&&(i.style.transform=`translate(${qe}px, 0)`),xe.length>0){xe[0].offsetHeight;for(const E of xe)E.style.transition=_,E.style.opacity="1",q(E)}L=ze,N=Ae,ie("layout",{items:ze,visibleIds:Ae})}function k(l){const h=new Set(l.map(g=>g.id));for(const g of A)h.has(g)||(K(g),T.delete(g));p.clear(),A=l.map(g=>g.id);for(const g of l)p.set(g.id,g);W()}return V.observe(e),{setItems(l){k(l),n()},updateItem(l,h){const g=p.get(l);g&&(p.set(l,{...g,...h}),W(),n())},addItem(l,h){p.set(l.id,l),h===void 0||h>=A.length?A.push(l.id):A.splice(h,0,l.id),W(),n()},removeItem(l){K(l),p.delete(l),A=A.filter(h=>h!==l),T.delete(l),W(),n()},relayout:n,getLayout(){return[...L]},getVisibleIds(){return[...N]},setDragging(l){Z!==l&&(Z=l,n())},on(l,h){ne.has(l)||ne.set(l,new Set);const g=ne.get(l);return g.add(h),()=>g.delete(h)},destroy(){V.destroy(),Q?.removeEventListener("scroll",F),i?.remove(),p.clear(),A=[],L=[],N=[],T.clear(),Z=null,ne.clear()}}}function ct(e,t){if(e===t)return!0;if(typeof e!="object"||typeof t!="object"||e===null||t===null||typeof Node<"u"&&(e instanceof Node||t instanceof Node))return!1;const a=Object.keys(e),s=Object.keys(t);return a.length!==s.length?!1:a.every(o=>ct(e[o],t[o]))}function Et(e,t){if(e===t)return!0;const a=new Set([...Object.keys(e),...Object.keys(t)]);for(const s of a)if(!ct(e[s],t[s]))return!1;return!0}var ce={},Qe=new WeakMap,Lt=0;function Y(e){if(e.id!==void 0)return e.id;let t=Qe.get(e);return t===void 0&&(t=`mk-auto-${++Lt}`,Qe.set(e,t)),t}var Rt=0,et={position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",border:"0"},Ot=ke({name:"MasonryGrid",props:{items:{type:Array,required:!0},options:{type:Object,default:()=>({})},sortable:{type:Boolean,default:!1}},emits:["layout","reorder"],setup(e,{slots:t,emit:a}){const s=`mk-${++Rt}`,o=R(null),c=new Map,m=new Map;let r=null,w=null,$=null,y=null,v=!1;const d=Xe(e.options.virtualize?new Set:null),S=R(!1),b=Xe(new Map),_=new Map;let i=new Set;const p=G(()=>{const n=d.value===null?e.items:e.items.filter(h=>d.value.has(Y(h)));if(b.value.size===0)return n;const k=new Set(n.map(h=>Y(h))),l=[...b.value.values()].filter(h=>!k.has(Y(h)));return l.length===0?n:[...n,...l]});function A(n,k){if(n.size!==k.size)return!1;for(const l of n)if(!k.has(l))return!1;return!0}function L(){return e.options.animate??ce.animate??!0}function N(){return e.options.transitionDuration??ce.transitionDuration??250}function T(){const n=e.options.gap??ce.gap;return typeof n=="number"?{main:n,cross:n}:{main:n?.main??16,cross:n?.cross??16}}function B(){const k=(e.options.direction??ce.direction)==="horizontal"?e.options.rows??ce.rows:e.options.columns??ce.columns;return xt(k,e.options.ssrColumns??ce.ssrColumns)}function re(n){const k=new Set(n.map(h=>Y(h)));for(const h of n)_.set(Y(h),h);let l=null;for(const h of i){if(k.has(h)||b.value.has(h)||!c.get(h)||!L())continue;const g=_.get(h);g&&(l??(l=new Map(b.value)),l.set(h,g),setTimeout(()=>{const P=new Map(b.value);P.delete(h),b.value=P,_.delete(h)},N()))}l&&(b.value=l),i=k}function Z(){if(!r)return;const n=e.items.map(k=>{const l=Y(k);return{id:l,el:c.get(l),colSpan:k.colSpan,rowSpan:k.rowSpan,aspectRatio:k.aspectRatio,estimatedSize:k.estimatedSize,order:k.order}});r.setItems(n)}function ne(){v||(v=!0,queueMicrotask(()=>{v=!1,Z()}))}function ie(n){let k=m.get(n);return k||(k=l=>{l!==c.get(n)&&(l?c.set(n,l):(c.delete(n),m.delete(n)),ne())},m.set(n,k),k)}function V(){if(o.value){d.value=e.options.virtualize?new Set:null,i=new Set(e.items.map(n=>Y(n))),_.clear();for(const n of e.items)_.set(Y(n),n);r=At(o.value,{...ce,...e.options}),w=r.on("layout",n=>{if(S.value=!0,a("layout",n.items),e.options.virtualize){const k=new Set(n.visibleIds);(!d.value||!A(d.value,k))&&(d.value=k)}}),Z()}}const F=R(null),Q=R(""),ee=`${s}-instructions`,W=`${s}-live`;function K(n){Q.value=n}function q(n,k){return`item ${k.findIndex(h=>Y(h)===n)+1} of ${k.length}`}let D=null;function z(n,k,l){const h=n.findIndex(C=>Y(C)===k);if(h===-1)return n;const g=[...n],[P]=g.splice(h,1);return g.splice(Math.max(0,Math.min(l,g.length)),0,P),g}function u(n,k){if(!e.sortable||!r)return;const l=Y(k);if(n.key===" "||n.key==="Enter"){n.preventDefault(),F.value===l?(F.value=null,D=null,r.setDragging(null),K(`Dropped ${q(l,e.items)}.`)):F.value===null&&(F.value=l,D=e.items,r.setDragging(l),K(`Picked up ${q(l,e.items)}. Use arrow keys to move, space to drop, escape to cancel.`));return}if(F.value!==l)return;if(n.key==="Escape"){n.preventDefault(),F.value=null,r.setDragging(null),D&&a("reorder",D),D=null,K("Reordering cancelled.");return}const h=e.options.direction==="horizontal",g=h?"ArrowRight":"ArrowDown",P=h?"ArrowLeft":"ArrowUp";if(n.key!==g&&n.key!==P)return;n.preventDefault();const C=e.items.findIndex(he=>Y(he)===l),j=n.key===g?1:-1,U=C+j;if(U<0||U>=e.items.length)return;const te=z(e.items,l,U);a("reorder",te),K(`Moved to ${q(l,te)}.`)}return Ce(()=>{!o.value||typeof window>"u"||(V(),$=Ve(()=>e.items,n=>{re(n),Z()},{deep:!0}),y=Ve(()=>e.options,(n,k)=>{Et(n,k)||(w?.(),r?.destroy(),V())},{deep:!0}))}),Ge(()=>{$?.(),y?.(),w?.(),r?.destroy()}),()=>Me("div",{ref:o,class:"mk-grid",style:S.value?{}:{columns:B(),columnGap:`${T().cross}px`}},[...p.value.map(n=>{const k=Y(n),l=b.value.has(k),h=e.sortable?{tabindex:0,role:"button","aria-roledescription":"Reorderable item","aria-describedby":ee,"aria-pressed":F.value===k?"true":"false",onKeydown:g=>u(g,n)}:{};return Me("div",{key:k,class:"mk-item",style:{...S.value?{}:{breakInside:"avoid",marginBottom:`${T().main}px`},...l?{pointerEvents:"none"}:{}},ref:ie(k),...h},t.item?.({item:n}))}),e.sortable?Me("span",{id:ee,style:et},"Press space or enter to pick up this item. While picked up, use the arrow keys to move it, space or enter to drop it, or escape to cancel."):null,e.sortable?Me("span",{id:W,role:"status","aria-live":"polite",style:et},Q.value):null])}});const Tt={key:1,class:"canvas canvas--bad",title:"Could not decode this hash"},Pt=ke({__name:"PlaceholderCanvas",props:{rgba:{}},setup(e){const t=e,a=R();function s(){const o=a.value;if(!o||!t.rgba)return;o.width=t.rgba.width,o.height=t.rgba.height;const c=o.getContext("2d");if(!c)return;const m=c.createImageData(t.rgba.width,t.rgba.height);m.data.set(t.rgba.data),c.putImageData(m,0,0)}return Ce(s),Ve(()=>t.rgba,s),(o,c)=>e.rgba?(x(),M("canvas",{key:0,ref_key:"canvas",ref:a,class:"canvas"},null,512)):(x(),M("div",Tt,"?"))}}),dt=$e(Pt,[["__scopeId","data-v-af1c304e"]]);var Nt=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","#","$","%","*","+",",","-",".",":",";","=","?","@","[","]","^","_","{","|","}","~"],ge=e=>{let t=0;for(let a=0;a<e.length;a++){let s=e[a],o=Nt.indexOf(s);t=t*83+o}return t},Pe=e=>{let t=e/255;return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},Ne=e=>{let t=Math.max(0,Math.min(1,e));return t<=.0031308?Math.trunc(t*12.92*255+.5):Math.trunc((1.055*Math.pow(t,.4166666666666667)-.055)*255+.5)},jt=e=>e<0?-1:1,je=(e,t)=>jt(e)*Math.pow(Math.abs(e),t),tt=class extends Error{constructor(e){super(e),this.name="ValidationError",this.message=e}},Dt=e=>{if(!e||e.length<6)throw new tt("The blurhash string must be at least 6 characters");let t=ge(e[0]),a=Math.floor(t/9)+1,s=t%9+1;if(e.length!==4+2*s*a)throw new tt(`blurhash length mismatch: length is ${e.length} but it should be ${4+2*s*a}`)},Ut=e=>{let t=e>>16,a=e>>8&255,s=e&255;return[Pe(t),Pe(a),Pe(s)]},Bt=(e,t)=>{let a=Math.floor(e/361),s=Math.floor(e/19)%19,o=e%19;return[je((a-9)/9,2)*t,je((s-9)/9,2)*t,je((o-9)/9,2)*t]},Ft=(e,t,a,s)=>{Dt(e),s=s|1;let o=ge(e[0]),c=Math.floor(o/9)+1,m=o%9+1,r=(ge(e[1])+1)/166,w=new Array(m*c);for(let v=0;v<w.length;v++)if(v===0){let d=ge(e.substring(2,6));w[v]=Ut(d)}else{let d=ge(e.substring(4+v*2,6+v*2));w[v]=Bt(d,r*s)}let $=t*4,y=new Uint8ClampedArray($*a);for(let v=0;v<a;v++)for(let d=0;d<t;d++){let S=0,b=0,_=0;for(let L=0;L<c;L++)for(let N=0;N<m;N++){let T=Math.cos(Math.PI*d*N/t)*Math.cos(Math.PI*v*L/a),B=w[N+L*m];S+=B[0]*T,b+=B[1]*T,_+=B[2]*T}let i=Ne(S),p=Ne(b),A=Ne(_);y[4*d+0+v*$]=i,y[4*d+1+v*$]=p,y[4*d+2+v*$]=A,y[4*d+3+v*$]=255}return y},Vt=Ft;const nt=new Map;function st(e,t){const a=e*4096+t;let s=nt.get(a);if(!s){s=new Float64Array(e*t);for(let o=0;o<e;o++)for(let c=0;c<t;c++)s[o*t+c]=Math.cos(Math.PI*o*(c+.5)/t);nt.set(a,s)}return s}function Ht(e,t,a,s,o,c,m){const r=st(a,o),w=st(s,c),$=new Float64Array(a);for(let y=0;y<c;y++){for(let v=0;v<a;v++){let d=0;for(let S=0;S<s;S++){const b=e[S*t+v];b!==0&&(d+=b*w[S*c+y])}$[v]=d}for(let v=0;v<o;v++){let d=0;for(let S=0;S<a;S++)d+=$[S]*r[S*o+v];m[y*o+v]=d}}}var we=class extends Error{constructor(e,t){super(t?`${e}: ${t}`:e),this.name="PlaceholderError",this.code=e}};const Gt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",ft=new Int8Array(128).fill(-1);for(let e=0;e<64;e++)ft[Gt.charCodeAt(e)]=e;function Wt(e){const t=e.length;if(t%4===1)throw new we("InvalidLength");const a=new Uint8Array(Math.floor(t*6/8));let s=0,o=0,c=0;for(let m=0;m<t;m++){const r=e.charCodeAt(m),w=r<128?ft[r]:-1;if(w<0)throw new we("InvalidCharacter");s=s<<6|w,o+=6,o>=8&&(o-=8,a[c++]=s>>o&255,s&=(1<<o)-1)}return a}function Kt(e){return typeof e=="string"?Wt(e):e}var ht=class{constructor(e,t=0){this.bytes=e,this.pos=t*8,this.end=e.length*8}bit(){if(this.pos>=this.end)return 0;const e=this.pos++;return this.bytes[e>>3]>>7-(e&7)&1}bits(e){let t=0;for(let a=0;a<e;a++)t=t<<1|this.bit();return t>>>0}};function qt(e,t){let a=0;for(;e.bit()===1;)a++;const s=a*(1<<t)+(t>0?e.bits(t):0);return s&1?-((s+1)/2):s/2}function Xt(e){return e?9:7}function Yt(e){return Math.pow(2,(e-32)/8)}function Jt(e,t){return e>=1?[t,Math.max(1,Math.round(t/e))]:[Math.max(1,Math.round(t*e)),t]}function Zt(e){if(e.length<7||e.length>1024)throw new we("InvalidLength");const t=new ht(e);if(t.bits(2)!==0)throw new we("UnsupportedVersion");const a=t.bit()===1;if(a&&e.length<9)throw new we("InvalidLength");const s={aspectCode:t.bits(6),alpha:a,Lx:t.bits(3)+1,Ly:t.bits(3)+1,Cx:t.bits(2)+1,Cy:t.bits(2)+1,Ax:1,Ay:1,dc:[0,0,0,0],scale:[0,0,0,0],k:[0,0,0,0]};for(let o=0;o<3;o++)s.dc[o]=t.bits(6);for(let o=0;o<3;o++)s.scale[o]=t.bits(4);for(let o=0;o<3;o++)s.k[o]=t.bits(2);return t.bit(),a&&(s.dc[3]=t.bits(5),s.Ax=t.bits(2)+1,s.Ay=t.bits(2)+1,s.scale[3]=t.bits(4),s.k[3]=t.bits(2)),s}const _e={qmaxL:7,qmaxC:3,smaxL:.64,smaxC:.32,reconOffset:0};function Qt(e){return e===0?_e.qmaxL:_e.qmaxC}function en(e,t,a,s){return 2*(e*s+t*a)<3*a*s}function We(e,t){return t===0?[e.Lx,e.Ly]:t===3?[e.Ax,e.Ay]:[e.Cx,e.Cy]}function tn(e){const t=[],a=e.alpha?[0,1,2,3]:[0,1,2];for(const s of a){const[o,c]=We(e,s);for(let m=0;m<c;m++)for(let r=0;r<o;r++)r===0&&m===0||!en(r,m,o,c)||t.push({ch:s,i:r,j:m,nx:o,ny:c,qmax:Qt(s)})}return t.sort((s,o)=>{const c=s.i*s.i*s.ny*s.ny+s.j*s.j*s.nx*s.nx,m=s.nx*s.nx*s.ny*s.ny,r=o.i*o.i*o.ny*o.ny+o.j*o.j*o.nx*o.nx,w=c*(o.nx*o.nx*o.ny*o.ny)-r*m;return w!==0?w:s.ch!==o.ch?s.ch-o.ch:s.j!==o.j?s.j-o.j:s.i-o.i}),t}function Se(e,t,a){return e<t?t:e>a?a:e}function nn(e,t){return e===0?t/63:e===3?t/31:t*.64/63-.32}const sn=Array.from({length:16},(e,t)=>Math.pow(2,-(15-t)/3));function an(e,t){return(e===1||e===2?_e.smaxC:_e.smaxL)*sn[t]}function on(e,t,a){if(e===0)return 0;const s=(Math.abs(e)-_e.reconOffset)/a,o=t*s*s;return e<0?-o:o}function ln(e){return e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055}function De(e,t,a,s){const o=e+.3963377774*t+.2158037573*a,c=e-.1055613458*t-.0638541728*a,m=e-.0894841775*t-1.291485548*a,r=o*o*o,w=c*c*c,$=m*m*m;s[0]=4.0767416621*r-3.3077115913*w+.2309699292*$,s[1]=-1.2684380046*r+2.6097574011*w-.3413193965*$,s[2]=-.0041960863*r-.7034186147*w+1.707614701*$}const Ue=-5e-4,Be=1.0005,at=[0,0,0];function ot(e){return e[0]>=Ue&&e[0]<=Be&&e[1]>=Ue&&e[1]<=Be&&e[2]>=Ue&&e[2]<=Be}function rn(e,t,a,s){if(De(e,t,a,s),!ot(s)){let o=0,c=1;for(let m=0;m<8;m++){const r=(o+c)/2;De(e,t*r,a*r,at),ot(at)?o=r:c=r}De(e,t*o,a*o,s)}for(let o=0;o<3;o++)s[o]=s[o]<0?0:s[o]>1?1:s[o]}function un(e,t){const a=t,s=t.alpha?[0,1,2,3]:[0,1,2],o=[];for(const r of s){const[w,$]=We(a,r),y=new Float64Array(w*$);y[0]=nn(r,t.dc[r]),o[r]=y}const c=s.map(r=>an(r,t.scale[r])),m=new ht(e,Xt(t.alpha));for(const r of tn(a)){let w=qt(m,t.k[r.ch]);w=w>r.qmax?r.qmax:w<-r.qmax?-r.qmax:w,o[r.ch][r.j*r.nx+r.i]=on(w,c[r.ch],r.qmax)}return o}function cn(e,t={}){const a=Kt(e),s=Zt(a),o=Math.round(Se(t.size??32,4,128)),c=t.dither??!0,[m,r]=Jt(Yt(s.aspectCode),o),w=un(a,s),$=s,y=m*r,v=[];for(let b=0;b<w.length;b++){const[_,i]=We($,b),p=new Float64Array(y);Ht(w[b],_,_,i,m,r,p),v.push(p)}const d=new Uint8ClampedArray(y*4),S=[0,0,0];for(let b=0;b<r;b++)for(let _=0;_<m;_++){const i=b*m+_;rn(Se(v[0][i],0,1),v[1][i],v[2][i],S);const p=c?lt(52.9829189*lt(.06711056*_+.00583715*b)):.5,A=i*4;for(let L=0;L<3;L++){const N=ln(S[L])*255;d[A+L]=Se(Math.floor(N+p),0,255)}d[A+3]=s.alpha?Math.round(Se(v[3][i],0,1)*255):255}return{width:m,height:r,data:d}}function lt(e){return e-Math.floor(e)}function dn(e){let{PI:t,min:a,max:s,cos:o,round:c}=Math,m=e[0]|e[1]<<8|e[2]<<16,r=e[3]|e[4]<<8,w=(m&63)/63,$=(m>>6&63)/31.5-1,y=(m>>12&63)/31.5-1,v=(m>>18&31)/31,d=m>>23,S=(r>>3&63)/63,b=(r>>9&63)/63,_=r>>15,i=s(3,_?d?5:7:r&7),p=s(3,_?r&7:d?5:7),A=d?(e[5]&15)/15:1,L=(e[5]>>4)/15,N=d?6:5,T=0,B=(q,D,z)=>{let u=[];for(let n=0;n<D;n++)for(let k=n?0:1;k*D<q*(D-n);k++)u.push(((e[N+(T>>1)]>>((T++&1)<<2)&15)/7.5-1)*z);return u},re=B(i,p,v),Z=B(3,3,S*1.25),ne=B(3,3,b*1.25),ie=d&&B(5,5,L),V=fn(e),F=c(V>1?32:32*V),Q=c(V>1?32/V:32),ee=new Uint8Array(F*Q*4),W=[],K=[];for(let q=0,D=0;q<Q;q++)for(let z=0;z<F;z++,D+=4){let u=w,n=$,k=y,l=A;for(let C=0,j=s(i,d?5:3);C<j;C++)W[C]=o(t/F*(z+.5)*C);for(let C=0,j=s(p,d?5:3);C<j;C++)K[C]=o(t/Q*(q+.5)*C);for(let C=0,j=0;C<p;C++)for(let U=C?0:1,te=K[C]*2;U*p<i*(p-C);U++,j++)u+=re[j]*W[U]*te;for(let C=0,j=0;C<3;C++)for(let U=C?0:1,te=K[C]*2;U<3-C;U++,j++){let he=W[U]*te;n+=Z[j]*he,k+=ne[j]*he}if(d)for(let C=0,j=0;C<5;C++)for(let U=C?0:1,te=K[C]*2;U<5-C;U++,j++)l+=ie[j]*W[U]*te;let h=u-2/3*n,g=(3*u-h+k)/2,P=g-k;ee[D]=s(0,255*a(1,g)),ee[D+1]=s(0,255*a(1,P)),ee[D+2]=s(0,255*a(1,h)),ee[D+3]=s(0,255*a(1,l))}return{w:F,h:Q,rgba:ee}}function fn(e){let t=e[3],a=e[2]&128,s=e[4]&128,o=s?a?5:7:t&7,c=s?t&7:a?5:7;return o/c}const be=32;function hn(e,t,a){const s=t>0&&a>0?t/a:1,o=s>=1?be:Math.max(1,Math.round(be*s)),c=s>=1?Math.max(1,Math.round(be/s)):be;try{return{width:o,height:c,data:Vt(e,o,c)}}catch{return null}}function vn(e){try{const t=atob(e),a=Uint8Array.from(t,o=>o.charCodeAt(0)),s=dn(a);return{width:s.w,height:s.h,data:new Uint8ClampedArray(s.rgba)}}catch{return null}}function mn(e){try{const t=cn(e,{size:be});return{width:t.width,height:t.height,data:new Uint8ClampedArray(t.data)}}catch{return null}}function vt(e,t,a,s){return e==="blurhash"?hn(t,a,s):e==="thumbhash"?vn(t):mn(t)}const pn={class:"item card"},yn=["aria-label"],gn=["alt","src"],bn={class:"strip__label"},wn=["src"],_n={class:"meta"},kn=["title"],xn={class:"muted"},Mn={class:"hashes"},Sn={class:"hashes__key"},Cn=["title"],$n=["aria-label","onClick"],In=ke({__name:"ResultCard",props:{entry:{}},emits:["open"],setup(e,{emit:t}){const a=e,s=t,o=["hazehash","blurhash","thumbhash"],{copied:c,copy:m}=ut(),r=G(()=>{const{width:y,height:v}=a.entry;return y>0&&v>0?Math.min(Math.max(y/v,.5),2):1}),w=G(()=>o.filter(y=>a.entry[y]!==void 0).map(y=>({type:y,rgba:vt(y,a.entry[y],a.entry.width,a.entry.height)}))),$=G(()=>{const y=[];for(const v of["hazehash","blurhash","thumbhash","color"]){const d=a.entry[v];d!==void 0&&y.push({key:v,value:d})}return y});return(y,v)=>(x(),M("article",pn,[f("button",{class:"item__open","aria-label":`Open ${e.entry.file}`,onClick:v[0]||(v[0]=d=>s("open"))},[f("span",{class:"shots",style:me({aspectRatio:String(r.value)})},[f("img",{class:"shot",loading:"lazy",alt:e.entry.file,src:pe(rt)(e.entry.path,480)},null,8,gn)],4),w.value.length>0?(x(),M("span",{key:0,class:"strip",style:me({aspectRatio:String(r.value*w.value.length)})},[(x(!0),M(oe,null,de(w.value,d=>(x(),M("span",{key:d.type,class:"strip__cell"},[J(dt,{rgba:d.rgba},null,8,["rgba"]),f("span",bn,I(d.type),1)]))),128))],4)):O("",!0),e.entry.preview?(x(),M("img",{key:1,class:"preview",alt:"Tiny preview",src:e.entry.preview},null,8,wn)):O("",!0)],8,yn),f("div",_n,[f("strong",{class:"meta__name",title:e.entry.path},I(e.entry.file),9,kn),f("span",xn,I(e.entry.width)+"×"+I(e.entry.height),1)]),f("ul",Mn,[(x(!0),M(oe,null,de($.value,d=>(x(),M("li",{key:d.key},[f("span",Sn,[d.key==="color"?(x(),M("span",{key:0,class:"swatch",style:me({background:d.value})},null,4)):O("",!0),le(" "+I(d.key),1)]),f("code",{class:"hashes__value",title:d.value},I(d.value),9,Cn),f("button",{class:"btn btn--ghost btn--small","aria-label":`Copy ${d.key}`,onClick:S=>pe(m)(d.key,d.value)},[J(fe,{name:pe(c)===d.key?"check":"copy",size:14},null,8,["name"])],8,$n)]))),128))])]))}}),zn=$e(In,[["__scopeId","data-v-ede0ed45"]]),An={class:"muted counter"},En=["disabled"],Ln=["disabled"],Rn={class:"scroll"},On={class:"stage"},Tn=["alt","src"],Pn={key:0,class:"compare"},Nn={key:0,class:"compare__item"},jn=["src"],Dn={class:"facts"},Un={class:"facts__row"},Bn={class:"facts__mono"},Fn={class:"facts__row"},Vn={class:"facts__mono facts__hash"},Hn=["aria-label","onClick"],Gn=ke({__name:"ResultModal",props:{entries:{},index:{}},emits:["close","update:index"],setup(e,{emit:t}){const a=e,s=t,o=["hazehash","blurhash","thumbhash"],{copied:c,copy:m}=ut(),r=G(()=>a.entries[a.index]),w=G(()=>a.index>0),$=G(()=>a.index<a.entries.length-1),y=G(()=>{const{width:_,height:i}=r.value;return _>0&&i>0?_/i:1}),v=G(()=>o.filter(_=>r.value[_]!==void 0).map(_=>({type:_,rgba:vt(_,r.value[_],r.value.width,r.value.height)}))),d=G(()=>{const _=[];for(const i of["hazehash","blurhash","thumbhash","color"]){const p=r.value[i];p!==void 0&&_.push({key:i,value:p})}return _});function S(_){const i=a.index+_;i>=0&&i<a.entries.length&&s("update:index",i)}function b(_){_.target instanceof HTMLInputElement||(_.key==="ArrowLeft"&&S(-1),_.key==="ArrowRight"&&S(1))}return Ce(()=>window.addEventListener("keydown",b)),Ge(()=>window.removeEventListener("keydown",b)),(_,i)=>(x(),it(wt,{title:r.value.file,width:"1040px",onClose:i[2]||(i[2]=p=>s("close"))},{actions:He(()=>[f("span",An,I(e.index+1)+" / "+I(e.entries.length),1),f("button",{class:"btn btn--small",disabled:!w.value,"aria-label":"Previous image",onClick:i[0]||(i[0]=p=>S(-1))},[J(fe,{name:"left",size:15})],8,En),f("button",{class:"btn btn--small",disabled:!$.value,"aria-label":"Next image",onClick:i[1]||(i[1]=p=>S(1))},[J(fe,{name:"right",size:15})],8,Ln)]),default:He(()=>[f("div",Rn,[f("div",On,[(x(),M("img",{key:r.value.path,class:"stage__img",alt:r.value.file,src:pe(rt)(r.value.path,1600)},null,8,Tn))]),v.value.length?(x(),M("div",Pn,[(x(!0),M(oe,null,de(v.value,p=>(x(),M("figure",{key:p.type,class:"compare__item"},[f("div",{class:"compare__frame",style:me({aspectRatio:String(y.value)})},[J(dt,{rgba:p.rgba},null,8,["rgba"])],4),f("figcaption",null,I(p.type),1)]))),128)),r.value.preview?(x(),M("figure",Nn,[f("div",{class:"compare__frame",style:me({aspectRatio:String(y.value)})},[f("img",{class:"compare__preview",alt:"Tiny preview",src:r.value.preview},null,8,jn)],4),i[3]||(i[3]=f("figcaption",null,"preview",-1))])):O("",!0)])):O("",!0),f("dl",Dn,[f("div",Un,[i[4]||(i[4]=f("dt",null,"File",-1)),f("dd",Bn,I(r.value.path),1)]),f("div",Fn,[i[5]||(i[5]=f("dt",null,"Size",-1)),f("dd",null,I(r.value.width)+" × "+I(r.value.height)+" px",1)]),(x(!0),M(oe,null,de(d.value,p=>(x(),M("div",{key:p.key,class:"facts__row"},[f("dt",null,[p.key==="color"?(x(),M("span",{key:0,class:"swatch",style:me({background:p.value})},null,4)):O("",!0),le(" "+I(p.key),1)]),f("dd",Vn,I(p.value),1),f("button",{class:"btn btn--ghost btn--small","aria-label":`Copy ${p.key}`,onClick:A=>pe(m)(p.key,p.value)},[J(fe,{name:pe(c)===p.key?"check":"copy",size:14},null,8,["name"])],8,Hn)]))),128))])])]),_:1},8,["title"]))}}),Wn=$e(Gn,[["__scopeId","data-v-4cbae639"]]),Kn={class:"page"},qn={class:"page__head"},Xn={class:"muted"},Yn={key:0,class:"notice notice--warn"},Jn={class:"card block"},Zn={class:"types"},Qn=["checked","onChange"],es={class:"type__title"},ts={class:"type__text muted"},ns={class:"grid"},ss={key:0,class:"field"},as=["min","max"],os={key:1,class:"field"},ls=["value"],rs={class:"field"},is=["value"],us={key:2,class:"field"},cs={class:"runbar"},ds=["disabled"],fs={key:0,class:"muted"},hs={key:1,class:"muted"},vs={key:1,class:"card block",role:"status"},ms={class:"progress"},ps={class:"muted"},ys={key:0},gs={key:2,class:"notice notice--error"},bs={key:3,class:"card block"},ws={class:"block__head"},_s={class:"muted"},ks={key:0},xs={key:1},Ms={key:0,class:"errors"},Ss={class:"tabs",role:"tablist"},Cs=["aria-selected"],$s=["aria-selected"],Is={key:0,class:"muted"},zs={key:1,class:"more"},As={class:"outbar"},Es=["disabled"],Ls={key:0,class:"muted"},Rs={class:"output"},Fe=48,Os=ke({__name:"ImageHashPage",props:{module:{},status:{}},setup(e){const t={columns:"auto",minLaneSize:250,gap:14},a=["auto","3x3","4x3","4x4","5x4","6x4","8x6"],s={json:"json",plain:"txt",csv:"csv",ts:"ts",js:"js"},o=R(),c=R([]),m=R(!0),r=R(["blurhash","thumbhash"]),w=R(28),$=R("auto"),y=R("json"),v=R("imageHashes"),d=R(null),S=R("idle"),b=R({done:0,total:0,cached:0}),_=R(""),i=R(),p=R("gallery"),A=R(Fe),L=R(""),N=R(""),T=R(!1);let B;const re=G(()=>_.value.toLowerCase().includes("sharp")),Z=G(()=>c.value.length>0&&r.value.length>0&&S.value!=="running"),ne=G(()=>b.value.total>0?Math.round(b.value.done/b.value.total*100):0),ie=G(()=>i.value?.entries.slice(0,A.value)??[]),V=G(()=>ie.value.map((z,u)=>({id:z.path,position:u})));function F(z){return ie.value[Number(z.position)]}function Q(z){r.value=r.value.includes(z)?r.value.filter(u=>u!==z):[...r.value,z]}function ee(z,u){const n=z.includes("\\")?"\\":"/";return`${z}${z.endsWith(n)?"":n}image-hashes.${s[u]??"txt"}`}async function W(z=!1){B?.(),S.value="running",_.value="",i.value=void 0,N.value="",b.value={done:0,total:0,cached:0},A.value=Fe,d.value=null;try{const{jobId:u}=await Le.post("/api/image-hash/run",{paths:c.value,recursive:m.value,types:r.value,components:$.value,budget:w.value,format:y.value,exportName:v.value,installSharp:z});B=yt(u,{onProgress:n=>{b.value=n},onDone:n=>{i.value=n,S.value="done",p.value="gallery",L.value=ee(n.base,n.format)},onFailed:n=>{_.value=n,S.value="failed"}})}catch(u){_.value=u instanceof Error?u.message:String(u),S.value="failed"}}async function K(){if(i.value?.output)try{await navigator.clipboard.writeText(i.value.output),T.value=!0,setTimeout(()=>T.value=!1,1200)}catch{T.value=!1}}function q(){const z=i.value?.output;if(!z)return;const u=new Blob([z],{type:"text/plain;charset=utf-8"}),n=document.createElement("a");n.href=URL.createObjectURL(u),n.download=`image-hashes.${s[i.value?.format??"json"]??"txt"}`,n.click(),URL.revokeObjectURL(n.href)}async function D(z=!1){if(i.value?.output){N.value="";try{const u=await Le.post("/api/image-hash/save",{path:L.value,content:i.value.output,overwrite:z});N.value=`Saved to ${u.path}`}catch(u){if(u instanceof gt&&u.status===409){window.confirm(`${u.message}. Replace it?`)&&await D(!0);return}N.value=u instanceof Error?u.message:String(u)}}}return Ce(async()=>{try{o.value=await Le.get("/api/image-hash/options"),w.value=o.value.budget.default,$.value=o.value.components.auto?"auto":o.value.components.default,v.value=o.value.exportName}catch(z){_.value=z instanceof Error?z.message:String(z),S.value="failed"}}),Ge(()=>{B?.()}),(z,u)=>(x(),M("div",Kn,[f("header",qn,[f("h1",null,I(e.module.title),1),f("p",Xn,I(e.module.description),1)]),o.value&&!o.value.sharp?(x(),M("div",Yn," The sharp image library is not installed yet. Previews are limited, and the first run will offer to install it. ")):O("",!0),J(bt,{sources:c.value,"onUpdate:sources":u[0]||(u[0]=n=>c.value=n),recursive:m.value,"onUpdate:recursive":u[1]||(u[1]=n=>m.value=n),"scan-url":"/api/image-hash/scan",start:e.status?.cwd??""},null,8,["sources","recursive","start"]),f("section",Jn,[u[19]||(u[19]=f("h2",null,"Placeholders",-1)),f("div",Zn,[(x(!0),M(oe,null,de(o.value?.types,n=>(x(),M("label",{key:n.id,class:Re(["type",{"type--on":r.value.includes(n.id)}])},[f("input",{type:"checkbox",checked:r.value.includes(n.id),onChange:k=>Q(n.id)},null,40,Qn),f("span",es,I(n.title),1),f("span",ts,I(n.description),1)],2))),128))]),f("div",ns,[r.value.includes("hazehash")?(x(),M("label",ss,[f("span",null,"Hazehash size: "+I(w.value)+" bytes",1),ye(f("input",{"onUpdate:modelValue":u[2]||(u[2]=n=>w.value=n),type:"range",min:o.value?.budget.min,max:o.value?.budget.max},null,8,as),[[Oe,w.value,void 0,{number:!0}]])])):O("",!0),r.value.includes("blurhash")?(x(),M("label",os,[u[16]||(u[16]=f("span",null,"Blurhash components",-1)),ye(f("select",{"onUpdate:modelValue":u[3]||(u[3]=n=>$.value=n),class:"select"},[(x(),M(oe,null,de(a,n=>f("option",{key:n,value:n},I(n==="auto"?"auto (by aspect ratio)":n),9,ls)),64))],512),[[Ye,$.value]])])):O("",!0),f("label",rs,[u[17]||(u[17]=f("span",null,"Output format",-1)),ye(f("select",{"onUpdate:modelValue":u[4]||(u[4]=n=>y.value=n),class:"select"},[(x(!0),M(oe,null,de(o.value?.formats,n=>(x(),M("option",{key:n,value:n},I(n),9,is))),128))],512),[[Ye,y.value]])]),y.value==="ts"||y.value==="js"?(x(),M("label",us,[u[18]||(u[18]=f("span",null,"Export name",-1)),ye(f("input",{"onUpdate:modelValue":u[5]||(u[5]=n=>v.value=n),class:"input",spellcheck:"false"},null,512),[[Oe,v.value]])])):O("",!0)])]),f("div",cs,[f("button",{class:"btn btn--primary",disabled:!Z.value,onClick:u[6]||(u[6]=n=>W(!1))},[J(fe,{name:"play",size:15}),le(" "+I(S.value==="running"?"Working…":"Compute hashes"),1)],8,ds),c.value.length===0?(x(),M("span",fs,"Add at least one folder or image.")):r.value.length===0?(x(),M("span",hs,"Pick at least one placeholder.")):O("",!0)]),S.value==="running"?(x(),M("div",vs,[f("div",ms,[f("div",{class:"progress__bar",style:me({width:`${ne.value}%`})},null,4)]),f("span",ps,[le(I(b.value.done)+" of "+I(b.value.total||"…")+" images",1),b.value.cached?(x(),M("span",ys," · "+I(b.value.cached)+" from cache",1)):O("",!0)])])):O("",!0),S.value==="failed"?(x(),M("div",gs,[f("p",null,I(_.value),1),re.value?(x(),M("button",{key:0,class:"btn btn--small",onClick:u[7]||(u[7]=n=>W(!0))}," Install sharp and retry ")):O("",!0)])):O("",!0),i.value?(x(),M("section",bs,[f("div",ws,[u[20]||(u[20]=f("h2",null,"Result",-1)),f("span",_s,[le(I(i.value.entries.length)+" image"+I(i.value.entries.length===1?"":"s")+" ",1),i.value.cached?(x(),M("span",ks,"· "+I(i.value.cached)+" cached",1)):O("",!0),i.value.errors.length?(x(),M("span",xs,"· "+I(i.value.errors.length)+" failed",1)):O("",!0)])]),i.value.errors.length?(x(),M("ul",Ms,[(x(!0),M(oe,null,de(i.value.errors,n=>(x(),M("li",{key:n.file},[f("code",null,I(n.file),1),le(" — "+I(n.message),1)]))),128))])):O("",!0),f("div",Ss,[f("button",{class:Re(["tab",{"tab--on":p.value==="gallery"}]),role:"tab","aria-selected":p.value==="gallery",onClick:u[8]||(u[8]=n=>p.value="gallery")}," Gallery ",10,Cs),f("button",{class:Re(["tab",{"tab--on":p.value==="output"}]),role:"tab","aria-selected":p.value==="output",onClick:u[9]||(u[9]=n=>p.value="output")}," Output ("+I(i.value.format)+") ",11,$s)]),p.value==="gallery"?(x(),M(oe,{key:1},[i.value.entries.length===0?(x(),M("p",Is,"No images were found.")):O("",!0),J(pe(Ot),{class:"gallery",items:V.value,options:t},{item:He(({item:n})=>[J(zn,{entry:F(n),onOpen:k=>d.value=Number(n.position)},null,8,["entry","onOpen"])]),_:1},8,["items"]),A.value<i.value.entries.length?(x(),M("div",zs,[f("button",{class:"btn",onClick:u[10]||(u[10]=n=>A.value+=Fe)}," Show more ("+I(i.value.entries.length-A.value)+" left) ",1),f("button",{class:"btn",onClick:u[11]||(u[11]=n=>A.value=i.value.entries.length)}," Show all ("+I(i.value.entries.length)+") ",1)])):O("",!0)],64)):(x(),M(oe,{key:2},[f("div",As,[f("button",{class:"btn btn--small",onClick:K},[J(fe,{name:T.value?"check":"copy",size:15},null,8,["name"]),le(" "+I(T.value?"Copied":"Copy"),1)]),f("button",{class:"btn btn--small",onClick:q},[J(fe,{name:"download",size:15}),u[21]||(u[21]=le(" Download ",-1))]),ye(f("input",{"onUpdate:modelValue":u[12]||(u[12]=n=>L.value=n),class:"input outbar__path",spellcheck:"false","aria-label":"File to write"},null,512),[[Oe,L.value]]),f("button",{class:"btn btn--small",disabled:L.value.trim()==="",onClick:u[13]||(u[13]=n=>D(!1))},[J(fe,{name:"save",size:15}),u[22]||(u[22]=le(" Write to file ",-1))],8,Es)]),N.value?(x(),M("p",Ls,I(N.value),1)):O("",!0),f("pre",Rs,I(i.value.output),1)],64))])):O("",!0),i.value&&d.value!==null?(x(),it(Wn,{key:4,index:d.value,"onUpdate:index":u[14]||(u[14]=n=>d.value=n),entries:i.value.entries,onClose:u[15]||(u[15]=n=>d.value=null)},null,8,["index","entries"])):O("",!0)]))}}),Ds=$e(Os,[["__scopeId","data-v-7ea67e46"]]);export{Ds as default};
|