1import{S as p,b as x,c as h,g,n as m,e as f,r as c,f as b,i as v,k as y,j as s}from"./index-3tI9Vkes.js";import{u as j}from"./useServerFn-PK6o4-z0.js";import{c as w}from"./createServerFn-HugYVUdG.js";var O=class extends p{#t;#r=void 0;#e;#s;constructor(e,r){super(),this.#t=e,this.setOptions(r),this.bindMethods(),this.#a()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){const r=this.options;this.options=this.#t.defaultMutationOptions(e),x(this.options,r)||this.#t.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#e,observer:this}),r?.mutationKey&&this.options.mutationKey&&h(r.mutationKey)!==h(this.options.mutationKey)?this.reset():this.#e?.state.status==="pending"&&this.#e.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#e?.removeObserver(this)}onMutationUpdate(e){this.#a(),this.#i(e)}getCurrentResult(){return this.#r}reset(){this.#e?.removeObserver(this),this.#e=void 0,this.#a(),this.#i()}mutate(e,r){return this.#s=r,this.#e?.removeObserver(this),this.#e=this.#t.getMutationCache().build(this.#t,this.options),this.#e.addObserver(this),this.#e.execute(e)}#a(){const e=this.#e?.state??g();this.#r={...e,isPending:e.status==="pending",isSuccess:e.status==="success",isError:e.status==="error",isIdle:e.status==="idle",mutate:this.mutate,reset:this.reset}}#i(e){m.batch(()=>{if(this.#s&&this.hasListeners()){const r=this.#r.variables,n=this.#r.context,t={client:this.#t,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#s.onSuccess?.(e.data,r,n,t)}catch(a){Promise.reject(a)}try{this.#s.onSettled?.(e.data,null,r,n,t)}catch(a){Promise.reject(a)}}else if(e?.type==="error"){try{this.#s.onError?.(e.error,r,n,t)}catch(a){Promise.reject(a)}try{this.#s.onSettled?.(void 0,e.error,r,n,t)}catch(a){Promise.reject(a)}}}this.listeners.forEach(r=>{r(this.#r)})})}};function C(e,r){const n=f(),[t]=c.useState(()=>new O(n,e));c.useEffect(()=>{t.setOptions(e)},[t,e]);const a=c.useSyncExternalStore(c.useCallback(i=>t.subscribe(m.batchCalls(i)),[t]),()=>t.getCurrentResult(),()=>t.getCurrentResult()),d=c.useCallback((i,l)=>{t.mutate(i,l).catch(b)},[t]);if(a.error&&v(t.options.throwOnError,[a.error]))throw a.error;return{...a,mutate:d,mutateAsync:a.mutate}}const N=w({method:"POST"}).handler(y("3d6db5c0324e02c8a4d5614425aceb2c57d85dec3a521c59a451f6c45be92f3f"));function S(e){return new Promise((r,n)=>{const t=new FileReader;t.onload=()=>r(t.result),t.onerror=()=>n(t.error),t.readAsDataURL(e)})}function E(){const e=j(N),r=c.useRef(null),[n,t]=c.useState(null),[a,d]=c.useState("cleaned.png"),i=C({mutationFn:async o=>{const u=await S(o);return t(u),(await e({data:{imageDataUrl:u}})).imageDataUrl}}),l=o=>{if(!o)return;const u=o.name.replace(/\.[^.]+$/,"");d(`${u}-cleaned.png`),i.mutate(o)};return s.jsxs("section",{className:"container-page py-16",children:[s.jsx("span",{className:"text-xs uppercase tracking-[0.25em] text-copper",children:"Internal tool"}),s.jsx("h1",{className:"mt-2 font-display text-4xl md:text-5xl",children:"Clean menu photos"}),s.jsx("p",{className:"mt-4 max-w-xl text-muted-foreground",children:"Upload any photo with text overlays (captions, prices, watermarks) and we'll return a clean version ready to use on the site."}),s.jsxs("div",{onDragOver:o=>o.preventDefault(),onDrop:o=>{o.preventDefault(),l(o.dataTransfer.files?.[0]??null)},onClick:()=>r.current?.click(),className:"mt-8 cursor-pointer rounded-2xl border-2 border-dashed border-border p-10 text-center hover:bg-secondary/40 transition",children:[s.jsx("p",{className:"font-medium",children:"Click or drop an image here"}),s.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"PNG / JPG · up to ~10 MB"}),s.jsx("input",{ref:r,type:"file",accept:"image/*",className:"hidden",onChange:o=>l(o.target.files?.[0]??null)})]}),i.isError&&s.jsx("p",{className:"mt-6 rounded-md bg-destructive/10 px-4 py-3 text-sm text-destructive",children:i.error?.message??"Something went wrong."}),(n||i.isPending||i.data)&&s.jsxs("div",{className:"mt-10 grid gap-8 md:grid-cols-2",children:[s.jsxs("figure",{children:[s.jsx("figcaption",{className:"mb-2 text-xs uppercase tracking-wider text-muted-foreground",children:"Original"}),n?s.jsx("img",{src:n,alt:"Original upload",className:"w-full rounded-xl border border-border object-cover"}):s.jsx("div",{className:"aspect-square w-full rounded-xl bg-secondary"})]}),s.jsxs("figure",{children:[s.jsxs("figcaption",{className:"mb-2 text-xs uppercase tracking-wider text-muted-foreground",children:["Cleaned ",i.isPending&&"
1· processingâ¦"]}),i.data?s.jsxs(s.Fragment,{children:[s.jsx("img",{src:i.data,alt:"Cleaned",className:"w-full rounded-xl border border-border object-cover"}),s.jsx("a",{href:i.data,download:a,className:"mt-4 inline-block rounded-full bg-primary px-5 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",children:"Download cleaned image"})]}):s.jsx("div",{className:"aspect-square w-full animate-pulse rounded-xl bg-secondary"})]})]})]})}export{E as component};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.