PageSourceSearch

https://uniai.ai/assets/ImageEditorPage-CGRydluy.js

js uniai.ai collected 2026-10-05 13:11:48 UTC 178,110 bytes, 690 lines download raw bytes

1var Mt=Object.defineProperty;var At=(s,t,r)=>t in s?Mt(s,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[t]=r;var ae=(s,t,r)=>At(s,typeof t!="symbol"?t+"":t,r);import{a as ye,bB as It,b as q,r as i,ai as it,W as Pt,j as e,c8 as Ft,c2 as lt,o as ct,af as be,bc as dt,w as ut,p as ht,c9 as De,b_ as mt,L as pe,ak as Ge,D as gt,ca as Bt,b6 as ft,C as xt,X as Ye,g as pt,M as Ut,ac as Wt,I as yt,cb as bt,bm as Ke,k as zt,T as vt,E as Ot,cc as Ht,cd as he,h as Xt,as as $t,z as Z,ar as Gt,ce as Yt,cf as Kt,aW as Vt,bf as qt,b7 as Zt,aX as Jt}from"./index-BawMCgu8.js";import{B as wt}from"./brush-DxaqDCGx.js";import{S as Xe}from"./Select-CBvYay3K.js";import{S as jt}from"./sliders-horizontal-Bmdy766e.js";import{H as Et}from"./history-CWHZzLwH.js";import{S as Qt}from"./save-BInnCtLF.js";import{B as er,I as tr,A as rr,a as nr,b as ar,U as sr}from"./undo-2-B7yg3O6I.js";import{F as or,U as kt,I as Ct,M as ir}from"./unlock-BWBTEvlK.js";import{A as lr}from"./arrow-down-to-line-B7YpRwzl.js";import{G as cr}from"./grip-vertical-DlO1V8kJ.js";import{R as dr}from"./redo-2-BNRfpAAM.js";import"./locale-en-B8Z5F_o1.js";import"./locale-zh-CN-CFdD1mPv.js";import"./locale-fr-j4CMJpfE.js";import"./locale-de-DuE2gagy.js";import"./locale-it-C6yb6RzN.js";import"./locale-ja-VjZBy5eF.js";import"./locale-ko-Cl0W-Az5.js";import"./locale-es-DwboUZze.js";import"./locale-zh-Hant-uT5aTnfX.js";import"./locale-ru-DEr1xfTZ.js";import"./locale-id-Buh3Uolz.js";import"./locale-pt-BR-CqD5J4_0.js";/**
2 * @license lucide-react v0.309.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const ur=ye("ArrowDown",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]]);/**
7 * @license lucide-react v0.309.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const hr=ye("FlipVertical2",[["path",{d:"m17 3-5 5-5-5h10",key:"1ftt6x"}],["path",{d:"m17 21-5-5-5 5h10",key:"1m0wmu"}],["path",{d:"M4 12H2",key:"rhcxmi"}],["path",{d:"M10 12H8",key:"s88cx1"}],["path",{d:"M16 12h-2",key:"10asgb"}],["path",{d:"M22 12h-2",key:"14jgyd"}]]);/**
12 * @license lucide-react v0.309.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const mr=ye("Lasso",[["path",{d:"M7 22a5 5 0 0 1-2-4",key:"umushi"}],["path",{d:"M3.3 14A6.8 6.8 0 0 1 2 10c0-4.4 4.5-8 10-8s10 3.6 10 8-4.5 8-10 8a12 12 0 0 1-5-1",key:"146dds"}],["path",{d:"M5 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z",key:"bq3ynw"}]]);/**
17 * @license lucide-react v0.309.0 - ISC
18 *
19 * This source code is licensed under the ISC license.
20 * See the LICENSE file in the root directory of this source tree.
21 */const gr=ye("Move",[["polyline",{points:"5 9 2 12 5 15",key:"1r5uj5"}],["polyline",{points:"9 5 12 2 15 5",key:"5v383o"}],["polyline",{points:"15 19 12 22 9 19",key:"g7qi8m"}],["polyline",{points:"19 9 22 12 19 15",key:"tpp73q"}],["line",{x1:"2",x2:"22",y1:"12",y2:"12",key:"1dnqot"}],["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}]]);/**
22 * @license lucide-react v0.309.0 - ISC
23 *
24 * This source code is licensed under the ISC license.
25 * See the LICENSE file in the root directory of this source tree.
26 */const Nt=ye("Pentagon",[["path",{d:"M3.5 8.7c-.7.5-1 1.4-.7 2.2l2.8 8.7c.3.8 1 1.4 1.9 1.4h9.1c.9 0 1.6-.6 1.9-1.4l2.8-8.7c.3-.8 0-1.7-.7-2.2l-7.4-5.3a2.1 2.1 0 0 0-2.4 0Z",key:"hsj90r"}]]),St={sourceImage:null,canvasWidth:0,canvasHeight:0,zoom:1,panX:0,panY:0,isLoading:!1,isDirty:!1,artSource:null},qe=.1,Ze=32,fr=s=>({...St,loadImage:(t,r,n)=>{const a=`layer_${Date.now()}_${Math.random().toString(36).slice(2,9)}`;s({sourceImage:t,canvasWidth:r,canvasHeight:n,isLoading:!1,isDirty:!1,zoom:1,panX:0,panY:0,layers:[{id:a,type:"image",name:"Background",visible:!0,opacity:100,blendMode:"normal",locked:!1,imageData:t,adjustments:[],transform:{x:0,y:0,width:r,height:n,rotation:0,flipH:!1,flipV:!1}}],activeLayerId:a})},setViewport:(t,r)=>{s({panX:t,panY:r})},setZoom:t=>{s({zoom:Math.max(qe,Math.min(Ze,t))})},fitToWindow:(t,r)=>{s(n=>{if(n.canvasWidth===0||n.canvasHeight===0)return n;
26const a=t/n.canvasWidth,o=r/n.canvasHeight,g=Math.min(a,o,1)*.9;return{zoom:Math.max(qe,Math.min(Ze,g)),panX:0,panY:0}})},setArtSource:t=>{s({artSource:t})},setDirty:t=>{s({isDirty:t})},resetViewport:()=>{s({zoom:1,panX:0,panY:0})}}),_t={brush:{size:20,hardness:80,opacity:100,color:"#000000"},eraser:{size:20,hardness:80},selection:{mode:"new",feather:0,tolerance:32},crop:{aspectRatio:"free",rotation:0,flipH:!1,flipV:!1},text:{font:"Inter",size:24,color:"#000000",bold:!1,italic:!1,align:"left"},shape:{type:"rect",fill:"#ffffff",stroke:"#000000",strokeWidth:2}},Lt={activeTool:"move",toolOptions:{..._t},activePanel:null},xr=s=>({...Lt,setActiveTool:t=>{s({activeTool:t})},setToolOption:(t,r)=>{s(n=>({toolOptions:{...n.toolOptions,[t]:{...n.toolOptions[t],...r}}}))},setActivePanel:t=>{s({activePanel:t})},resetToolOptions:()=>{s({toolOptions:{..._t}})}}),Rt={layers:[],activeLayerId:"",selection:null};function Ie(){return`layer_${Date.now()}_${Math.random().toString(36).slice(2,9)}`}function pr(s,t){return`${{image:"Image",adjustment:"Adjustment",text:"Text",drawing:"Drawing",shape:"Shape"}[s]} ${t+1}`}const yr=(s,t)=>({...Rt,addLayer:r=>{const n=Ie(),{layers:a}=t(),o=a.filter(u=>u.type===r.type).length,g=r.name||pr(r.type,o),c={...r,id:n,name:g};return s(u=>({layers:[...u.layers,c],activeLayerId:n,isDirty:!0})),n},removeLayer:r=>{s(n=>{const a=n.layers.filter(g=>g.id!==r),o=n.activeLayerId===r?a.length>0?a[a.length-1].id:"":n.activeLayerId;return{layers:a,activeLayerId:o,isDirty:!0}})},updateLayer:(r,n)=>{s(a=>({layers:a.layers.map(o=>o.id===r?{...o,...n}:o),isDirty:!0}))},reorderLayers:(r,n)=>{s(a=>{const o=[...a.layers],[g]=o.splice(r,1);return o.splice(n,0,g),{layers:o,isDirty:!0}})},setActiveLayer:r=>{s({activeLayerId:r})},toggleVisibility:r=>{s(n=>({layers:n.layers.map(a=>a.id===r?{...a,visible:!a.visible}:a),isDirty:!0}))},toggleLock:r=>{s(n=>({layers:n.layers.map(a=>a.id===r?{...a,locked:!a.locked}:a)}))},duplicateLayer:r=>{const{layers:n}=t(),a=n.find(c=>c.id===r);if(!a)return"";const o=Ie(),g={...a,id:o,name:`${a.name} Copy`,transform:{...a.transform,x:a.transform.x+10,y:a.transform.y+10}};return s(c=>{const u=c.layers.findIndex(w=>w.id===r),d=[...c.layers];return d.splice(u+1,0,g),{layers:d,activeLayerId:o,isDirty:!0}}),o},mergeDown:r=>{s(n=>{const a=n.layers.findIndex(u=>u.id===r);if(a<=0)return n;const o=n.layers[a-1],g={...o,name:o.name,opacity:Math.min(100,o.opacity),blendMode:o.blendMode},c=[...n.layers];return c.splice(a-1,2,g),{layers:c,activeLayerId:g.id,isDirty:!0}})},flattenAll:()=>{s(r=>{var o;if(r.layers.length===0)return r;const n=Ie();return{layers:[{id:n,type:"image",name:"Flattened",visible:!0,opacity:100,blendMode:"normal",locked:!1,imageData:(o=r.layers[0])==null?void 0:o.imageData,transform:{x:0,y:0,width:r.canvasWidth,height:r.canvasHeight,rotation:0,flipH:!1,flipV:!1}}],activeLayerId:n,isDirty:!0}})},setSelection:r=>{s({selection:r})},clearSelection:()=>{s({selection:null})}}),Tt={undoStack:[],redoStack:[],maxHistory:50};function Pe(){return`snap_${Date.now()}_${Math.random().toString(36).slice(2,9)}`}const br=(s,t)=>({...Tt,pushSnapshot:r=>{const n=t(),a={id:Pe(),name:r,timestamp:Date.now(),layers:n.layers.map(o=>({...o,transform:{...o.transform}})),activeLayerId:n.activeLayerId,canvasWidth:n.canvasWidth,canvasHeight:n.canvasHeight};s(o=>{const g=[...o.undoStack,a];return g.length>o.maxHistory&&g.splice(0,g.length-o.maxHistory),{undoStack:g,redoStack:[]}})},undo:()=>{const r=t();if(r.undoStack.length===0)return;const n={id:Pe(),name:"Current",timestamp:Date.now(),layers:r.layers.map(g=>({...g,transform:{...g.transform}})),activeLayerId:r.activeLayerId,canvasWidth:r.canvasWidth,canvasHeight:r.canvasHeight},a=[...r.undoStack],o=a.pop();s({undoStack:a,redoStack:[...r.redoStack,n],layers:o.layers,activeLayerId:o.activeLayerId,canvasWidth:o.canvasWidth,canvasHeight:o.canvasHeight,isDirty:!0})},redo:()=>{const r=t();if(r.redoStack.length===0)return;const n={id:Pe(),name:"Current",timestamp:Date.now(),layers:r.layers.map(g=>({...g,transform:{...g.transform}})),activeLayerId:r.activeLayerId,canvasWidth:r.canvasWidth,canvasHeight:r.canvasHeight},a=[...r.redoStack],o=a.pop();s({undoStack:[...r.undoStack,n],redoStack:a,layers:o.layers,activeLayerId:o.activeLayerId,canvasWidth:o.canvasWidth,canvasHeight:o.canvasHeight,isDirty:!0})},clearHistory:()=>{s({undoStack:[],redoStack:[]})}}),vr={...St,...Lt,...Rt,...Tt},L=It()((...s)=>({...fr(...s),...xr(...s),...yr(...s),...br(...s),reset:()=>{const[t]=s;t(vr)}})),Fe=[{tool:"rect-select",icon:it,group:"selection"},{tool:"lasso",icon:mr,group:"selection"},{tool:"magic-wand",icon:Pt,group:"selection"}],wr=[{tool:"move",icon:gr,group:"basic"},{tool:"crop",icon:Ft,group:"crop"},{tool:"brush",icon:wt,group:"draw"},{tool:"eraser",icon:lt,group:"draw"},{tool:"text",icon:ct,group:"content"},{tool:"shape",icon:Nt,group:"content"},{tool:"ai-erase",icon:be,group:"ai"},{tool:"ai-expand",icon:dt,group:"ai"}],jr=new Set(["basic","crop","draw","content"]);function Er(){const{t:s}=q(),t=L(y=>y.activeTool),r=L(y=>y.setActiveTool),[n,a]=i.useState(!1),[o,g]=i.useState("rect-select"),c=i.useRef(null);i.useEffect(()=>{const y=_=>{c.current&&!c.current.contains(_.target)&&a(!1)};return n&&document.addEventListener("mousedown",y),()=>document.removeEventListener("mousedown",y)},[n]);const d=(y=>y==="rect-select"||y==="lasso"||y==="magic-wand")(t),k=(Fe.find(y=>y.tool===o)||Fe[0]).icon,N=()=>{d?a(!n):r(o)},j=y=>{g(y),r(y),a(!1)},b=(y,_,M)=>{const l=y.icon;return e.jsx("button",{className:`w-10 h-10 flex items-center justify-center rounded-lg transition-colors ${_?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:_?void 0:"var(--text-secondary)"},onClick:M,title:s(`imageEditor.tools.${y.tool}`,y.tool),children:e.jsx(l,{size:20})},y.tool)};let v="";return e.jsx("div",{className:"w-14 border-r flex flex-col items-center py-2 gap-0.5",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)"},children:wr.map(y=>{const _=[];return y.group==="crop"&&v==="basic"&&(_.push(e.jsx("div",{className:"w-8 h-px my-1",style:{background:"var(--border-default)"}},"divider-basic")),_.push(e.jsxs("div",{className:"relative",ref:c,children:[e.jsxs("div",{className:"relative",children:[e.jsx("button",{className:`w-10 h-10 flex items-center justify-center rounded-lg transition-colors ${d?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:d?void 0:"var(--text-secondary)"},onClick:N,title:s(`imageEditor.tools.${o}`,o),children:e.jsx(k,{size:20})}),e.jsx("button",{className:"absolute bottom-0.5 right-0.5 w-3 h-3 flex items-center justify-center opacity-60",onClick:M=>{M.stopPropagation(),a(!n)},style:{color:d?"rgb(96, 165, 250)":"var(--text-secondary)"},children:e.jsx(ut,{size:8})})]}),n&&e.jsx("div",{className:"absolute left-full ml-2 top-0 py-1 rounded-lg shadow-xl border z-50 min-w-[160px]",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)"},children:Fe.map(M=>{const l=M.icon;return e.jsxs("button",{className:`w-full flex items-center gap-3 px-3 py-2 text-sm transition-colors ${t===M.tool?"bg-blue-500/15 text-blue-400":"hover:bg-white/10"}`,style:{color:t===M.tool?void 0:"var(--text-primary)"},onClick:()=>j(M.tool),children:[e.jsx(l,{size:16}),e.jsx("span",{children:s(`imageEditor.tools.${M.tool}`,M.tool)})]},M.tool)})})]},"selection-group"))),v&&y.group!==v&&jr.has(v)&&v!=="basic"&&_.push(e.jsx("div",{className:"w-8 h-px my-1",style:{background:"var(--border-default)"}},`divider-${v}`)),v=y.group,_.push(b(y,t===y.tool,()=>r(y.tool))),_})})}const kr=[{type:"adjust",icon:jt,labelKey:"imageEditor.panels.adju
26st"},{type:"filter",icon:ht,labelKey:"imageEditor.panels.filter"},{type:"layers",icon:De,labelKey:"imageEditor.panels.layers"},{type:"ai",icon:be,labelKey:"imageEditor.panels.ai"},{type:"history",icon:Et,labelKey:"imageEditor.panels.history"}],Cr=[{value:"free",label:"Free"},{value:"1:1",label:"1:1"},{value:"4:3",label:"4:3"},{value:"3:4",label:"3:4"},{value:"16:9",label:"16:9"},{value:"9:16",label:"9:16"}],Nr=[{value:"rect",icon:it,label:"Rectangle"},{value:"ellipse",icon:Bt,label:"Ellipse"},{value:"line",icon:ft,label:"Line"}];function Sr(s){if(!s)return"";const t=Date.now()-s,r=Math.floor(t/1e3);if(r<60)return"Just now";const n=Math.floor(r/60);return n<60?`${n}m ago`:`${Math.floor(n/60)}h ago`}function _r({onExport:s,artSource:t,onApplyToArt:r,onReturnToArt:n,isApplyingToArt:a,onSave:o,isSaving:g,lastSaved:c}){const{t:u}=q(),d=L(l=>l.activeTool),w=L(l=>l.activePanel),k=L(l=>l.setActivePanel),N=L(l=>l.zoom),j=L(l=>l.setZoom),b=L(l=>l.toolOptions),v=L(l=>l.setToolOption),y=l=>{k(w===l?null:l)},_=Math.round(N*100),M=()=>{switch(d){case"move":return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},onClick:()=>j(Math.max(.1,N-.1)),title:u("imageEditor.property.zoomOut","Zoom Out"),children:e.jsx(ft,{size:14})}),e.jsxs("span",{className:"text-xs font-mono w-12 text-center select-none",style:{color:"var(--text-primary)"},children:[_,"%"]}),e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},onClick:()=>j(Math.min(32,N+.1)),title:u("imageEditor.property.zoomIn","Zoom In"),children:e.jsx(pt,{size:14})}),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}}),e.jsxs("button",{className:"h-7 px-2 flex items-center gap-1.5 rounded text-xs hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},title:u("imageEditor.property.fitToWindow","Fit to Window"),children:[e.jsx(Ut,{size:14}),e.jsx("span",{children:u("imageEditor.property.fit","Fit")})]}),e.jsxs("button",{className:"h-7 px-2 flex items-center gap-1.5 rounded text-xs hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},onClick:()=>j(1),title:u("imageEditor.property.actualSize","1:1"),children:[e.jsx(Wt,{size:14}),e.jsx("span",{children:"1:1"})]})]});case"crop":return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.aspectRatio","Aspect Ratio")}),e.jsx(Xe,{value:b.crop.aspectRatio,onChange:l=>v("crop",{aspectRatio:l}),options:Cr.map(l=>({value:l.value,label:l.label}))}),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}}),e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.rotation","Rotation")}),e.jsx("input",{type:"number",className:"w-16 h-7 px-2 rounded text-xs border outline-none text-center",style:{background:"var(--bg-tertiary)",borderColor:"var(--border-default)",color:"var(--text-primary)"},value:b.crop.rotation,onChange:l=>v("crop",{rotation:Number(l.target.value)%360}),min:-180,max:180}),e.jsx("span",{className:"text-xs",style:{color:"var(--text-secondary)"},children:"deg"}),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}}),e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.crop.flipH?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.crop.flipH?void 0:"var(--text-secondary)"},onClick:()=>v("crop",{flipH:!b.crop.flipH}),title:u("imageEditor.property.flipH","Flip Horizontal"),children:e.jsx(or,{size:14})}),e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.crop.flipV?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.crop.flipV?void 0:"var(--text-secondary)"},onClick:()=>v("crop",{flipV:!b.crop.flipV}),title:u("imageEditor.property.flipV","Flip Vertical"),children:e.jsx(hr,{size:14})}),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}}),e.jsxs("button",{className:"h-7 px-3 flex items-center gap-1.5 rounded text-xs font-medium bg-blue-500 hover:bg-blue-600 text-white transition-colors",children:[e.jsx(xt,{size:14}),u("imageEditor.property.apply","Apply")]}),e.jsxs("button",{className:"h-7 px-3 flex items-center gap-1.5 rounded text-xs hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},children:[e.jsx(Ye,{size:14}),u("common.cancel")]})]});case"brush":return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.size","Size")}),e.jsx("input",{type:"range",className:"w-24 h-1 accent-blue-500",min:1,max:200,value:b.brush.size,onChange:l=>v("brush",{size:Number(l.target.value)})}),e.jsx("span",{className:"text-xs font-mono w-8",style:{color:"var(--text-primary)"},children:b.brush.size})]}),e.jsx("div",{className:"w-px h-5",style:{background:"var(--border-default)"}}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.hardness","Hardness")}),e.jsx("input",{type:"range",className:"w-20 h-1 accent-blue-500",min:0,max:100,value:b.brush.hardness,onChange:l=>v("brush",{hardness:Number(l.target.value)})}),e.jsxs("span",{className:"text-xs font-mono w-8",style:{color:"var(--text-primary)"},children:[b.brush.hardness,"%"]})]}),e.jsx("div",{className:"w-px h-5",style:{background:"var(--border-default)"}}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.opacity","Opacity")}),e.jsx("input",{type:"range",className:"w-20 h-1 accent-blue-500",min:1,max:100,value:b.brush.opacity,onChange:l=>v("brush",{opacity:Number(l.target.value)})}),e.jsxs("span",{className:"text-xs font-mono w-8",style:{color:"var(--text-primary)"},children:[b.brush.opacity,"%"]})]}),e.jsx("div",{className:"w-px h-5",style:{background:"var(--border-default)"}}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.color","Color")}),e.jsx("input",{type:"color",className:"w-7 h-7 rounded cursor-pointer border-0 p-0",value:b.brush.color,onChange:l=>v("brush",{color:l.target.value})})]})]});case"eraser":return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.size","Size")}),e.jsx("input",{type:"range",className:"w-24 h-1 accent-blue-500",min:1,max:200,value:b.eraser.size,onChange:l=>v("eraser",{size:Number(l.target.value)})}),e.jsx("span",{className:"text-xs font-mono w-8",style:{color:"var(--text-primary)"},children:b.eraser.size})]}),e.jsx("div",{className:"w-px h-5",style:{background:"var(--border-default)"}}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.hardness","Hardness")}),e.jsx("input",{type:"range",className:"w-20 h-1 accent-blue-500",min:0,max:100,value:b.eraser.hardness,onChange:l=>v("eraser",{hardness:Number(l.target.value)})}),e.jsxs("span",{className:"text-xs font-mono w-8",style:{color:"var(--text-primary)"},children:[b.eraser.hardness,"%"]})]})]});case"text":return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Xe,{value:b.text.font,onChange:l=>v("text",{font:l}),className:"min-w-[100px]",options:[{value:"Inter",label:"Inter"},{value:"Arial",label:"Arial"},{value:"Helvetica",label:"Helvetica"},{value:"Georgia",label:"Georgia"},{value:"Times New Roman",label:"Times New Roman"},{value:"Courier New",label:"Courier New"},{value:"Noto Sans SC",label:"Noto Sans SC"}]}),e.jsx("input",{type:"number",className:"w-14 h-7 px-2 rounded text-xs border outline-none text-center",style:{background:"var(--bg-tertiary)",borderColor:"var(--border-default)",color:"var(--text-primary)"},value:b.text.size,onChange:l=>v("text",{size:Number(l.target.value)}),min:1,max:999}),e.jsx("input",{type:"color",className:"w-7 h-7 rounded cursor-pointer border-0 p-0",value:b.text.color,onChange:l=>v("text",{color:l.target.value})}),e.jsx("div",{className:"w-px h-5 mx-0.5",style:{background:"var(--border-default)"}}),e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.text.bold?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.text.bold?void 0:"var(--text-secondary)"},onClick:()=>v("text",{bold:!b.text.bold}),title:u("imageEditor.property.bold","Bold"),children:e.jsx(er,{size:14})}),e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.text.italic?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.text.italic?void 0:"var(--text-secondary)"},onClick:()=>v("text",{italic:!b.text.italic}),title:u("imageEditor.property.italic","Italic"),children:e.jsx(tr,{size:14})}),e.jsx("div",{className:"w-px h-5 mx-0.5",style:{background:"var(--border-default)"}}),e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.text.align==="left"?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.text.align==="left"?void 0:"var(--text-secondary)"},onClick:()=>v("text",{align:"left"}),title:u("imageEditor.property.alignLeft","Align Left"),children:e.jsx(rr,{size:14})}),e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.text.align==="center"?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.text.align==="center"?void 0:"var(--text-secondary)"},onClick:()=>v("text",{align:"center"}),title:u("imageEditor.property.alignCenter","Align Center"),children:e.jsx(nr,{size:14})}),e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.text.align==="right"?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.text.align==="right"?void 0:"var(--text-secondary)"},onClick:()=>v("text",{align:"right"}),title:u("imageEditor.property.alignRight","Align Right"),children:e.jsx(ar,{size:14})})]});case"shape":return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.shapeType","Shape")}),e.jsx("div",{className:"flex items-center gap-0.5",children:Nr.map(l=>{const m=l.icon;return e.jsx("button",{className:`w-7 h-7 flex items-center justify-center rounded transition-colors ${b.shape.type===l.value?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.shape.type===l.value?void 0:"var(--text-secondary)"},onClick:()=>v("shape",{type:l.value}),title:l.label,children:e.jsx(m,{size:14})},l.value)})}),e.jsx("div",{className:"w-px h-5 mx-0.5",style:{background:"var(--border-default)"}}),e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.fill","Fill")}),e.jsx("input",{type:"color",className:"w-7 h-7 rounded cursor-pointer border-0 p-0",value:b.shape.fill,onChange:l=>v("shape",{fill:l.target.value})}),e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.stroke","Stroke")}),e.jsx("input",{type:"color",className:"w-7 h-7 rounded cursor-pointer border-0 p-0",value:b.shape.stroke,onChange:l=>v("shape",{stroke:l.target.value})}),e.jsx("input",{type:"number",className:"w-12 h-7 px-1 rounded text-xs border outline-none text-center",style:{background:"var(--bg-tertiary)",borderColor:"var(--border-default)",color:"var(--text-primary)"},value:b.shape.strokeWidth,onChange:l=>v("shape",{strokeWidth:Number(l.target.value)}),min:0,max:100}),e.jsx("span",{className:"text-xs",style:{color:"var(--text-secondary)"},children:"px"})]});
26case"rect-select":case"lasso":case"magic-wand":return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.mode","Mode")}),["new","add","subtract","intersect"].map(l=>e.jsx("button",{className:`h-7 px-2 rounded text-xs transition-colors ${b.selection.mode===l?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:b.selection.mode===l?void 0:"var(--text-secondary)"},onClick:()=>v("selection",{mode:l}),title:u(`imageEditor.property.selectionMode.${l}`,l),children:u(`imageEditor.property.selectionMode.${l}`,l.charAt(0).toUpperCase()+l.slice(1))},l)),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}}),e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.feather","Feather")}),e.jsx("input",{type:"range",className:"w-20 h-1 accent-blue-500",min:0,max:100,value:b.selection.feather,onChange:l=>v("selection",{feather:Number(l.target.value)})}),e.jsx("span",{className:"text-xs font-mono w-6",style:{color:"var(--text-primary)"},children:b.selection.feather}),d==="magic-wand"&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}}),e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.tolerance","Tolerance")}),e.jsx("input",{type:"range",className:"w-20 h-1 accent-blue-500",min:0,max:255,value:b.selection.tolerance,onChange:l=>v("selection",{tolerance:Number(l.target.value)})}),e.jsx("span",{className:"text-xs font-mono w-6",style:{color:"var(--text-primary)"},children:b.selection.tolerance})]})]});case"ai-erase":case"ai-expand":return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(pe,{size:14,className:"animate-spin text-blue-400"}),e.jsx("span",{className:"text-xs",style:{color:"var(--text-secondary)"},children:u("imageEditor.property.aiReady","AI tool ready - select area on canvas")})]});default:return null}};return e.jsxs("div",{className:"h-12 border-b flex items-center justify-between px-3 gap-4",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)"},children:[e.jsx("div",{className:"flex-1 flex items-center min-w-0 overflow-x-auto no-scrollbar",children:M()}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[t&&n&&e.jsxs("button",{className:"h-8 px-2 flex items-center gap-1.5 rounded-lg text-xs hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},onClick:n,title:u("imageEditor.art.returnToArt","Return to Art"),children:[e.jsx(mt,{size:14}),e.jsx("span",{children:u("imageEditor.art.returnToArt","Return to Art")})]}),t&&r&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"h-8 px-3 flex items-center gap-1.5 rounded-lg text-xs font-medium bg-green-500 hover:bg-green-600 text-white transition-colors disabled:opacity-50",onClick:r,disabled:a,title:u("imageEditor.art.applyToCanvas","Apply to Canvas"),children:[a?e.jsx(pe,{size:14,className:"animate-spin"}):e.jsx(Ge,{size:14}),e.jsx("span",{children:a?u("imageEditor.art.applying","Applying..."):u("imageEditor.art.applyToCanvas","Apply to Canvas")})]}),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}})]}),o&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"h-8 px-2 flex items-center gap-1.5 rounded-lg text-xs hover:bg-white/10 transition-colors disabled:opacity-50",style:{color:"var(--text-secondary)"},onClick:()=>o(),disabled:g,title:u("common.save","Save"),children:[g?e.jsx(pe,{size:14,className:"animate-spin"}):e.jsx(Qt,{size:14}),e.jsx("span",{children:g?u("imageEditor.save.saving","Saving..."):u("common.save","Save")})]}),c&&e.jsx("span",{className:"text-[10px] px-1 whitespace-nowrap",style:{color:"var(--text-tertiary)"},title:new Date(c).toLocaleString(),children:Sr(c)}),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}})]}),kr.map(l=>{const m=l.icon,x=w===l.type;return e.jsx("button",{className:`w-8 h-8 flex items-center justify-center rounded-lg transition-colors ${x?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:x?void 0:"var(--text-secondary)"},onClick:()=>y(l.type),title:u(l.labelKey,l.type),children:e.jsx(m,{size:16})},l.type)}),e.jsx("div",{className:"w-px h-5 mx-1",style:{background:"var(--border-default)"}}),e.jsxs("button",{className:"h-8 px-3 flex items-center gap-1.5 rounded-lg text-xs font-medium bg-blue-500 hover:bg-blue-600 text-white transition-colors",title:u("imageEditor.property.export","Export"),onClick:s,children:[e.jsx(gt,{size:14}),e.jsx("span",{children:u("imageEditor.property.export","Export")})]})]})]})}const Lr=`precision mediump float;
27
28varying vec2 v_texCoord;
29
30uniform sampler2D u_image;
31uniform float u_brightness; // -1..1
32uniform float u_contrast;   // -1..1
33uniform float u_exposure;   // -2..2
34
35void main() {
36    vec4 color = texture2D(u_image, v_texCoord);
37
38    // Apply exposure: multiply by 2^exposure
39    vec3 rgb = color.rgb * pow(2.0, u_exposure);
40
41    // Apply brightness: add value directly
42    rgb += u_brightness;
43
44    // Apply contrast: expand/compress around midpoint 0.5
45    rgb = (rgb - 0.5) * (1.0 + u_contrast) + 0.5;
46
47    // Clamp to valid range
48    rgb = clamp(rgb, 0.0, 1.0);
49
50    gl_FragColor = vec4(rgb, color.a);
51}
52`,Rr=`precision mediump float;
53
54varying vec2 v_texCoord;
55
56uniform sampler2D u_image;
57uniform float u_saturation;  // -1..1
58uniform float u_vibrance;    // -1..1
59uniform float u_temperature; // -1..1
60uniform float u_tint;        // -1..1
61
62// Convert RGB to HSL
63vec3 rgbToHsl(vec3 color) {
64    float maxC = max(max(color.r, color.g), color.b);
65    float minC = min(min(color.r, color.g), color.b);
66    float delta = maxC - minC;
67
68    float h = 0.0;
69    float s = 0.0;
70    float l = (maxC + minC) * 0.5;
71
72    if (delta > 0.0001) {
73        s = l < 0.5 ? delta / (maxC + minC) : delta / (2.0 - maxC - minC);
74
75        if (maxC == color.r) {
76            h = (color.g - color.b) / delta + (color.g < color.b ? 6.0 : 0.0);
77        } else if (maxC == color.g) {
78            h = (color.b - color.r) / delta + 2.0;
79        } else {
80            h = (color.r - color.g) / delta + 4.0;
81        }
82        h /= 6.0;
83    }
84
85    return vec3(h, s, l);
86}
87
88// Helper for HSL to RGB conversion
89float hueToRgb(float p, float q, float t) {
90    if (t < 0.0) t += 1.0;
91    if (t > 1.0) t -= 1.0;
92    if (t < 1.0 / 6.0) return p + (q - p) * 6.0 * t;
93    if (t < 1.0 / 2.0) return q;
94    if (t < 2.0 / 3.0) return p + (q - p) * (2.0 / 3.0 - t) * 6.0;
95    return p;
96}
97
98// Convert HSL to RGB
99vec3 hslToRgb(vec3 hsl) {
100    float h = hsl.x;
101    float s = hsl.y;
102    float l = hsl.z;
103
104    if (s < 0.0001) {
105        return vec3(l, l, l);
106    }
107
108    float q = l < 0.5 ? l * (1.0 + s) : l + s - l * s;
109    float p = 2.0 * l - q;
110
111    float r = hueToRgb(p, q, h + 1.0 / 3.0);
112    float g = hueToRgb(p, q, h);
113    float b = hueToRgb(p, q, h - 1.0 / 3.0);
114
115    return vec3(r, g, b);
116}
117
118void main() {
119    vec4 color = texture2D(u_image, v_texCoord);
120    vec3 rgb = color.rgb;
121
122    // Apply saturation via HSL
123    vec3 hsl = rgbToHsl(rgb);
124    if (u_saturation > 0.0) {
125        hsl.y = hsl.y + (1.0 - hsl.y) * u_saturation;
126    } else {
127        hsl.y = hsl.y * (1.0 + u_saturation);
128    }
129    hsl.y = clamp(hsl.y, 0.0, 1.0);
130    rgb = hslToRgb(hsl);
131
132    // Apply vibrance: boost less-saturated colors more
133    float maxChannel = max(max(rgb.r, rgb.g), rgb.b);
134    float minChannel = min(min(rgb.r, rgb.g), rgb.b);
135    float currentSat = maxChannel - minChannel;
136    // Less saturated pixels get more boost
137    float vibranceScale = u_vibrance * (1.0 - currentSat);
138    float avgLum = (rgb.r + rgb.g + rgb.b) / 3.0;
139    rgb += (avgLum - rgb) * (-vibranceScale);
140
141    // Apply temperature: shift warm (red) vs cool (blue)
142    rgb.r += u_temperature * 0.1;
143    rgb.b -= u_temperature * 0.1;
144
145    // Apply tint: shift green vs magenta
146    rgb.g += u_tint * 0.1;
147
148    rgb = clamp(rgb, 0.0, 1.0);
149
150    gl_FragColor = vec4(rgb, color.a);
151}
152`,Tr=`precision mediump float;
153
154varying vec2 v_texCoord;
155
156uniform sampler2D u_image;
157uniform sampler2D u_curveLUT; // 256x1 RGBA lookup texture
158uniform int u_channel;        // 0=RGB, 1=R, 2=G, 3=B
159
160void main() {
161    vec4 color = texture2D(u_image, v_texCoord);
162
163    // Sample the curve LUT for each channel
164    // The LUT stores remapped values: x-coord = input intensity, sampled value = output intensity
165    float r = color.r;
166    float g = color.g;
167    float b = color.b;
168
169    if (u_channel == 0) {
170        // Apply RGB curve to all channels
171        r = texture2D(u_curveLUT, vec2(r, 0.5)).r;
172        g = texture2D(u_curveLUT, vec2(g, 0.5)).r;
173        b = texture2D(u_curveLUT, vec2(b, 0.5)).r;
174    } else if (u_channel == 1) {
175        // Red channel only
176        r = texture2D(u_curveLUT, vec2(r, 0.5)).r;
177    } else if (u_channel == 2) {
178        // Green channel only
179        g = texture2D(u_curveLUT, vec2(g, 0.5)).r;
180    } else if (u_channel == 3) {
181        // Blue channel only
182        b = texture2D(u_curveLUT, vec2(b, 0.5)).r;
183    }
184
185    gl_FragColor = vec4(r, g, b, color.a);
186}
187`,Dr=`precision mediump float;
188
189varying vec2 v_texCoord;
190
191uniform sampler2D u_image;
192uniform float u_inputBlack;  // 0..1
193uniform float u_inputWhite;  // 0..1
194uniform float u_gamma;       // 0.1..10
195uniform float u_outputBlack; // 0..1
196uniform float u_outputWhite; // 0..1
197
198void main() {
199    vec4 color = texture2D(u_image, v_texCoord);
200    vec3 rgb = color.rgb;
201
202    // Step 1: Clamp to input range and normalize
203    float inputRange = max(u_inputWhite - u_inputBlack, 0.001);
204    rgb = clamp(rgb, vec3(u_inputBlack), vec3(u_inputWhite));
205    rgb = (rgb - u_inputBlack) / inputRange;
206
207    // Step 2: Apply gamma correction
208    // gamma > 1 darkens midtones, gamma < 1 brightens midtones
209    float invGamma = 1.0 / u_gamma;
210    rgb = pow(rgb, vec3(invGamma));
211
212    // Step 3: Remap to output range
213    float outputRange = u_outputWhite - u_outputBlack;
214    rgb = rgb * outputRange + u_outputBlack;
215
216    rgb = clamp(rgb, 0.0, 1.0);
217
218    gl_FragColor = vec4(rgb, color.a);
219}
220`,Mr=`precision mediump float;
221
222varying vec2 v_texCoord;
223
224uniform sampler2D u_image;
225
226// Shadows adjustments (-1..1)
227uniform float u_shadowsCyanRed;
228uniform float u_shadowsMagentaGreen;
229uniform float u_shadowsYellowBlue;
230
231// Midtones adjustments (-1..1)
232uniform float u_midtonesCyanRed;
233uniform float u_midtonesMagentaGreen;
234uniform float u_midtonesYellowBlue;
235
236// Highlights adjustments (-1..1)
237uniform float u_highlightsCyanRed;
238uniform float u_highlightsMagentaGreen;
239uniform float u_highlightsYellowBlue;
240
241void main() {
242    vec4 color = texture2D(u_image, v_texCoord);
243    vec3 rgb = color.rgb;
244
245    // Compute luminance for tonal range weighting
246    float lum = dot(rgb, vec3(0.2126, 0.7152, 0.0722));
247
248    // Shadows weight: strongest in dark regions, fades out
249    float shadowsWeight = 1.0 - smoothstep(0.0, 0.5, lum);
250    // Highlights weight: strongest in bright regions, fades out
251    float highlightsWeight = smoothstep(0.5, 1.0, lum);
252    // Midtones weight: strongest in middle range
253    float midtonesWeight = 1.0 - shadowsWeight - highlightsWeight;
254    midtonesWeight = max(midtonesWeight, 0.0);
255
256    // Build color shift for each tonal range
257    vec3 shadowShift = vec3(
258        u_shadowsCyanRed,
259        u_shadowsMagentaGreen,
260        u_shadowsYellowBlue
261    );
262    vec3 midtoneShift = vec3(
263        u_midtonesCyanRed,
264        u_midtonesMagentaGreen,
265        u_midtonesYellowBlue
266    );
267    vec3 highlightShift = vec3(
268        u_highlightsCyanRed,
269        u_highlightsMagentaGreen,
270        u_highlightsYellowBlue
271    );
272
273    // Apply weighted shifts (scale to reasonable range)
274    vec3 totalShift = shadowShift * shadowsWeight * 0.15
275                    + midtoneShift * midtonesWeight * 0.15
276                    + highlightShift * highlightsWeight * 0.15;
277
278    rgb += totalShift;
279    rgb = clamp(rgb, 0.0, 1.0);
280
281    gl_FragColor = vec4(rgb, color.a);
282}
283`,Ar=`precision mediump float;
284
285varying vec2 v_texCoord;
286
287uniform sampler2D u_image;
288uniform float u_amount;    // 0..1
289uniform vec2 u_texelSize;  // vec2(1.0/width, 1.0/height)
290
291void main() {
292    // Sample the center and its 4 neighbors (cross kernel)
293    vec3 center = texture2D(u_image, v_texCoord).rgb;
294
295    vec3 top    = texture2D(u_image, v_texCoord + vec2(0.0, -u_texelSize.y)).rgb;
296    vec3 bottom = texture2D(u_image, v_texCoord + vec2(0.0,  u_texelSize.y)).rgb;
297    vec3 left   = texture2D(u_image, v_texCoord + vec2(-u_texelSize.x, 0.0
297)).rgb;
298    vec3 right  = texture2D(u_image, v_texCoord + vec2( u_texelSize.x, 0.0)).rgb;
299
300    // Also sample diagonals for better quality blur estimate
301    vec3 topLeft     = texture2D(u_image, v_texCoord + vec2(-u_texelSize.x, -u_texelSize.y)).rgb;
302    vec3 topRight    = texture2D(u_image, v_texCoord + vec2( u_texelSize.x, -u_texelSize.y)).rgb;
303    vec3 bottomLeft  = texture2D(u_image, v_texCoord + vec2(-u_texelSize.x,  u_texelSize.y)).rgb;
304    vec3 bottomRight = texture2D(u_image, v_texCoord + vec2( u_texelSize.x,  u_texelSize.y)).rgb;
305
306    // Gaussian-weighted blur (3x3 kernel)
307    // Weights: center=4/16, edges=2/16, corners=1/16
308    vec3 blur = (center * 4.0
309               + (top + bottom + left + right) * 2.0
310               + (topLeft + topRight + bottomLeft + bottomRight) * 1.0) / 16.0;
311
312    // Unsharp mask: original + (original - blur) * amount
313    vec3 sharpened = center + (center - blur) * u_amount * 3.0;
314
315    sharpened = clamp(sharpened, 0.0, 1.0);
316
317    float alpha = texture2D(u_image, v_texCoord).a;
318    gl_FragColor = vec4(sharpened, alpha);
319}
320`,Ir=`precision mediump float;
321
322varying vec2 v_texCoord;
323
324uniform sampler2D u_image;
325uniform float u_amount;    // 0..1
326uniform vec2 u_texelSize;  // vec2(1.0/width, 1.0/height)
327
328void main() {
329    vec3 center = texture2D(u_image, v_texCoord).rgb;
330    float alpha = texture2D(u_image, v_texCoord).a;
331
332    // Bilateral filter approximation: 3x3 kernel
333    // Weight by both spatial distance and color/range distance
334
335    float sigmaSpace = 1.0;
336    float sigmaRange = 0.15 + u_amount * 0.35; // Higher amount = more tolerance for color diff
337
338    vec3 weightedSum = vec3(0.0);
339    float totalWeight = 0.0;
340
341    for (int y = -1; y <= 1; y++) {
342        for (int x = -1; x <= 1; x++) {
343            vec2 offset = vec2(float(x), float(y)) * u_texelSize;
344            vec3 sample_color = texture2D(u_image, v_texCoord + offset).rgb;
345
346            // Spatial weight (Gaussian)
347            float spatialDist = length(vec2(float(x), float(y)));
348            float spatialWeight = exp(-spatialDist * spatialDist / (2.0 * sigmaSpace * sigmaSpace));
349
350            // Range weight (color similarity)
351            vec3 colorDiff = sample_color - center;
352            float rangeDist = dot(colorDiff, colorDiff);
353            float rangeWeight = exp(-rangeDist / (2.0 * sigmaRange * sigmaRange));
354
355            float weight = spatialWeight * rangeWeight;
356            weightedSum += sample_color * weight;
357            totalWeight += weight;
358        }
359    }
360
361    vec3 denoised = weightedSum / totalWeight;
362
363    // Mix between original and denoised based on amount
364    vec3 result = mix(center, denoised, u_amount);
365
366    gl_FragColor = vec4(result, alpha);
367}
368`,Pr=`precision mediump float;
369
370varying vec2 v_texCoord;
371
372uniform sampler2D u_image;
373uniform float u_amount;   // -1..1 (negative = brighten edges)
374uniform float u_softness; // 0..1
375
376void main() {
377    vec4 color = texture2D(u_image, v_texCoord);
378
379    // Distance from center (0,0 at center, ~0.707 at corners)
380    vec2 uv = v_texCoord - 0.5;
381    float dist = length(uv);
382
383    // Compute vignette factor
384    // Inner radius where vignette starts; outer radius where it's fully applied
385    float innerRadius = 0.2 + u_softness * 0.3;
386    float outerRadius = 0.7 + u_softness * 0.3;
387
388    float vignette = smoothstep(innerRadius, outerRadius, dist);
389
390    // Apply vignette: darken (positive amount) or brighten (negative amount) edges
391    float factor = 1.0 - vignette * u_amount;
392
393    vec3 rgb = color.rgb * factor;
394    rgb = clamp(rgb, 0.0, 1.0);
395
396    gl_FragColor = vec4(rgb, color.a);
397}
398`,Fr=`precision mediump float;
399
400varying vec2 v_texCoord;
401
402uniform sampler2D u_base;
403uniform sampler2D u_blend;
404uniform float u_opacity;   // 0..1
405uniform int u_blendMode;   // 0..11
406
407// Blend mode constants
408// 0  = normal
409// 1  = multiply
410// 2  = screen
411// 3  = overlay
412// 4  = soft-light
413// 5  = hard-light
414// 6  = color-dodge
415// 7  = color-burn
416// 8  = darken
417// 9  = lighten
418// 10 = difference
419// 11 = exclusion
420
421// Overlay per-channel helper
422float overlayChannel(float base, float blend) {
423    if (base < 0.5) {
424        return 2.0 * base * blend;
425    } else {
426        return 1.0 - 2.0 * (1.0 - base) * (1.0 - blend);
427    }
428}
429
430// Soft light per-channel (Photoshop formula)
431float softLightChannel(float base, float blend) {
432    if (blend < 0.5) {
433        return base - (1.0 - 2.0 * blend) * base * (1.0 - base);
434    } else {
435        float d = (base <= 0.25)
436            ? ((16.0 * base - 12.0) * base + 4.0) * base
437            : sqrt(base);
438        return base + (2.0 * blend - 1.0) * (d - base);
439    }
440}
441
442// Hard light per-channel
443float hardLightChannel(float base, float blend) {
444    // Hard light is overlay with base/blend swapped
445    if (blend < 0.5) {
446        return 2.0 * base * blend;
447    } else {
448        return 1.0 - 2.0 * (1.0 - base) * (1.0 - blend);
449    }
450}
451
452// Color dodge per-channel
453float colorDodgeChannel(float base, float blend) {
454    if (blend >= 1.0) return 1.0;
455    return min(1.0, base / (1.0 - blend));
456}
457
458// Color burn per-channel
459float colorBurnChannel(float base, float blend) {
460    if (blend <= 0.0) return 0.0;
461    return max(0.0, 1.0 - (1.0 - base) / blend);
462}
463
464void main() {
465    vec4 baseColor = texture2D(u_base, v_texCoord);
466    vec4 blendColor = texture2D(u_blend, v_texCoord);
467
468    vec3 base = baseColor.rgb;
469    vec3 blend = blendColor.rgb;
470    vec3 result = blend; // default: normal
471
472    if (u_blendMode == 0) {
473        // Normal
474        result = blend;
475    } else if (u_blendMode == 1) {
476        // Multiply
477        result = base * blend;
478    } else if (u_blendMode == 2) {
479        // Screen
480        result = 1.0 - (1.0 - base) * (1.0 - blend);
481    } else if (u_blendMode == 3) {
482        // Overlay
483        result = vec3(
484            overlayChannel(base.r, blend.r),
485            overlayChannel(base.g, blend.g),
486            overlayChannel(base.b, blend.b)
487        );
488    } else if (u_blendMode == 4) {
489        // Soft Light
490        result = vec3(
491            softLightChannel(base.r, blend.r),
492            softLightChannel(base.g, blend.g),
493            softLightChannel(base.b, blend.b)
494        );
495    } else if (u_blendMode == 5) {
496        // Hard Light
497        result = vec3(
498            hardLightChannel(base.r, blend.r),
499            hardLightChannel(base.g, blend.g),
500            hardLightChannel(base.b, blend.b)
501        );
502    } else if (u_blendMode == 6) {
503        // Color Dodge
504        result = vec3(
505            colorDodgeChannel(base.r, blend.r),
506            colorDodgeChannel(base.g, blend.g),
507            colorDodgeChannel(base.b, blend.b)
508        );
509    } else if (u_blendMode == 7) {
510        // Color Burn
511        result = vec3(
512            colorBurnChannel(base.r, blend.r),
513            colorBurnChannel(base.g, blend.g),
514            colorBurnChannel(base.b, blend.b)
515        );
516    } else if (u_blendMode == 8) {
517        // Darken
518        result = min(base, blend);
519    } else if (u_blendMode == 9) {
520        // Lighten
521        result = max(base, blend);
522    } else if (u_blendMode == 10) {
523        // Difference
524        result = abs(base - blend);
525    } else if (u_blendMode == 11) {
526        // Exclusion
527        result = base + blend - 2.0 * base * blend;
528    }
529
530    // Mix the blended result with the base using opacity
531    result = mix(base, result, u_opacity * blendColor.a);
532
533    gl_FragColor = vec4(result, baseColor.a);
534}
535`,Br=`precision mediump float;
536
537varying vec2 v_texCoord;
538
539uniform sampler2D u_image;
540uniform float u_highlights; // -1..1
541uniform float u_shadows;    // -1..1
542
543void main() {
544    vec4 color = texture2D(u_image, v_texCoord);
545    vec3 rgb = color.rgb;
546
547    // Compute luminance (Rec. 709)
548    float lum = dot(rgb, vec3(0.2126, 0.7152, 0.0722));
549
550    // Shadow weight: strong in dark areas, fades in bright areas
551    float shadowWeight = 1.0 - smoothstep(0.0, 0.5, lum);
552    // Highlight weight: strong in bright areas, fades in dark areas
553    float highlightWeight = smoothstep(0.5, 1.0, lum);
554
555    // Apply shadow adjustment: brighten or darken dark areas
556    // Positive u_shadows brightens shadows, negative darkens them further
557    vec3 shadowAdjust = rgb + u_shadows * shadowWeight * 0.3;
558
559    // Apply highlight adjustment: brighten or darken bright areas
560    // Positive u_highlights brightens highlights, negative darkens them
561    vec3 highlightAdjust = shadowAdjust + u_highlights * highlightWeight * 0.3;
562
563    vec3 result = clamp(highlightAdjust, 0.0, 1.0);
564
565    gl_FragColor = vec4(result, color.a);
566}
567`,Ur={normal:0,multiply:1,screen:2,overlay:3,"soft-light":4,"hard-light":5,"color-dodge":6,"color-burn":7,darken:8,lighten:9,difference:10,exclusion:11},Wr=`
568attribute vec2 a_position;
569attribute vec2 a_texCoord;
570varying vec2 v_texCoord;
571void main() {
572  gl_Position = vec4(a_position, 0.0, 1.0);
573  v_texCoord = a_texCoord;
574}
575`,zr={"brightness-contrast":Lr,"hue-saturation":Rr,curves:Tr,levels:Dr,"color-balance":Mr,sharpen:Ar,denoise:Ir,vignette:Pr,"blend-modes":Fr,"highlights-shadows":Br};class Or{constructor(t){ae(this,"gl",null);ae(this,"canvas");ae(this,"programs",new Map);ae(this,"textures",new Map);ae(this,"framebuffers");ae(this,"fboTextures");ae(this,"vertexBuffer",null);ae(this,"texCoordBuffer",null);ae(this,"width",0);ae(this,"height",0);ae(this,"currentFbo","a");ae(this,"contextLost",!1);ae(this,"_onContextLost",null);ae(this,"_onContextRestored",null);this.canvas=t}init(){this._onContextLost=t=>{t.preventDefault(),this.contextLost=!0,console.warn("[WebGLRenderer] WebGL context lost")},this._onContextRestored=()=>{console.info("[WebGLRenderer] WebGL context restored, reinitializing..."),this.contextLost=!1,this._initInternal()},this.canvas.addEventListener("webglcontextlost",this._onContextLost),this.canvas.addEventListener("webglcontextrestored",this._onContextRestored),this._initInternal()}_initInternal(){this.programs.clear(),this.textures.clear();const t=this.canvas.getContext("webgl",{premultipliedAlpha:!1,preserveDrawingBuffer:!0,antialias:!1});if(!t)throw new Error("WebGL is not supported in this browser");this.gl=t,this._createGeometryBuffers();for(const[r,n]of Object.entries(zr))this.compileProgram(r,Wr,n)}_createGeometryBuffers(){const t=this._getGL(),r=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),n=new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1]);if(this.vertexBuffer=t.createBuffer(),!this.vertexBuffer)throw new Error("Failed to create vertex buffer");if(t.bindBuffer(t.ARRAY_BUFFER,this.vertexBuffer),t.bufferData(t.ARRAY_BUFFER,r,t.STATIC_DRAW),this.texCoordBuffer=t.createBuffer(),!this.texCoordBuffer)throw new Error("Failed to create texCoord buffer");t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferData(t.ARRAY_BUFFER,n,t.STATIC_DRAW)}compileProgram(t,r,n){const a=this._getGL(),o=this._compileShader(a.VERTEX_SHADER,r,t),g=this._compileShader(a.FRAGMENT_SHADER,n,t),c=a.createProgram();if(!c)throw new Error(`Failed to create program "${t}"`);if(a.attachShader(c,o),a.attachShader(c,g),a.linkProgram(c),!a.getProgramParameter(c,a.LINK_STATUS)){const u=a.getProgramInfoLog(c);throw a.deleteProgram(c),a.deleteShader(o),a.deleteShader(g),new Error(`Failed to link program "${t}": ${u}`)}return a.detachShader(c,o),a.detachShader(c,g),a.deleteShader(o),a.deleteShader(g),this.programs.set(t,c),c}_compileShader(t,r,n){const a=this._getGL(),o=a.createShader(t);if(!o)throw new Error(`Failed to create shader for "${n}"`);if(a.shaderSource(o,r),a.compileShader(o),!a.getShaderParameter(o,a.COMPILE_STATUS)){const g=a.getShaderInfoLog(o),c=t===a.VERTEX_SHADER?"vertex":"fragment";throw a.deleteShader(o),new Error(`Failed to compile ${c} shader for "${n}": ${g}`)}return o}uploadTexture(t,r){const n=this._getGL(),a=this.textures.get(t);a&&n.deleteTexture(a);const o=n.createTexture();if(!o)throw new Error(`Failed to create texture "${t}"`);return n.bindTexture(n.TEXTURE_2D,o),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.L
575INEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,r),n.bindTexture(n.TEXTURE_2D,null),this.textures.set(t,o),o}uploadDataTexture(t,r,n,a){const o=this._getGL(),g=this.textures.get(t);g&&o.deleteTexture(g);const c=o.createTexture();if(!c)throw new Error(`Failed to create data texture "${t}"`);return o.bindTexture(o.TEXTURE_2D,c),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,n,a,0,o.RGBA,o.UNSIGNED_BYTE,r),o.bindTexture(o.TEXTURE_2D,null),this.textures.set(t,c),c}getTexture(t){return this.textures.get(t)}setupFramebuffers(t,r){this._getGL(),this.width=t,this.height=r,this._deleteFramebuffers();const n=this._createFBO(t,r),a=this._createFBO(t,r);this.framebuffers={a:n.framebuffer,b:a.framebuffer},this.fboTextures={a:n.texture,b:a.texture},this.currentFbo="a",this.canvas.width=t,this.canvas.height=r}_createFBO(t,r){const n=this._getGL(),a=n.createTexture();if(!a)throw new Error("Failed to create FBO texture");n.bindTexture(n.TEXTURE_2D,a),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.L
575INEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,t,r,0,n.RGBA,n.UNSIGNED_BYTE,null);const o=n.createFramebuffer();if(!o)throw new Error("Failed to create framebuffer");n.bindFramebuffer(n.FRAMEBUFFER,o),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,a,0);const g=n.checkFramebufferStatus(n.FRAMEBUFFER);if(g!==n.FRAMEBUFFER_COMPLETE)throw new Error(`Framebuffer incomplete: status ${g}`);return n.bindFramebuffer(n.FRAMEBUFFER,null),n.bindTexture(n.TEXTURE_2D,null),{framebuffer:o,texture:a}}_deleteFramebuffers(){const t=this.gl;t&&(this.framebuffers&&(t.deleteFramebuffer(this.framebuffers.a),t.deleteFramebuffer(this.framebuffers.b)),this.fboTextures&&(t.deleteTexture(this.fboTextures.a),t.deleteTexture(this.fboTextures.b)))}applyShader(t,r,n){const a=this._getGL();if(this.contextLost)return;const o=this.programs.get(t);if(!o)throw new Error(`Shader program "${t}" not found`);a.useProgram(o);const g=this.currentFbo,c=g==="a"?"b":"a";a.bindFramebuffer(a.FRAMEBUFFER,this.framebuffers[c]),a.viewport(0,0,this.width,this.height),this._bindGeometry(o);let u=0;for(const[N,j]of Object.entries(r)){const b=a.getUniformLocation(o,N);if(b!==null){if(j instanceof WebGLTexture)a.activeTexture(a.TEXTURE0+u),a.bindTexture(a.TEXTURE_2D,j),a.uniform1i(b,u),u++;else if(typeof j=="number")N==="u_blendMode"||N==="u_channel"?a.uniform1i(b,j):a.uniform1f(b,j);else if(Array.isArray(j))switch(j.length){case 2:a.uniform2f(b,j[0],j[1]);break;case 3:a.uniform3f(b,j[0],j[1],j[2]);break;case 4:a.uniform4f(b,j[0],j[1],j[2],j[3]);break;default:console.warn(`[WebGLRenderer] Unsupported uniform array length ${j.length} for "${N}"`)}}}const d=n??this.fboTextures[g],w=this._getPrimaryTextureUniform(t),k=a.getUniformLocation(o,w);k!==null&&!(w in r)&&(a.activeTexture(a.TEXTURE0+u),a.bindTexture(a.TEXTURE_2D,d),a.uniform1i(k,u),u++),a.drawArrays(a.TRIANGLES,0,6),this.currentFbo=c}applyAdjustments(t,r){if(this._getGL(),this.contextLost)return;const n=this.textures.get(t);if(!n)throw new Error(`Source texture "${t}" not found`);const a=r.filter(g=>g.enabled);if(a.length===0){this._copyTextureToCurrentFbo(n);return}const o=a[0];this.applyShader(o.type,o.uniforms,n);for(let g=1;g<a.length;g++){const c=a[g];this.applyShader(c.type,c.uniforms)}}renderToScreen(){const t=this._getGL();if(this.contextLost)return;const r=this.fboTextures[this.currentFbo];t.bindFramebuffer(t.FRAMEBUFFER,null),t.viewport(0,0,this.width,this.height);const n=this.programs.get("brightness-contrast");if(!n)throw new Error("Passthrough program not available");t.useProgram(n),this._bindGeometry(n);const a=t.getUniformLocation(n,"u_brightness"),o=t.getUniformLocation(n,"u_contrast"),g=t.getUniformLocation(n,"u_exposure");a&&t.uniform1f(a,0),o&&t.uniform1f(o,0),g&&t.uniform1f(g,0);const c=t.getUniformLocation(n,"u_image");t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,r),c&&t.uniform1i(c,0),t.drawArrays(t.TRIANGLES,0,6)}readPixels(){const t=this._getGL();t.bindFramebuffer(t.FRAMEBUFFER,this.framebuffers[this.currentFbo]),t.viewport(0,0,this.width,this.height);const r=new Uint8Array(this.width*this.height*4);t.readPixels(0,0,this.width,this.height,t.RGBA,t.UNSIGNED_BYTE,r);const n=new Uint8ClampedArray(this.width*this.height*4),a=this.width*4;for(let o=0;o<this.height;o++){const g=(this.height-1-o)*a,c=o*a;n.set(r.subarray(g,g+a),c)}return t.bindFramebuffer(t.FRAMEBUFFER,null),new ImageData(n,this.width,this.height)}blendTextures(t,r,n,a){this.applyShader("blend-modes",{u_base:t,u_blend:r,u_blendMode:Ur[n],u_opacity:a},void 0)}dispose(){const t=this.gl;if(this._onContextLost&&this.canvas.removeEventListener("webglcontextlost",this._onContextLost),this._onContextRestored&&this.canvas.removeEventListener("webglcontextrestored",this._onContextRestored),!!t){for(const r of this.programs.values())t.deleteProgram(r);this.programs.clear();for(const r of this.textures.values())t.deleteTexture(r);this.textures.clear(),this._deleteFramebuffers(),this.vertexBuffer&&t.deleteBuffer(this.vertexBuffer),this.texCoordBuffer&&t.deleteBuffer(this.texCoordBuffer),this.gl=null}}getGL(){return this.gl}isContextLost(){return this.contextLost}getWidth(){return this.width}
575getHeight(){return this.height}_getGL(){if(!this.gl)throw new Error("WebGL context not initialized. Call init() first.");if(this.contextLost)throw new Error("WebGL context is currently lost.");return this.gl}_bindGeometry(t){const r=this._getGL(),n=r.getAttribLocation(t,"a_position");n>=0&&(r.bindBuffer(r.ARRAY_BUFFER,this.vertexBuffer),r.enableVertexAttribArray(n),r.vertexAttribPointer(n,2,r.FLOAT,!1,0,0));const a=r.getAttribLocation(t,"a_texCoord");a>=0&&(r.bindBuffer(r.ARRAY_BUFFER,this.texCoordBuffer),r.enableVertexAttribArray(a),r.vertexAttribPointer(a,2,r.FLOAT,!1,0,0))}_getPrimaryTextureUniform(t){return t==="blend-modes"?"u_base":"u_image"}_copyTextureToCurrentFbo(t){const r=this._getGL(),n=this.currentFbo==="a"?"b":"a";r.bindFramebuffer(r.FRAMEBUFFER,this.framebuffers[n]),r.viewport(0,0,this.width,this.height);const a=this.programs.get("brightness-contrast");if(!a)throw new Error("Passthrough program not available");r.useProgram(a),this._bindGeometry(a);const o=r.getUniformLocation(a,"u_brightness"),g=r.getUniformLocation(a,"u_contrast"),c=r.getUniformLocation(a,"u_exposure");o&&r.uniform1f(o,0),g&&r.uniform1f(g,0),c&&r.uniform1f(c,0);const u=r.getUniformLocation(a,"u_image");r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,t),u&&r.uniform1i(u,0),r.drawArrays(r.TRIANGLES,0,6),this.currentFbo=n}}class Hr{constructor(t){ae(this,"renderer");this.renderer=t}applyLayerAdjustments(t,r){this.renderer.applyAdjustments(t,r),this.renderer.renderToScreen()}composite(t){const r=t.filter(c=>c.visible&&c.source!==null);if(r.length===0){this._clearCanvas();return}const n=this.renderer.getWidth(),a=this.renderer.getHeight();if(n===0||a===0){console.warn("[LayerEngine] Canvas dimensions not set. Call setupFramebuffers first.");return}const o=r[0];this._processLayer(o,`_layer_${o.id}`);const g=this.renderer.readPixels();this._uploadImageData("_composite_result",g,n,a);for(let c=1;c<r.length;c++){const u=r[c];this._processLayer(u,`_layer_${u.id}`);const d=this.renderer.readPixels();this._uploadImageData(`_layer_result_${u.id}`,d,n,a);const w=this.renderer.getTexture("_composite_result"),k=this.renderer.getTexture(`_layer_result_${u.id}`);if(!w||!k){console.warn(`[LayerEngine] Missing textures for layer "${u.name}"`);continue}this.renderer.blendTextures(w,k,u.blendMode,u.opacity);const N=this.renderer.readPixels();this._uploadImageData("_composite_result",N,n,a)}this.renderer.renderToScreen()}exportResult(){return this.renderer.readPixels()}_processLayer(t,r){t.source&&(this.renderer.uploadTexture(r,t.source),this.renderer.applyAdjustments(r,t.adjustments),t.mask&&this._applyMask(t.mask,r))}_applyMask(t,r){this.renderer.uploadTexture("_mask_temp",t),console.info("[LayerEngine] Mask application is a Phase 2 feature")}_uploadImageData(t,r,n,a){const o=document.createElement("canvas");o.width=n,o.height=a;const g=o.getContext("2d");if(!g){console.warn("[LayerEngine] Failed to create 2D context for ImageData upload");return}g.putImageData(r,0,0),this.renderer.uploadTexture(t,o)}_clearCanvas(){const t=this.renderer.getGL();t&&(t.bindFramebuffer(t.FRAMEBUFFER,null),t.viewport(0,0,this.renderer.getWidth(),this.renderer.getHeight()),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT))}}function Xr(s,t,r){const n=a=>{if(!(a.metaKey||a.ctrlKey))return;const g=a.target;g&&(g.tagName==="INPUT"||g.tagName==="TEXTAREA"||g.isContentEditable)||(a.key==="z"&&!a.shiftKey?(a.preventDefault(),s()):(a.key==="y"||a.key==="z"&&a.shiftKey)&&(a.preventDefault(),t()))};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)}function Je(s){return s.map(t=>{const r={};switch(t.type){case"brightness":case"contrast":case"exposure":return r.u_brightness=t.type==="brightness"&&typeof t.value=="number"?t.value/100:0,r.u_contrast=t.type==="contrast"&&typeof t.value=="number"?t.value/100:0,r.u_exposure=t.type==="exposure"&&typeof t.value=="number"?t.value/100:0,{type:"brightness-contrast",enabled:t.enabled,uniforms:r};case"highlights":case"shadows":return r.u_highlights=t.type==="highlights"&&typeof t.value=="number"?t.value/100:0,r.u_shadows=t.type==="shadows"&&typeof t.value=="number"?t.value/100:0,{type:"highlights-shadows",enabled:t.enabled,uniforms:r};case"saturation":case"vibrance":case"temperature":case"tint":return r.u_saturation=t.type==="saturation"&&typeof t.value=="number"?t.value/100:0,r.u_vibrance=t.type==="vibrance"&&typeof t.value=="number"?t.value/100:0,r.u_hue=(t.type==="temperature"||t.type==="tint")&&typeof t.value=="number"?t.value/100:0,{type:"hue-saturation",enabled:t.enabled,uniforms:r};case"levels":{const n={u_inputMin:Array.isArray(t.value)?t.value[0]/255:0,u_inputMax:Array.isArray(t.value)?t.value[1]/255:1,u_gamma:Array.isArray(t.value)?t.value[2]:1,u_outputMin:Array.isArray(t.value)?t.value[3]/255:0,u_outputMax:Array.isArray(t.value)?t.value[4]/255:1};return{type:"levels",enabled:t.enabled,uniforms:n}}case"curves":return{type:"curves",enabled:t.enabled,uniforms:r};case"color-balance":{const n={u_shadows:Array.isArray(t.value)?t.value.slice(0,3):[0,0,0],u_midtones:Array.isArray(t.value)?t.value.slice(3,6):[0,0,0],u_highlights:Array.isArray(t.value)?t.value.slice(6,9):[0,0,0]};return{type:"color-balance",enabled:t.enabled,uniforms:n}}case"sharpen":{const n={u_amount:typeof t.value=="number"?t.value/100:0};return{type:"sharpen",enabled:t.enabled,uniforms:n}}case"denoise":{const n={u_amount:typeof t.value=="number"?t.value/100:0};return{type:"denoise",enabled:t.enabled,uniforms:n}}case"clarity":{const n={u_amount:typeof t.value=="number"?t.value/200:0};return{type:"sharpen",enabled:t.enabled,uniforms:n}}case"vignette":{const n={u_amount:typeof t.value=="number"?t.value/100:0};return{type:"vignette",enabled:t.enabled,uniforms:n}}default:return{type:"brightness-contrast",enabled:!1,uniforms:{}}}})}function $r(s,t){if(t)return"grabbing";switch(s){case"move":return"grab";case"rect-select":case"lasso":case"magic-wand":return"crosshair";case"crop":return"crosshair";case"brush":case"eraser":return"none";case"text":return"text";case"shape":return"crosshair";case"ai-erase":case"ai-expand":return"crosshair";default:return"default"}}function Gr(){const{t:s}=q(),t=i.useRef(null),r=i.useRef(null),n=i.useRef(null),a=i.useRef(null),o=i.useRef(null),g=i.useRef(null),c=i.useRef(0),u=i.useRef(!1),d=i.useRef({x:0,y:0}),w=i.useRef(!1),[k,N]=i.useState(!1),[j,b]=i.useState({x:0,y:0}),[v,y]=i.useState(!1),_=L(A=>A.sourceImage),M=L(A=>A.canvasWidth),l=L(A=>A.canvasHeight),m=L(A=>A.zoom),x=L(A=>A.panX),T=L(A=>A.panY),p=L(A=>A.setZoom),f=L(A=>A.setViewport),C=L(A=>A.fitToWindow),D=L(A=>
575A.layers),E=L(A=>A.activeLayerId),h=L(A=>A.activeTool),R=L(A=>A.selection),S=L(A=>A.undo),W=L(A=>A.redo),F=L(A=>A.pushSnapshot);i.useEffect(()=>{const A=t.current;if(!A)return;try{const Y=new Or(A);Y.init(),a.current=Y,o.current=new Hr(Y)}catch(Y){console.error("[EditorCanvas] Failed to initialize WebGL:",Y),y(!0)}const K=()=>y(!0),V=()=>y(!1);return A.addEventListener("webglcontextlost",K),A.addEventListener("webglcontextrestored",V),()=>{var Y;A.removeEventListener("webglcontextlost",K),A.removeEventListener("webglcontextrestored",V),(Y=a.current)==null||Y.dispose(),a.current=null,o.current=null}},[]),i.useEffect(()=>Xr(S,W),[S,W,F]),i.useEffect(()=>{const A=V=>{V.code==="Space"&&!V.repeat&&(V.preventDefault(),w.current=!0)},K=V=>{V.code==="Space"&&(w.current=!1,u.current&&(u.current=!1,N(!1)))};return window.addEventListener("keydown",A),window.addEventListener("keyup",K),()=>{window.removeEventListener("keydown",A),window.removeEventListener("keyup",K)}},[]),i.useEffect(()=>{if(!_||!a.current)return;const A=new Image;A.crossOrigin="anonymous",A.onload=()=>{g.current=A;const K=a.current;if(K)try{K.setupFramebuffers(A.naturalWidth,A.naturalHeight),K.uploadTexture("source",A);const V=o.current;if(V){const oe=L.getState(),z=oe.layers.find(de=>de.id===oe.activeLayerId),ce=(z==null?void 0:z.adjustments)||[];V.applyLayerAdjustments("source",Je(ce))}const Y=n.current;Y&&C(Y.clientWidth,Y.clientHeight)}catch(V){console.error("[EditorCanvas] Failed to load image into renderer:",V)}},A.onerror=()=>{console.error("[EditorCanvas] Failed to load source image")},A.src=_},[_,C]),i.useEffect(()=>{if(!a.current||!_||!g.current)return;const A=D.find(Y=>Y.id===E),K=(A==null?void 0:A.adjustments)||[],V=o.current;if(V)try{const Y=Je(K);V.applyLayerAdjustments("source",Y)}catch(Y){console.error("[EditorCanvas] Failed to apply adjustments:",Y)}},[D,E,_]);const B=i.useCallback(()=>{const A=r.current,K=n.current;if(!A||!K)return;const V=window.devicePixelRatio||1,Y=K.clientWidth,oe=K.clientHeight;(A.width!==Y*V||A.height!==oe*V)&&(A.width=Y*V,A.height=oe*V,A.style.width=`${Y}px`,A.style.height=`${oe}px`);const z=A.getContext("2d");if(!z||(z.setTransform(V,0,0,V,0,0),z.clearRect(0,0,Y,oe),!_||M===0||l===0))return;const ce=M*m,de=l*m,we=(Y-ce)/2+x,je=(oe-de)/2+T;if(z.strokeStyle="rgba(255, 255, 255, 0.15)",z.lineWidth=1,z.strokeRect(Math.round(we)+.5,Math.round(je)+.5,Math.round(ce),Math.round(de)),R&&(z.save(),z.translate(we,je),z.scale(m,m),z.setLineDash([4,4]),z.lineDashOffset=-(Date.now()/80)%8,z.strokeStyle="rgba(255, 255, 255, 0.8)",z.lineWidth=1/m,z.strokeRect(R.bounds.x,R.bounds.y,R.bounds.width,R.bounds.height),z.lineDashOffset=-(Date.now()/80+4)%8,z.strokeStyle="rgba(0, 0, 0, 0.6)",z.strokeRect(R.bounds.x,R.bounds.y,R.bounds.width,R.bounds.height),z.setLineDash([]),z.restore()),(h==="brush"||h==="eraser")&&j.x>=0&&j.y>=0){const Se=L.getState().toolOptions,Dt=(h==="brush"?Se.brush.size:Se.eraser.size)*m/2;z.beginPath(),z.arc(j.x,j.y,Dt,0,Math.PI*2),z.strokeStyle="rgba(255, 255, 255, 0.7)",z.lineWidth=1,z.stroke(),z.beginPath(),z.moveTo(j.x-4,j.y),z.lineTo(j.x+4,j.y),z.moveTo(j.x,j.y-4),z.lineTo(j.x,j.y+4),z.strokeStyle="rgba(255, 255, 255, 0.5)",z.lineWidth=1,z.stroke()}z.save();const Ee=`${M} x ${l}`,ke=`${Math.round(m*100)}%`;z.font="11px ui-monospace, SFMono-Regular, monospace",z.textAlign="right",z.textBaseline="bottom";const Ce=Math.max(z.measureText(Ee).width,z.measureText(ke).width)+16,Ne=36,Me=Y-12-Ce,Ae=oe-12-Ne;z.fillStyle="rgba(0, 0, 0, 0.6)",z.beginPath(),z.roundRect(Me,Ae,Ce,Ne,6),z.fill(),z.fillStyle="rgba(255, 255, 255, 0.7)",z.fillText(Ee,Y-20,oe-26),z.fillStyle="rgba(255, 255, 255, 0.5)",z.fillText(ke,Y-20,oe-14),z.restore(),R&&(c.current=requestAnimationFrame(B))},[_,M,l,m,x,T,R,h,j]);i.useEffect(()=>(B(),()=>{c.current&&cancelAnimationFrame(c.current)}),[B]),i.useEffect(()=>{const A=n.current;if(!A)return;const K=new ResizeObserver(()=>{B()});return K.observe(A),()=>K.disconnect()},[B]);const O=i.useCallback(A=>{A.preventDefault();const K=n.current;if(!K)return;const Y=A.ctrlKey?.01:.001,oe=-A.deltaY*Y,z=Math.exp(oe),ce=K.getBoundingClientRect(),de=A.clientX-ce.left,we=A.clientY-ce.top,je=K.clientWidth,Ee=K.clientHeight,ke=je/2+x,Ve=Ee/2+T,Ce=de-ke,
575Ne=we-Ve,Me=m*z,Ae=x-Ce*(z-1),Se=T-Ne*(z-1);p(Me),f(Ae,Se)},[m,x,T,p,f]),X=i.useCallback(A=>{(A.button===1||A.button===0&&w.current||A.button===0&&h==="move")&&(A.preventDefault(),u.current=!0,N(!0),d.current={x:A.clientX,y:A.clientY})},[h]),$=i.useCallback(A=>{var V;const K=(V=n.current)==null?void 0:V.getBoundingClientRect();if(K&&b({x:A.clientX-K.left,y:A.clientY-K.top}),u.current){const Y=A.clientX-d.current.x,oe=A.clientY-d.current.y;d.current={x:A.clientX,y:A.clientY},f(x+Y,T+oe)}},[x,T,f]),te=i.useCallback(()=>{u.current&&(u.current=!1,N(!1))},[]);i.useEffect(()=>{const A=()=>{u.current&&(u.current=!1,N(!1))};return window.addEventListener("mouseup",A),()=>window.removeEventListener("mouseup",A)},[]);const J=n.current,re=(J==null?void 0:J.clientWidth)??0,P=(J==null?void 0:J.clientHeight)??0,U=M*m,H=l*m,I=(re-U)/2+x,G=(P-H)/2+T,Q=$r(h,k);return v?e.jsx("div",{ref:n,className:"relative flex-1 overflow-hidden flex items-center justify-center",style:{background:"#1a1a1a"},children:e.jsxs("div",{className:"text-center p-8",children:[e.jsx("p",{className:"text-sm mb-2",style:{color:"var(--text-primary)"},children:s("imageEditor.canvas.contextLost","WebGL context was lost")}),e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:s("imageEditor.canvas.contextLostHint","Try reloading the page. This can happen if GPU resources are exhausted.")})]})}):e.jsxs("div",{ref:n,className:"relative flex-1 overflow-hidden",style:{background:"#1a1a1a",cursor:Q},children:[_&&M>0&&e.jsx("div",{style:{position:"absolute",left:0,top:0,width:`${M}px`,height:`${l}px`,transformOrigin:"0 0",transform:`translate(${I}px, ${G}px) scale(${m})`,backgroundImage:"linear-gradient(45deg, #333 25%, transparent 25%), linear-gradient(-45deg, #333 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #333 75%), linear-gradient(-45deg, transparent 75%, #333 75%)",backgroundSize:"24px 24px",backgroundPosition:"0 0, 0 12px, 12px -12px, -12px 0px",backgroundColor:"#2a2a2a",imageRendering:m>4?"pixelated":"auto",pointerEvents:"none"}}),e.jsx("canvas",{ref:t,style:{position:"absolute",left:0,top:0,width:`${M}px`,height:`${l}px`,transformOrigin:"0 0",transform:`translate(${I}px, ${G}px) scale(${m})`,imageRendering:m>4?"pixelated":"auto",pointerEvents:"none"}}),e.jsx("canvas",{ref:r,className:"absolute inset-0",style:{cursor:Q},onWheel:O,onMouseDown:X,onMouseMove:$,onMouseUp:te,onMouseLeave:()=>b({x:-1,y:-1})}),!_&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center pointer-events-none",children:e.jsx("p",{className:"text-sm",style:{color:"var(--text-secondary)"},children:s("imageEditor.canvas.noImage","No image loaded")})})]})}const Qe=[{value:"png",label:"PNG",extension:".png",mimeType:"image/png"},{value:"jpeg",label:"JPEG",extension:".jpg",mimeType:"image/jpeg"},{value:"webp",label:"WebP",extension:".webp",mimeType:"image/webp"}],Be=["jpeg","webp"];function Yr({open:s,onClose:t,rendererRef:r}){const{t:n}=q(),a=L(h=>h.canvasWidth),o=L(h=>h.canvasHeight),g=L(h=>h.sourceImage),[c,u]=i.useState("png"),[d,w]=i.useState(90),[k,N]=i.useState({width:a,height:o}),[j,b]=i.useState(!0),[v,y]=i.useState(!1),[_,M]=i.useState(null),l=i.useRef(null),m=a>0?a/o:1;i.useEffect(()=>{s&&(N({width:a,height:o}),u("png"),w(90),b(!0))},[s,a,o]),i.useEffect(()=>{if(!s||!g)return;const h=new Image;return h.crossOrigin="anonymous",h.onload=()=>{const S=Math.min(200/h.naturalWidth,200/h.naturalHeight,1),W=Math.round(h.naturalWidth*S),F=Math.round(h.naturalHeight*S),B=document.createElement("canvas");B.width=W,B.height=F;const O=B.getContext("2d");O&&(O.drawImage(h,0,0,W,F),M(B.toDataURL("image/png")))},h.src=g,()=>{_&&URL.revokeObjectURL(_)}},[s,g]),i.useEffect(()=>{if(!s)return;const h=R=>{R.key==="Escape"&&(R.preventDefault(),t())};return window.addEventListener("keydown",h),()=>window.removeEventListener("keydown",h)},[s,t]);const x=i.useCallback(h=>{l.current&&!l.current.contains(h.target)&&t()},[t]),T=i.useCallback(h=>{const R=Math.max(1,parseInt(h.target.value)||1);N(S=>({width:R,height:j?Math.round(R/m):S.height}))},[j,m]),p=i.useCallback(h=>{const R=Math.max(1,parseInt(h.target.value)||1);N(S=>({width:j?Math.round(R*m):S.width,height:R}))},[j,m]),f=i.useCallback(()=>{N({width:a,height:o})},[a,o]),C=i.useMemo(()=>{const h=k.width*k.height;let R;switch(c){case"png":R=2;break;case"jpeg":R=.3+d/100*1.5;break;case"webp":R=.2+d/100*1.2;break;default:R=2}const S=h*R;return S<1024?`${Math.round(S)} B`:S<1024*1024?`${(S/1024).toFixed(1)} KB`:`${(S/(1024*1024)).toFixed(1)} MB`},[c,d,k]),D=i.useCallback(async()=>{y(!0);try{const h=Qe.find(B=>B.value===c);let R=null;const S=r==null?void 0:r.current;if(S&&!S.isContextLost())try{const B=S.readPixels(),O=document.createElement("canvas");O.width=k.width,O.height=k.height;const X=O.getContext("2d");if(X){const $=document.createElement("canvas");$.width=B.width,$.height=B.height;const te=$.getContext("2d");te&&(te.putImageData(B,0,0),X.drawImage($,0,0,k.width,k.height));const J=Be.includes(c)?d/100:void 0;R=await new Promise(re=>{O.toBlob(P=>re(P),h.mimeType,J)})}}catch(B){console.warn("[ExportDialog] Failed to read from renderer, falling back to source image:",B)}if(!R&&g){const B=await Kr(g),O=document.createElement("canvas");O.width=k.width,O.height=k.height;const X=O.getContext("2d");if(X){X.drawImage(B,0,0,k.width,k.height);const $=Be.includes(c)?d/100:void 0;R=await new Promise(te=>{O.toBlob(J=>te(J),h.mimeType,$)})}}if(!R){console.error("[ExportDialog] Failed to generate export blob");return}const W=URL.createObjectURL(R),F=document.createElement("a");F.href=W,F.download=`image_export_${Date.now()}${h.extension}`,document.body.appendChild(F),F.click(),document.body.removeChild(F),setTimeout(()=>URL.revokeObjectURL(W),5e3),t()}catch(h){console.error("[ExportDialog] Export failed:",h)}finally{y(!1)}},[c,d,k,r,g,t]);if(!s)return null;const E=Be.includes(c);return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center",style:{background:"rgba(0, 0, 0, 0.6)",backdropFilter:"blur(4px)"},onClick:x,children:e.jsxs("div",{ref:l,className:"rounded-xl border shadow-2xl w-full max-w-md overflow-hidden",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)"},role:"dialog","aria-modal":"true","aria-label":n("imageEditor.export.title","Export Image"),children:[e.jsxs("div",{className:"flex items-center justify-between px-5 py-4 border-b",style:{borderColor:"var(--border-default)"},children:[e.jsx("h2",{className:"text-base font-semibold",style:{color:"var(--text-primary)"},children:n("imageEditor.export.title","Export Image")}),e.jsx("button",{className:"w-8 h-8 flex items-center justify-center rounded-lg hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},onClick:t,"aria-label":n("common.close","Close"),children:e.jsx(Ye,{size:18})})]}),e.jsxs("div",{className:"p-5 space-y-5",children:[e.jsx("div",{className:"flex justify-center",children:e.jsx("div",{className:"rounded-lg overflow-hidden border flex items-center justify-center",style:{borderColor:"var(--border-default)",background:"#1a1a1a",width:"200px",height:"140px"},children:_?e.jsx("img",{src:_,alt:n("imageEditor.export.preview","Preview"),className:"max-w-full max-h-full object-contain",draggable:!1}):e.jsx(yt,{size:32,style:{color:"var(--text-secondary)",opacity:.3}})})}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium mb-2 block",style:{color:"var(--text-secondary)"},children:n("imageEditor.export.format","Format")}),e.jsx("div",{className:"flex gap-2",children:Qe.map(h=>e.jsx("button",{className:`flex-1 h-9 rounded-lg text-sm font-medium transition-colors border ${c===h.value?"bg-blue-500/20 text-blue-400 border-blue-500/40":"hover:bg-white/5 border-transparent"}`,style:{color:c===h.value?void 0:"var(--text-primary)",borderColor:c===h.value?void 0:"var(--border-default)"},onClick:()=>
575u(h.value),children:h.label},h.value))})]}),E&&e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-xs font-medium",style:{color:"var(--text-secondary)"},children:n("imageEditor.export.quality","Quality")}),e.jsxs("span",{className:"text-xs font-mono",style:{color:"var(--text-primary)"},children:[d,"%"]})]}),e.jsx("input",{type:"range",className:"w-full h-1.5 accent-blue-500 rounded-full",min:1,max:100,value:d,onChange:h=>w(Number(h.target.value))}),e.jsxs("div",{className:"flex justify-between mt-1",children:[e.jsx("span",{className:"text-[10px]",style:{color:"var(--text-secondary)"},children:n("imageEditor.export.smaller","Smaller")}),e.jsx("span",{className:"text-[10px]",style:{color:"var(--text-secondary)"},children:n("imageEditor.export.higher","Higher quality")})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-xs font-medium",style:{color:"var(--text-secondary)"},children:n("imageEditor.export.size","Size")}),e.jsx("button",{className:"text-[10px] hover:underline",style:{color:"var(--text-secondary)"},onClick:f,children:n("imageEditor.export.resetSize","Reset to original")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("label",{className:"text-[10px] mb-0.5 block",style:{color:"var(--text-secondary)"},children:n("imageEditor.export.width","Width")}),e.jsx("input",{type:"number",className:"w-full h-9 px-3 rounded-lg text-sm border outline-none",style:{background:"var(--bg-tertiary)",borderColor:"var(--border-default)",color:"var(--text-primary)"},value:k.width,onChange:T,min:1,max:16384})]}),e.jsx("button",{className:"w-8 h-8 flex items-center justify-center rounded-lg hover:bg-white/10 transition-colors mt-4",style:{color:j?"rgb(96, 165, 250)":"var(--text-secondary)"},onClick:()=>b(!j),title:j?n("imageEditor.export.unlockAspect","Unlock aspect ratio"):n("imageEditor.export.lockAspect","Lock aspect ratio"),children:j?e.jsx(bt,{size:14}):e.jsx(kt,{size:14})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("label",{className:"text-[10px] mb-0.5 block",style:{color:"var(--text-secondary)"},children:n("imageEditor.export.height","Height")}),e.jsx("input",{type:"number",className:"w-full h-9 px-3 rounded-lg text-sm border outline-none",style:{background:"var(--bg-tertiary)",borderColor:"var(--border-default)",color:"var(--text-primary)"},value:k.height,onChange:p,min:1,max:16384})]})]})]}),e.jsxs("div",{className:"flex items-center justify-between px-3 py-2 rounded-lg text-xs",style:{background:"var(--bg-tertiary)",color:"var(--text-secondary)"},children:[e.jsx("span",{children:n("imageEditor.export.estimatedSize","Estimated size")}),e.jsxs("span",{className:"font-mono",style:{color:"var(--text-primary)"},children:["~",C]})]})]}),e.jsxs("div",{className:"flex items-center justify-end gap-3 px-5 py-4 border-t",style:{borderColor:"var(--border-default)"},children:[e.jsx("button",{className:"h-9 px-4 rounded-lg text-sm hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},onClick:t,disabled:v,children:n("common.cancel","Cancel")}),e.jsx("button",{className:"h-9 px-5 rounded-lg text-sm font-medium bg-blue-500 hover:bg-blue-600 text-white transition-colors flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed",onClick:D,disabled:v||!g,children:v?e.jsxs(e.Fragment,{children:[e.jsx(pe,{size:14,className:"animate-spin"}),n("imageEditor.export.exporting","Exporting...")]}):e.jsxs(e.Fragment,{children:[e.jsx(gt,{size:14}),n("imageEditor.export.download","Download")]})})]})]})})}function Kr(s){return new Promise((t,r)=>{const n=new Image;n.crossOrigin="anonymous",n.onload=()=>t(n),n.onerror=a=>r(a),n.src=s})}const ne=280,ie=80,_e=20,ue=12,Vr={inputBlack:0,inputWhite:255,gamma:1,outputBlack:0,outputWhite:255};function qr(s){return new Promise(t=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{const n=document.createElement("canvas"),a=n.getContext("2d");if(!a){t(new Array(256).fill(0));return}const g=Math.min(1,512/Math.max(r.width,r.height));n.width=Math.round(r.width*g),n.height=Math.round(r.height*g),a.drawImage(r,0,0,n.width,n.height);const u=a.getImageData(0,0,n.width,n.height).data,d=new Array(256).fill(0);for(let w=0;w<u.length;w+=4){const k=Math.round(.299*u[w]+.587*u[w+1]+.114*u[w+2]);d[k]++}
575t(d)},r.onerror=()=>t(new Array(256).fill(0)),r.src=s})}function Zr(){const{t:s}=q(),t=L(l=>l.sourceImage),r=L(l=>l.layers),n=L(l=>l.activeLayerId),a=L(l=>l.updateLayer),o=L(l=>l.pushSnapshot),g=r.find(l=>l.id===n),c=(g==null?void 0:g.adjustments)||[],u=i.useRef(null),d=i.useRef(null),[w,k]=i.useState(new Array(256).fill(0)),[N,j]=i.useState(null),b=i.useMemo(()=>{const l=c.find(m=>m.type==="levels");return(l==null?void 0:l.levelsConfig)||{...Vr}},[c]);i.useEffect(()=>{t&&qr(t).then(k)},[t]),i.useEffect(()=>{const l=u.current;if(!l)return;const m=l.getContext("2d");if(!m)return;m.clearRect(0,0,ne,ie);const x=Math.max(...w,1);m.fillStyle="rgba(200, 200, 200, 0.3)",m.beginPath(),m.moveTo(0,ie);for(let T=0;T<256;T++){const p=T/255*ne,f=w[T]/x*ie;m.lineTo(p,ie-f)}m.lineTo(ne,ie),m.closePath(),m.fill(),m.strokeStyle="rgba(200, 200, 200, 0.5)",m.lineWidth=.5,m.beginPath();for(let T=0;T<256;T++){const p=T/255*ne,f=w[T]/x*ie;T===0?m.moveTo(p,ie-f):m.lineTo(p,ie-f)}m.stroke()},[w]),i.useEffect(()=>{const l=d.current;if(!l)return;const m=l.getContext("2d");if(!m)return;const x=ue+_e;m.clearRect(0,0,ne,x);const T=m.createLinearGradient(0,0,ne,0);T.addColorStop(0,"#000000"),T.addColorStop(1,"#ffffff"),m.fillStyle=T,m.fillRect(0,0,ne,ue);const p=b.inputBlack/255*ne,f=b.inputWhite/255*ne;m.fillStyle="rgba(59, 130, 246, 0.15)",m.fillRect(p,0,f-p,ue);const C=ue+2,D=_e-4;We(m,p,C,D,"#333333","#ffffff"),We(m,f,C,D,"#ffffff","#333333");const E=Math.pow(.5,b.gamma),h=p+E*(f-p);We(m,h,C,D,"#888888","#ffffff")},[b]);const v=i.useCallback(l=>{if(!n)return;o(s("imageEditor.adjust.levels"));const m={...b,...l},x=c.find(p=>p.type==="levels");let T;x?T=c.map(p=>p.type==="levels"?{...p,value:1,levelsConfig:m}:p):T=[...c,{type:"levels",value:1,enabled:!0,levelsConfig:m}],a(n,{adjustments:T})},[n,c,b,o,a,s]),y=i.useCallback(()=>{if(!n)return;o(s("imageEditor.adjust.reset"));const l=c.filter(m=>m.type!=="levels");a(n,{adjustments:l})},[n,c,o,a,s]),_=b.inputBlack!==0||b.inputWhite!==255||b.gamma!==1||b.outputBlack!==0||b.outputWhite!==255,M=i.useCallback(l=>{const m=d.current;if(!m)return;const x=m.getBoundingClientRect(),T=l.clientX-x.left,p=b.inputBlack/255*ne,f=b.inputWhite/255*ne,C=Math.pow(.5,b.gamma),D=p+C*(f-p),E=10,h=Math.abs(T-p),R=Math.abs(T-f),S=Math.abs(T-D),W=Math.min(h,R,S);W>E||j(W===h?"inputBlack":W===R?"inputWhite":"gamma")},[b]);return i.useEffect(()=>{if(!N)return;const l=x=>{const T=d.current;if(!T)return;const p=T.getBoundingClientRect(),f=Math.max(0,Math.min(ne,x.clientX-p.left)),C=Math.round(f/ne*255);if(N==="inputBlack")v({inputBlack:Math.min(C,b.inputWhite-2)});else if(N==="inputWhite")v({inputWhite:Math.max(C,b.inputBlack+2)});else if(N==="gamma"){const D=b.inputBlack/255*ne,h=b.inputWhite/255*ne-D;if(h<=0)return;const R=Math.max(.01,Math.min(.99,(f-D)/h)),S=Math.max(.1,Math.min(10,Math.log(R)/Math.log(.5)));v({gamma:Math.round(S*100)/100})}},m=()=>j(null);return window.addEventListener("mousemove",l),window.addEventListener("mouseup",m),()=>{window.removeEventListener("mousemove",l),window.removeEventListener("mouseup",m)}},[N,b,v]),e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-xs font-medium",style:{color:"var(--text-primary)"},children:s("imageEditor.adjust.levels")}),e.jsx("button",{className:`p-1 rounded transition-colors ${_?"hover:bg-white/10 cursor-pointer":"opacity-30 cursor-not-allowed"}`,onClick:y,disabled:!_,title:s("imageEditor.adjust.reset"),children:e.jsx(Ke,{size:12,style:{color:"var(--text-secondary)"}})})]}),e.jsx("div",{className:"rounded overflow-hidden mb-1",style:{background:"rgba(0,0,0,0.3)",border:"1px solid rgba(255,255,255,0.08)"},children:e.jsx("canvas",{ref:u,width:ne,height:ie,className:"block w-full",style:{height:`${ie}px`}})}),e.jsx("canvas",{ref:d,width:ne,height:ue+_e,className:"block w-full cursor-pointer mb-2",style:{height:`${ue+_e}px`},onMouseDown:M}),e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx(Ue,{label:s("imageEditor.adjust.inputBlack"),value:b.inputBlack,min:0,max:253,onChange:l=>v({inputBlack:Math.min(l,b.inputWhite-2)})}),e.jsx(Ue,{label:s("imageEditor.adjust.gamma"),value:b.gamma,min:.1,max:10,step:.
57501,onChange:l=>v({gamma:l})}),e.jsx(Ue,{label:s("imageEditor.adjust.inputWhite"),value:b.inputWhite,min:2,max:255,onChange:l=>v({inputWhite:Math.max(l,b.inputBlack+2)})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[10px] shrink-0",style:{color:"var(--text-secondary)"},children:s("imageEditor.adjust.outputBlack")}),e.jsx("input",{type:"range",min:0,max:255,value:b.outputBlack,onChange:l=>v({outputBlack:Math.min(Number(l.target.value),b.outputWhite-1)}),className:"adjust-slider flex-1",style:{"--slider-fill":`linear-gradient(to right,
576              #3b82f6 0%,
577              #3b82f6 ${b.outputBlack/255*100}%,
578              rgba(255,255,255,0.08) ${b.outputBlack/255*100}%,
579              rgba(255,255,255,0.08) 100%)`}}),e.jsx("span",{className:"text-[10px] font-mono tabular-nums w-6 text-right",style:{color:"var(--text-secondary)"},children:b.outputBlack})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[e.jsx("span",{className:"text-[10px] shrink-0",style:{color:"var(--text-secondary)"},children:s("imageEditor.adjust.outputWhite")}),e.jsx("input",{type:"range",min:0,max:255,value:b.outputWhite,onChange:l=>v({outputWhite:Math.max(Number(l.target.value),b.outputBlack+1)}),className:"adjust-slider flex-1",style:{"--slider-fill":`linear-gradient(to right,
580              #3b82f6 0%,
581              #3b82f6 ${b.outputWhite/255*100}%,
582              rgba(255,255,255,0.08) ${b.outputWhite/255*100}%,
583              rgba(255,255,255,0.08) 100%)`}}),e.jsx("span",{className:"text-[10px] font-mono tabular-nums w-6 text-right",style:{color:"var(--text-secondary)"},children:b.outputWhite})]})]})}function Ue({label:s,value:t,min:r,max:n,step:a=1,onChange:o}){return e.jsxs("div",{className:"flex flex-col items-center gap-0.5",children:[e.jsx("span",{className:"text-[10px]",style:{color:"var(--text-secondary)"},children:s}),e.jsx("input",{type:"number",min:r,max:n,step:a,value:a<1?t.toFixed(2):t,onChange:g=>{const c=Number(g.target.value);!isNaN(c)&&c>=r&&c<=n&&o(c)},className:"w-14 h-6 text-center text-xs rounded bg-white/5 border border-white/10 outline-none focus:border-blue-500 tabular-nums",style:{color:"var(--text-primary)"}})]})}function We(s,t,r,n,a,o){s.beginPath(),s.moveTo(t,r),s.lineTo(t-6,r+n),s.lineTo(t+6,r+n),s.closePath(),s.fillStyle=a,s.fill(),s.strokeStyle=o,s.lineWidth=1,s.stroke()}const se=280,ee=200,Le=4,Jr=5,et=10,Qr=10,xe={rgb:"#ffffff",r:"#ef4444",g:"#22c55e",b:"#3b82f6"},en={rgb:"rgba(255,255,255,0.15)",r:"rgba(239,68,68,0.15)",g:"rgba(34,197,94,0.15)",b:"rgba(59,130,246,0.15)"},ze=["rgb","r","g","b"],Re=[{x:0,y:0},{x:255,y:255}];function tt(s){if(s.length<2)return d=>d;const t=[...s].sort((d,w)=>d.x-w.x),r=t.length,n=t.map(d=>d.x),a=t.map(d=>d.y);if(r===2){const d=(a[1]-a[0])/(n[1]-n[0]||1);return w=>w<=n[0]?a[0]:w>=n[r-1]?a[r-1]:a[0]+d*(w-n[0])}const o=[],g=[],c=[];for(let d=0;d<r-1;d++)o.push(n[d+1]-n[d]),g.push(a[d+1]-a[d]),c.push(g[d]/(o[d]||1));const u=[c[0]];for(let d=1;d<r-1;d++)c[d-1]*c[d]<=0?u.push(0):u.push(3*(o[d-1]+o[d])/((2*o[d]+o[d-1])/c[d-1]+(o[d]+2*o[d-1])/c[d]));return u.push(c[r-2]),d=>{if(d<=n[0])return a[0];if(d>=n[r-1])return a[r-1];let w=0,k=r-1;for(;w<k-1;){const T=Math.floor((w+k)/2);n[T]<=d?w=T:k=T}const N=w,j=o[N];if(j===0)return a[N];const b=(d-n[N])/j,v=b*b,y=v*b,_=2*y-3*v+1,M=y-2*v+b,l=-2*y+3*v,m=y-v,x=_*a[N]+M*j*u[N]+l*a[N+1]+m*j*u[N+1];return Math.max(0,Math.min(255,x))}}function tn(s){return new Promise(t=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{const n=document.createElement("canvas"),a=n.getContext("2d");if(!a){t(new Array(256).fill(0));return}const g=Math.min(1,512/Math.max(r.width,r.height));n.width=Math.round(r.width*g),n.height=Math.round(r.height*g),a.drawImage(r,0,0,n.width,n.height);const u=a.getImageData(0,0,n.width,n.height).data,d=new Array(256).fill(0);for(let w=0;w<u.length;w+=4){const k=Math.round(.299*u[w]+.587*u[w+1]+.114*u[w+2]);d[k]++}t(d)},r.onerror=()=>t(new Array(256).fill(0)),r.src=s})}function rn(){const{t:s}=q(),t=L(E=>E.sourceImage),r=L(E=>E.layers),n=L(E=>E.activeLayerId),a=L(E=>E.updateLayer),o=L(E=>E.pushSnapshot),g=r.find(E=>E.id===n),c=(g==null?void 0:g.adjustments)||[],u=i.useRef(null),[d,w]=i.useState("rgb"),[k,N]=i.useState(null),[j,b]=i.useState(new Array(256).fill(0)),v=i.useMemo(()=>{const E=c.find(R=>
583R.type==="curves"),h=E==null?void 0:E.curvePoints;return{rgb:(h==null?void 0:h.rgb)||[...Re],r:(h==null?void 0:h.r)||[...Re],g:(h==null?void 0:h.g)||[...Re],b:(h==null?void 0:h.b)||[...Re]}},[c]),y=v[d];i.useEffect(()=>{t&&tn(t).then(b)},[t]);const _=i.useCallback(E=>E/255*se,[]),M=i.useCallback(E=>ee-E/255*ee,[]),l=i.useCallback(E=>Math.round(Math.max(0,Math.min(255,E/se*255))),[]),m=i.useCallback(E=>Math.round(Math.max(0,Math.min(255,(ee-E)/ee*255))),[]),x=i.useCallback((E,h)=>{if(!n)return;o(s("imageEditor.adjust.curves"));const R={...v,[E]:[...h].sort((F,B)=>F.x-B.x)},S=c.find(F=>F.type==="curves");let W;S?W=c.map(F=>F.type==="curves"?{...F,value:1,curvePoints:R}:F):W=[...c,{type:"curves",value:1,enabled:!0,curvePoints:R}],a(n,{adjustments:W})},[n,c,v,o,a,s]),T=i.useCallback(()=>{if(!n)return;o(s("imageEditor.adjust.reset"));const E=c.filter(h=>h.type!=="curves");a(n,{adjustments:E})},[n,c,o,a,s]);i.useEffect(()=>{const E=u.current;if(!E)return;const h=E.getContext("2d");if(!h)return;h.clearRect(0,0,se,ee),h.fillStyle="rgba(0, 0, 0, 0.4)",h.fillRect(0,0,se,ee);const R=Math.max(...j,1);h.fillStyle="rgba(255, 255, 255, 0.04)",h.beginPath(),h.moveTo(0,ee);for(let F=0;F<256;F++){const B=F/255*se,O=j[F]/R*ee;h.lineTo(B,ee-O)}h.lineTo(se,ee),h.closePath(),h.fill(),h.strokeStyle="rgba(255, 255, 255, 0.08)",h.lineWidth=1;for(let F=1;F<Le;F++){const B=F/Le*se;h.beginPath(),h.moveTo(B,0),h.lineTo(B,ee),h.stroke(),h.beginPath(),h.moveTo(0,B*(ee/se)),h.lineTo(se,B*(ee/se)),h.stroke()}for(let F=1;F<Le;F++){const B=F/Le*ee;h.beginPath(),h.moveTo(0,B),h.lineTo(se,B),h.stroke()}h.strokeStyle="rgba(255, 255, 255, 0.15)",h.lineWidth=1,h.setLineDash([4,4]),h.beginPath(),h.moveTo(0,ee),h.lineTo(se,0),h.stroke(),h.setLineDash([]);for(const F of ze){if(F===d)continue;const B=v[F];if(!B||B.length<2||B.length===2&&B[0].x===0&&B[0].y===0&&B[1].x===255&&B[1].y===255)continue;const X=tt(B);h.strokeStyle=en[F],h.lineWidth=1.5,h.beginPath();for(let $=0;$<=255;$++){const te=_($),J=M(X($));$===0?h.moveTo(te,J):h.lineTo(te,J)}h.stroke()}const S=tt(y);h.strokeStyle=xe[d],h.lineWidth=2,h.beginPath();for(let F=0;F<=255;F++){const B=_(F),O=M(S(F));F===0?h.moveTo(B,O):h.lineTo(B,O)}h.stroke();const W=[...y].sort((F,B)=>F.x-B.x);for(let F=0;F<W.length;F++){const B=W[F],O=_(B.x),X=M(B.y);h.beginPath(),h.arc(O,X,Jr,0,Math.PI*2),h.fillStyle=F===k?xe[d]:"rgba(0,0,0,0.6)",h.fill(),h.strokeStyle=xe[d],h.lineWidth=2,h.stroke()}},[d,y,v,k,j,_,M]);const p=i.useCallback(E=>{const h=u.current;if(!h)return;const R=h.getBoundingClientRect(),S=se/R.width,W=ee/R.height,F=(E.clientX-R.left)*S,B=(E.clientY-R.top)*W,O=[...y].sort((P,U)=>P.x-U.x);for(let P=0;P<O.length;P++){const U=_(O[P].x),H=M(O[P].y);if(Math.sqrt((F-U)**2+(B-H)**2)<=et){N(P);return}}if(O.length>=Qr)return;const X=l(F),$=m(B);if(O.some(P=>Math.abs(P.x-X)<5))return;const J=[...O,{x:X,y:$}].sort((P,U)=>P.x-U.x),re=J.findIndex(P=>P.x===X&&P.y===$);x(d,J),N(re)},[d,y,l,m,_,M,x]),f=i.useCallback(E=>{const h=u.current;if(!h)return;const R=h.getBoundingClientRect(),S=se/R.width,W=ee/R.height,F=(E.clientX-R.left)*S,B=(E.clientY-R.top)*W,O=[...y].sort((X,$)=>X.x-$.x);for(let X=0;X<O.length;X++){const $=_(O[X].x),te=M(O[X].y);if(Math.sqrt((F-$)**2+(B-te)**2)<=et){if(X===0||X===O.length-1)return;const re=O.filter((P,U)=>U!==X);x(d,re),N(null);return}}},[d,y,_,M,x]);i.useEffect(()=>{if(k===null)return;const E=R=>{const S=u.current;if(!S)return;const W=S.getBoundingClientRect(),F=se/W.width,B=ee/W.height,O=(R.clientX-W.left)*F,X=(R.clientY-W.top)*B,$=[...y].sort((H,I)=>H.x-I.x);if(k<0||k>=$.length)return;const te=k===0,J=k===$.length-1;let re=l(O);const P=m(X);if(te)re=0;else if(J)re=255;else{const H=$[k-1].x,I=$[k+1].x;re=Math.max(H+1,Math.min(I-1,re))}const U=$.map((H,I)=>I===k?{x:re,y:P}:H);x(d,U)},h=()=>N(null);return window.addEventListener("mousemove",E),window.addEventListener("mouseup",h),()=>{window.removeEventListener("mousemove",E),window.removeEventListener("mouseup",h)}},[k,d,y,l,m,x]);const C=i.useMemo(()=>ze.some(E=>{const h=v[E];return h.length!==2||h[0].x!==0||h[0].y!==0||h[1].x!==255||h[1].y!==255}),[v]),D={rgb:s("imageEditor.adjust.channelRGB"),r:s("imageEditor.adjust.channelR"),g:s("imageEditor.adjust.channelG"),b:s("imageEditor.adjust.channelB")};return e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-xs font-medium",style:{color:"var(--text-primary)"},children:s("imageEditor.adjust.curves")}),e.jsx("button",{className:`p-1 rounded transition-colors ${C?"hover:bg-white/10 cursor-pointer":"opacity-30 curs
583or-not-allowed"}`,onClick:T,disabled:!C,title:s("imageEditor.adjust.reset"),children:e.jsx(Ke,{size:12,style:{color:"var(--text-secondary)"}})})]}),e.jsx("div",{className:"flex gap-1 mb-2",children:ze.map(E=>e.jsx("button",{className:`flex-1 h-6 text-[10px] font-medium rounded transition-colors ${d===E?"bg-white/15":"bg-white/5 hover:bg-white/10"}`,style:{color:d===E?xe[E]:"var(--text-secondary)",borderBottom:d===E?`2px solid ${xe[E]}`:"2px solid transparent"},onClick:()=>w(E),children:D[E]},E))}),e.jsx("div",{className:"rounded overflow-hidden cursor-crosshair",style:{border:"1px solid rgba(255,255,255,0.08)"},title:k!==null?void 0:s("imageEditor.adjust.addPoint"),children:e.jsx("canvas",{ref:u,width:se,height:ee,className:"block w-full",style:{height:`${ee}px`},onMouseDown:p,onDoubleClick:f})}),e.jsxs("div",{className:"mt-1.5 flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px]",style:{color:"var(--text-secondary)",opacity:.6},children:s("imageEditor.adjust.addPoint")}),e.jsx("span",{className:"text-[10px]",style:{color:"var(--text-secondary)",opacity:.6},children:s("imageEditor.adjust.removePoint")})]})]})}const nn=[{titleKey:"imageEditor.adjust.sections.basic",sliders:[{type:"brightness",labelKey:"imageEditor.adjust.brightness",min:-100,max:100,bipolar:!0},{type:"contrast",labelKey:"imageEditor.adjust.contrast",min:-100,max:100,bipolar:!0},{type:"exposure",labelKey:"imageEditor.adjust.exposure",min:-100,max:100,bipolar:!0}]},{titleKey:"imageEditor.adjust.sections.light",sliders:[{type:"highlights",labelKey:"imageEditor.adjust.highlights",min:-100,max:100,bipolar:!0},{type:"shadows",labelKey:"imageEditor.adjust.shadows",min:-100,max:100,bipolar:!0}]},{titleKey:"imageEditor.adjust.sections.color",sliders:[{type:"saturation",labelKey:"imageEditor.adjust.saturation",min:-100,max:100,bipolar:!0},{type:"vibrance",labelKey:"imageEditor.adjust.vibrance",min:-100,max:100,bipolar:!0},{type:"temperature",labelKey:"imageEditor.adjust.temperature",min:-100,max:100,bipolar:!0},{type:"tint",labelKey:"imageEditor.adjust.tint",min:-100,max:100,bipolar:!0}]},{titleKey:"imageEditor.adjust.sections.detail",sliders:[{type:"sharpen",labelKey:"imageEditor.adjust.sharpen",min:0,max:100,bipolar:!1},{type:"denoise",labelKey:"imageEditor.adjust.denoise",min:0,max:100,bipolar:!1},{type:"clarity",labelKey:"imageEditor.adjust.clarity",min:-100,max:100,bipolar:!0},{type:"vignette",labelKey:"imageEditor.adjust.vignette",min:0,max:100,bipolar:!1}]}];function an({config:s,value:t,onChange:r,onReset:n}){const{t:a}=q(),o=i.useRef(0),g=i.useCallback(k=>{const N=Number(k.target.value);o.current&&cancelAnimationFrame(o.current),o.current=requestAnimationFrame(()=>{r(N)})},[r]),c=k=>k>0?`+${k}`:String(k),u=s.max-s.min,d=(t-s.min)/u*100;let w;return s.bipolar?t>=0?w=`linear-gradient(to right,
584        rgba(255,255,255,0.08) 0%,
585        rgba(255,255,255,0.08) 50%,
586        #3b82f6 50%,
587        #3b82f6 ${d}%,
588        rgba(255,255,255,0.08) ${d}%,
589        rgba(255,255,255,0.08) 100%)`:w=`linear-gradient(to right,
590        rgba(255,255,255,0.08) 0%,
591        rgba(255,255,255,0.08) ${d}%,
592        #3b82f6 ${d}%,
593        #3b82f6 50%,
594        rgba(255,255,255,0.08) 50%,
595        rgba(255,255,255,0.08) 100%)`:w=`linear-gradient(to right,
596      #3b82f6 0%,
597      #3b82f6 ${d}%,
598      rgba(255,255,255,0.08) ${d}%,
599      rgba(255,255,255,0.08) 100%)`,e.jsxs("div",{className:"mb-3 last:mb-0",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsx("span",{className:"text-xs select-none cursor-pointer hover:text-blue-400 transition-colors",style:{color:"var(--text-secondary)"},onDoubleClick:n,title:a("imageEditor.adjust.doubleClickReset"),children:a(s.labelKey)}),e.jsx("span",{className:"text-xs font-mono tabular-nums min-w-[36px] text-right",style:{color:t!==0?"#3b82f6":"var(--text-secondary)"},children:c(t)})]}),e.jsxs("div",{className:"relative h-5 flex items-center",children:[s.bipolar&&e.jsx("div",{className:"absolute top-1/2 -translate-y-1/2 w-px h-2.5 z-10 pointer-events-none",style:{left:"50%",background:"rgba(255,255,255,0.25)"}}),e.jsx("input",{type:"range",min:s.min,max:s.max,value:t,onChange:g,className:"adjust-slider w-full",style:{"--slider-fill":w}
599})]})]})}function rt({titleKey:s,children:t,defaultOpen:r=!0}){const{t:n}=q(),[a,o]=i.useState(r);return e.jsxs("div",{className:"mb-1",children:[e.jsxs("button",{className:"w-full flex items-center justify-between py-2 px-1 rounded hover:bg-white/5 transition-colors",onClick:()=>o(!a),children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wider",style:{color:"var(--text-primary)"},children:n(s)}),e.jsx(ut,{size:14,className:`transition-transform duration-200 ${a?"rotate-0":"-rotate-90"}`,style:{color:"var(--text-secondary)"}})]}),a&&e.jsx("div",{className:"px-1 pb-2",children:t})]})}function sn(){const{t:s}=q(),t=L(j=>j.layers),r=L(j=>j.activeLayerId),n=L(j=>j.updateLayer),a=L(j=>j.pushSnapshot),o=L(j=>j.sourceImage),g=t.find(j=>j.id===r),c=(g==null?void 0:g.adjustments)||[],u=i.useCallback(j=>{const b=c.find(v=>v.type===j);return(b==null?void 0:b.value)||0},[c]),d=i.useCallback((j,b)=>{if(!r)return;a(s(`imageEditor.adjust.${j}`));const v=c.find(_=>_.type===j);let y;v?y=c.map(_=>_.type===j?{..._,value:b}:_):y=[...c,{type:j,value:b,enabled:!0}],n(r,{adjustments:y})},[r,c,a,n,s]),w=i.useCallback(j=>{if(!r)return;a(s("imageEditor.adjust.reset"));const b=c.filter(v=>v.type!==j);n(r,{adjustments:b})},[r,c,a,n,s]),k=i.useCallback(()=>{r&&(a(s("imageEditor.adjust.resetAll")),n(r,{adjustments:[]}))},[r,a,n,s]),N=c.length>0&&c.some(j=>j.value!==0);return!o||!g?e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center gap-3 p-6 text-center",children:[e.jsx(Ct,{size:32,style:{color:"var(--text-secondary)"}}),e.jsx("p",{className:"text-sm",style:{color:"var(--text-secondary)"},children:s("imageEditor.adjust.noImage")})]}):e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("style",{children:`
600        .adjust-slider {
601          -webkit-appearance: none;
602          appearance: none;
603          height: 4px;
604          border-radius: 2px;
605          background: var(--slider-fill);
606          outline: none;
607          cursor: pointer;
608        }
609        .adjust-slider::-webkit-slider-thumb {
610          -webkit-appearance: none;
611          appearance: none;
612          width: 14px;
613          height: 14px;
614          border-radius: 50%;
615          background: #ffffff;
616          border: 2px solid #3b82f6;
617          cursor: pointer;
618          box-shadow: 0 1px 3px rgba(0,0,0,0.3);
619          transition: transform 0.1s ease, box-shadow 0.1s ease;
620        }
621        .adjust-slider::-webkit-slider-thumb:hover {
622          transform: scale(1.15);
623          box-shadow: 0 1px 6px rgba(59,130,246,0.4);
624        }
625        .adjust-slider::-webkit-slider-thumb:active {
626          transform: scale(1.05);
627        }
628        .adjust-slider::-moz-range-thumb {
629          width: 14px;
630          height: 14px;
631          border-radius: 50%;
632          background: #ffffff;
633          border: 2px solid #3b82f6;
634          cursor: pointer;
635          box-shadow: 0 1px 3px rgba(0,0,0,0.3);
636        }
637        .adjust-slider::-moz-range-track {
638          height: 4px;
639          border-radius: 2px;
640          background: var(--slider-fill);
641        }
642      `}),e.jsxs("div",{className:"flex-1 overflow-y-auto px-3 py-2 custom-scrollbar",children:[nn.map((j,b)=>e.jsx(rt,{titleKey:j.titleKey,defaultOpen:b<2,children:j.sliders.map(v=>e.jsx(an,{config:v,value:u(v.type),onChange:y=>d(v.type,y),onReset:()=>w(v.type)},v.type))},j.titleKey)),o&&e.jsxs(rt,{titleKey:"imageEditor.adjust.sections.advanced",defaultOpen:!1,children:[e.jsx(Zr,{}),e.jsx(rn,{})]})]}),e.jsx("div",{className:"shrink-0 p-3 border-t",style:{borderColor:"var(--border-default)"},children:e.jsxs("button",{className:`w-full h-8 flex items-center justify-center gap-2 rounded-lg text-xs font-medium transition-colors ${N?"bg-white/5 hover:bg-white/10 cursor-pointer":"opacity-40 cursor-not-allowed"}`,style:{color:"var(--text-secondary)"},onClick:k,disabled:!N,children:[e.jsx(Ke,{size:14}),s("imageEditor.adjust.resetAll")]})})]})}const nt=[{id:"none",nameKey:"imageEditor.filters.names.none",category:"classic",adjustments:[]},{id:"blackWhite",nameKey:"imageEditor.filters.names.blackWhite",category:"classic",adjustments:[{type:"saturation",value:-100,enabled:!0},{type:"contrast",value:10,enabled:!0}]},{id:"vintage",nameKey:"imageEditor.filters.names.vintage",category:"classic",adjustments:[{type:"saturation",value:-30,enabled:!0},{type:"temperature",value:20,enabled:!0},{type:"contrast",value:-10,enabled:!0},{type:"vignette",value:30,enabled:!0}]},{id:"film",nameKey:"imageEditor.filters.names.film",category:"classic",adjustments:[{type:"saturation",value:-20,enabled:!0},{type:"temperature",value:-10,enabled:!0},{type:"contrast",value:-15,enabled:!0},{type:"highlights",value:-20,enabled:!0},{type:"vignette",value:20,enabled:!0}]},{id:"faded",nameKey:"imageEditor.filters.names.faded",category:"classic",adjustments:[{type:"contrast",value:-25,enabled:!0},{type:"shadows",value:30,enabled:!0},{type:"saturation",value:-15,enabled:!0},{type:"brightness",value:10,enabled:!0}]},{id:"crossProcess",nameKey:"imageEditor.filters.names.crossProcess",category:"classic",adjustments:[{type:"saturation",value:40,enabled:!0},{type:"tint",value:25,enabled:!0},{type:"contrast",value:15,enabled:!0},{type:"temperature",value:-15,enabled:!0}]},{id:"vivid",nameKey:"imageEditor.filters.names.vivid",category:"landscape",adjustments:[{type:"saturation",value:35,enabled:!0},{type:"contrast",value:20,enabled:!0},{type:"vibrance",value:25,enabled:!0},{type:"clarity",value:15,enabled:!0}]},{id:"autumn",nameKey:"imageEditor.filters.names.autumn",category:"landscape",adjustments:[{type:"temperature",value:35,enabled:!0},{type:"saturation",value:20,enabled:!0},{type:"vibrance",value:15,enabled:!0},{type:"shadows",value:-10,enabled:!0}]},{id:"sunset",nameKey:"imageEditor.filters.names.sunset",category:"landscape",adjustments:[{type:"temperature",value:40,enabled:!0},{type:"tint",value:15,enabled:!0},{type:"exposure",value:10,enabled:!0},{type:"vibrance",value:20,enabled:!0},{type:"highlights",value:15,enabled:!0}]},{id:"winterMorning",nameKey:"imageEditor.filters.names.winterMorning",category:"landscape",adjustments:[{type:"temperature",value:-30,enabled:!0},{type:"tint",value:-10,enabled:!0},{type:"brightness",value:10,enabled:!0},{type:"contrast",value:-5,enabled:!0},{type:"saturation",value:-15,enabled:!0}]},{id:"brighten",nameKey:"imageEditor.filters.names.brighten",category:"portrait",adjustments:[{type:"exposure",value:20,enabled:!0},{type:"highlights",value:15,enabled:!0},{type:"shadows",value:10,enabled:!0},{type:"contrast",value:-5,enabled:!0}]},{id:"warmTone",nameKey:"imageEditor.filters.names.warmTone",category:"portrait",adjustments:[{type:"temperature",value:25,enabled:!0},{type:"tint",value:10,enabled:!0},{type:"vibrance",value:10,enabled:!0}]},{id:"coolTone",nameKey:"imageEditor.filters.names.coolTone",category:"portrait",adjustments:[{type:"temperature",value:-25,enabled:!0},{type:"tint",value:-10,enabled:!0},{type:"vibrance",value:10,enabled:!0}]},{id:"softLight",nameKey:"imageEditor.filters.names.softLight",category:"portrait",adjustments:[{type:"contrast",value:-20,enabled:!0},{type:"temperature",value:10,enabled:!0},{type:"highlights",value:20,enabled:!0},{type:"shadows",value:15,enabled:!0},{type:"clarity",value:-15,enabled:!0}]},{id:"warmYellow",nameKey:"imageEditor.filters.names.warmYellow",category:"food",adjustments:[{type:"temperature",value:45,enabled:!0},{type:"saturation",value:15,enabled:!0},{type:"brightness",value:10,enabled:!0},{type:"contrast",value:5,enabled:!0}]},{id:"fresh",nameKey:"imageEditor.filters.names.fresh",category:"food",adjustments:[{type:"temperature",value:-10,enabled:!0},{type:"vibrance",value:30,enabled:!0},{type:"saturation",value:10,enabled:!0},{type:"brightness",value:5,enabled:!0},{type:"clarity",value:10,enabled:!0}]},{id:"retroDiner",nameKey:"imageEditor.filters.names.retroDiner",category:"food",adjustments:[{type:"saturation",value:25,enabled:!0},{type:"temperature",value:20,enabled:!0},{type:"contrast",value:10,enabled:!0},{type:"vignette",value:25,enabled:!0}]},{id:"oilPainting",nameKey:"imageEditor.filters.names.oilPainting",category:"artistic",adjustments:[{type:"clarity",value:60,enabled:!0},{type:"saturation",value:30,enabled:!0},{type:"contrast",value:10,enabled:!0},{type:"vibrance",value:20,enabled:!0}]},{id:"sketch",nameKey:"imageEditor.filters.names.sketch",category:"artistic",adjustments:[{type:"saturation",value:-80,enabled:!0},{type:"contrast",value:50,enabled:!0},{type:"sharpen",value:70,enabled:!0},{type:"clarity",value:40,enabled:!0}]},{id:"watercolor",nameKey:"imageEditor.filters.names.watercolor",category:"artistic",adjustments:[{type:"clarity",value:-40,enabled:!0},{type:"saturation",value:20,enabled:!0},{type:"brightness",value:15,enabled:!0},{type:"contrast",value:-15,enabled:!0},{type:"vibrance",value:15,enabled:!0}]},{id:"dramatic",nameKey:"imageEditor.filters.names.dramatic",category:"artistic",adjustments:[{type:"contrast",value:40,enabled:!0},{type:"clarity",value:30,enabled:!0},{type:"highlights",value:-30,enabled:!0},{type:"shadows",value:-20,enabled:!0},{type:"vignette",value:35,enabled:!0}]}];function on(s){return{none:"linear-gradient(135deg, #4a4a4a 0%, #6a6a6a 50%, #4a4a4a 100%)",blackWhite:"linear-gradient(135deg, #333 0%, #666 50%, #999 100%)",vintage:"linear-gradient(135deg, #8B6914 0%, #C49B47 50%, #A67B35 100%)",film:"linear-gradient(135deg, #3A4A5C 0%, #5C7A8A 50%, #4A6070 100%)",faded:"linear-gradient(135deg, #8A8A7A 0%, #B8B8A8 50%, #9A9A8A 100%)",crossProcess:"linear-gradient(135deg, #2E5C34 0%, #7AB648 50%, #44B3D0 100%)",vivid:"linear-gradient(135deg, #2563EB 0%, #10B981 50%, #F59E0B 100%)",autumn:"linear-gradient(135deg, #D4762C 0%, #E8A849 50%, #C45D1A 100%)",sunset:"linear-gradient(135deg, #F97316 0%, #EAB308 50%, #EC4899 100%)",winterMorning:"linear-gradient(135deg, #6BB3D9 0%, #A4D1E8 50%, #C8E1F0 100%)",brighten:"linear-gradient(135deg, #F5D76E 0%, #FDF2C3 50%, #F9E79F 100%)",warmTone:"linear-gradient(135deg, #D4883E 0%, #E8AD6D 50%, #C47A2E 100%)",coolTone:"linear-gradient(135deg, #5B8DBE 0%, #89B4D8 50%, #6FA0CA 100%)",softLight:"linear-gradient(135deg, #E8D5C4 0%, #F0E2D3 50%, #F5EDE5 100%)",warmYellow:"linear-gradient(135deg, #D4A017 0%, #F0C75E 50%, #E8B830 100%)",fresh:"linear-gradient(135deg, #34D399 0%, #6EE7B7 50%, #A7F3D0 100%)",retroDiner:"linear-gradient(135deg, #DC2626 0%, #F
64259E0B 50%, #D97706 100%)",oilPainting:"linear-gradient(135deg, #1D4ED8 0%, #D97706 50%, #059669 100%)",sketch:"linear-gradient(135deg, #1A1A1A 0%, #E5E5E5 50%, #333 100%)",watercolor:"linear-gradient(135deg, #93C5FD 0%, #F9A8D4 50%, #FDE68A 100%)",dramatic:"linear-gradient(135deg, #1A1A2E 0%, #4A4A6A 50%, #16213E 100%)"}[s]||"linear-gradient(135deg, #555 0%, #777 100%)"}const ln=[{key:"classic",labelKey:"imageEditor.filters.categories.classic"},{key:"landscape",labelKey:"imageEditor.filters.categories.landscape"},{key:"portrait",labelKey:"imageEditor.filters.categories.portrait"},{key:"food",labelKey:"imageEditor.filters.categories.food"},{key:"artistic",labelKey:"imageEditor.filters.categories.artistic"}];function cn(){const{t:s}=q(),t=L(m=>m.layers),r=L(m=>m.activeLayerId),n=L(m=>m.updateLayer),a=L(m=>m.pushSnapshot),o=L(m=>m.sourceImage),g=t.find(m=>m.id===r),[c,u]=i.useState("classic"),[d,w]=i.useState("none"),[k,N]=i.useState(100),j=i.useRef(0),b=i.useRef(null),v=i.useMemo(()=>nt.filter(m=>m.category===c||m.id==="none"),[c]),y=i.useCallback((m,x)=>{if(!r)return;a(s("imageEditor.filters.apply"));const T=m.adjustments.map(p=>({...p,value:Math.round(p.value*(x/100))}));n(r,{adjustments:T})},[r,a,n,s]),_=i.useCallback(m=>{w(m.id),N(100),y(m,100)},[y]),M=i.useCallback(m=>{const x=Number(m.target.value);N(x),j.current&&cancelAnimationFrame(j.current),j.current=requestAnimationFrame(()=>{const T=nt.find(p=>p.id===d);T&&y(T,x)})},[d,y]);if(!o||!g)return e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center gap-3 p-6 text-center",children:[e.jsx(Ct,{size:32,style:{color:"var(--text-secondary)"}}),e.jsx("p",{className:"text-sm",style:{color:"var(--text-secondary)"},children:s("imageEditor.adjust.noImage")})]});const l=k;return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("style",{children:`
643        .filter-slider {
644          -webkit-appearance: none;
645          appearance: none;
646          height: 4px;
647          border-radius: 2px;
648          outline: none;
649          cursor: pointer;
650        }
651        .filter-slider::-webkit-slider-thumb {
652          -webkit-appearance: none;
653          appearance: none;
654          width: 14px;
655          height: 14px;
656          border-radius: 50%;
657          background: #ffffff;
658          border: 2px solid #3b82f6;
659          cursor: pointer;
660          box-shadow: 0 1px 3px rgba(0,0,0,0.3);
661          transition: transform 0.1s ease;
662        }
663        .filter-slider::-webkit-slider-thumb:hover {
664          transform: scale(1.15);
665        }
666        .filter-slider::-moz-range-thumb {
667          width: 14px;
668          height: 14px;
669          border-radius: 50%;
670          background: #ffffff;
671          border: 2px solid #3b82f6;
672          cursor: pointer;
673          box-shadow: 0 1px 3px rgba(0,0,0,0.3);
674        }
675      `}),e.jsx("div",{ref:b,className:"shrink-0 flex items-center gap-1 px-3 py-2 overflow-x-auto no-scrollbar",style:{borderBottom:"1px solid var(--border-default)"},children:ln.map(m=>e.jsx("button",{className:`shrink-0 h-7 px-3 rounded-full text-xs font-medium transition-colors whitespace-nowrap ${c===m.key?"bg-blue-500/20 text-blue-400":"hover:bg-white/10"}`,style:{color:c===m.key?void 0:"var(--text-secondary)"},onClick:()=>u(m.key),children:s(m.labelKey)},m.key))}),e.jsx("div",{className:"flex-1 overflow-y-auto px-3 py-3 custom-scrollbar",children:e.jsx("div",{className:"grid grid-cols-3 gap-2",children:v.map(m=>{const x=d===m.id;return e.jsxs("button",{className:`flex flex-col items-center gap-1.5 p-1.5 rounded-lg transition-all ${x?"ring-2 ring-blue-500 bg-blue-500/10":"hover:bg-white/5"}`,onClick:()=>_(m),children:[e.jsx("div",{className:"w-full aspect-square rounded-md overflow-hidden",style:{background:on(m.id)},children:m.id==="none"&&e.jsx("div",{className:"w-full h-full flex items-center justify-center",children:e.jsx("div",{className:"w-6 h-6 rounded-full border-2",style:{borderColor:"rgba(255,255,255,0.4)"}})})}),e.jsx("span",{className:"text-[10px] leading-tight text-center truncate w-full",style:{color:x?"#3b82f6":"var(--text-secondary)"},children:s(m.nameKey)})]},m.id)})})}),d!=="none"&&e.jsxs("div",{className:"shrink-0 px-3 py-3 border-t",style:{borderColor:"var(--border-default)"},children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-xs",style:{color:"var(--text-secondary)"},children:s("imageEditor.filters.strength")}),e.jsxs("span",{className:"text-xs font-mono tabular-nums",style:{color:"#3b82f6"},children:[k,"%"]})]}),e.jsx("input",{type:"range",min:0,max:100,value:k,onChange:M,className:"filter-slider w-full",style:{background:`linear-gradient(to right,
676                #3b82f6 0%,
677                #3b82f6 ${l}%,
678                rgba(255,255,255,0.08) ${l}%,
679                rgba(255,255,255,0.08) 100%)`}})]})]})}const dn=["normal","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","darken","lighten","difference","exclusion"],un={image:yt,text:ct,drawing:wt,shape:Nt,adjustment:jt};function hn({layer:s}){const t=un[s.type]||De;return s.imageData?e.jsx("img",{src:s.imageData,alt:s.name,className:"w-8 h-8 rounded object-cover",style:{background:"var(--bg-base)"},draggable:!1}):e.jsx("div",{className:"w-8 h-8 rounded flex items-center justify-center",style:{background:"var(--bg-base)"},children:e.jsx(t,{size:14,style:{color:"var(--text-secondary)"}})})}function mn({layer:s,isActive:t,onSelect:r,onToggleVisibility:n,onToggleLock:a,onRename:o,onDragStart:g,onDragOver:c,onDrop:u}){const[d,w]=i.useState(!1),[k,N]=i.useState(s.name),j=i.useRef(null),b=i.useCallback(()=>{N(s.name),w(!0),setTimeout(()=>{var _;return(_=j.current)==null?void 0:_.select()},0)},[s.name]),v=i.useCallback(()=>{const _=k.trim();_&&_!==s.name&&o(_),w(!1)},[k,s.name,o]),y=i.useCallback(_=>{_.key==="Enter"&&!_.nativeEvent.isComposing?v():_.key==="Escape"&&(w(!1),N(s.name))},[v,s.name]);return e.jsxs("div",{className:`flex items-center gap-2 px-2 py-1.5 cursor-pointer transition-colors group ${t?"bg-blue-500/15":"hover:bg-white/5"}`,style:{borderLeft:t?"2px solid rgb(59, 130, 246)":"2px solid transparent",opacity:s.visible?1:.5},onClick:r,draggable:!0,onDragStart:_=>g(_,s.id),onDragOver:c,onDrop:_=>u(_,s.id),children:[e.jsx("div",{className:"opacity-0 group-hover:opacity-40 cursor-grab",style:{color:"var(--text-secondary)"},children:e.jsx(cr,{size:12})}),e.jsx(hn,{layer:s}),e.jsx("div",{className:"flex-1 min-w-0",children:d?e.jsx("input",{ref:j,className:"w-full text-xs px-1 py-0.5 rounded border outline-none",style:{background:"var(--bg-tertiary)",borderColor:"var(--border-focus)",color:"var(--text-primary)"},value:k,maxLength:50,onChange:_=>N(_.target.value),onBlur:v,onKeyDown:y,onClick:_=>_.stopPropagation()}):e.jsx("span",{className:"text-xs truncate block",style:{color:t?"var(--text-primary)":"var(--text-secondary)"},onDoubleClick:b,children:s.name})}),e.jsxs("div",{className:"flex items-center gap-0.5 shrink-0",children:[e.jsx("button",{className:"w-6 h-6 flex items-center justify-center rounded hover:bg-white/10 transition-colors",onClick:_=>{_.stopPropagation(),a()},style:{color:s.locked?"rgb(59, 130, 246)":"var(--text-tertiary)"},children:s.locked?e.jsx(bt,{size:12}):e.jsx(kt,{size:12})}),e.jsx("button",{className:"w-6 h-6 flex items-center justify-center rounded hover:bg-white/10 transition-colors",onClick:_=>{_.stopPropagation(),n()},style:{color:s.visible?"var(--text-secondary)":"var(--text-tertiary)"},children:s.visible?e.jsx(Ot,{size:12}):e.jsx(Ht,{size:12})})]})]})}function gn(){const{t:s}=q(),t=L(S=>
679S.layers),r=L(S=>S.activeLayerId),n=L(S=>S.setActiveLayer),a=L(S=>S.toggleVisibility),o=L(S=>S.toggleLock),g=L(S=>S.updateLayer),c=L(S=>S.removeLayer),u=L(S=>S.duplicateLayer),d=L(S=>S.addLayer),w=L(S=>S.mergeDown),k=L(S=>S.flattenAll),N=L(S=>S.reorderLayers),j=L(S=>S.canvasWidth),b=L(S=>S.canvasHeight),v=L(S=>S.pushSnapshot),y=t.find(S=>S.id===r),_=i.useRef(null),M=i.useCallback(S=>{y&&(v("Change Blend Mode"),g(y.id,{blendMode:S}))},[y,v,g]),l=i.useCallback(S=>{y&&g(y.id,{opacity:Number(S.target.value)})},[y,g]),m=i.useCallback(()=>{v("Add Layer"),d({type:"image",name:"",visible:!0,opacity:100,blendMode:"normal",locked:!1,transform:{x:0,y:0,width:j,height:b,rotation:0,flipH:!1,flipV:!1}})},[d,j,b,v]),x=i.useCallback(()=>{!r||t.length<=1||(v("Delete Layer"),c(r))},[r,t.length,v,c]),T=i.useCallback(()=>{r&&(v("Duplicate Layer"),u(r))},[r,v,u]),p=i.useCallback(()=>{!r||t.findIndex(W=>W.id===r)<=0||(v("Merge Down"),w(r))},[r,t,v,w]),f=i.useCallback(()=>{t.length<=1||(v("Flatten All"),k())},[t.length,v,k]),C=i.useCallback((S,W)=>{g(S,{name:W})},[g]),D=i.useCallback((S,W)=>{_.current=W,S.dataTransfer.effectAllowed="move";const F=S.currentTarget;F.style.opacity="0.5"},[]),E=i.useCallback(S=>{S.preventDefault(),S.dataTransfer.dropEffect="move"},[]),h=i.useCallback((S,W)=>{S.preventDefault();const F=_.current;if(!F||F===W)return;const B=t.findIndex(X=>X.id===F),O=t.findIndex(X=>X.id===W);B===-1||O===-1||(v("Reorder Layers"),N(B,O),_.current=null)},[t,v,N]),R=[...t].reverse();return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"p-3 border-b space-y-2",style:{borderColor:"var(--border-default)"},children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs mb-1 block",style:{color:"var(--text-secondary)"},children:s("imageEditor.layers.blendMode","Blend Mode")}),e.jsx(Xe,{value:(y==null?void 0:y.blendMode)||"normal",onChange:M,disabled:!y,className:"w-full",options:dn.map(S=>({value:S,label:s(`imageEditor.layers.blend.${S}`,S)}))})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("label",{className:"text-xs",style:{color:"var(--text-secondary)"},children:s("imageEditor.layers.opacity","Opacity")}),e.jsxs("span",{className:"text-xs font-mono",style:{color:"var(--text-primary)"},children:[(y==null?void 0:y.opacity)??100,"%"]})]}),e.jsx("input",{type:"range",className:"w-full h-1 accent-blue-500",min:0,max:100,value:(y==null?void 0:y.opacity)??100,onChange:l,disabled:!y})]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:R.length===0?e.jsxs("div",{className:"p-4 text-center",children:[e.jsx(De,{size:24,className:"mx-auto mb-2",style:{color:"var(--text-tertiary)"}}),e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:s("imageEditor.layers.empty","No layers yet")})]}):R.map(S=>e.jsx(mn,{layer:S,isActive:S.id===r,onSelect:()=>n(S.id),onToggleVisibility:()=>a(S.id),onToggleLock:()=>o(S.id),onRename:W=>C(S.id,W),onDragStart:D,onDragOver:E,onDrop:h},S.id))}),e.jsxs("div",{className:"p-2 border-t flex items-center justify-between",style:{borderColor:"var(--border-default)"},children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors",style:{color:"var(--text-secondary)"},onClick:m,title:s("imageEditor.layers.addLayer","Add Layer"),children:e.jsx(pt,{size:16})}),e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors disabled:opacity-30",style:{color:"var(--text-secondary)"},onClick:T,disabled:!r,title:s("imageEditor.layers.duplicate","Duplicate Layer"),children:e.jsx(zt,{size:14})}),e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors disabled:opacity-30",style:{color:"var(--text-secondary)"},onClick:p,disabled:!r||t.findIndex(S=>S.id===r)<=0,title:s("imageEditor.layers.mergeDown","Merge Down"),children:e.jsx(lr,{size:14})}),e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors disabled:opacity-30",style:{color:"var(--text-secondary)"},onClick:f,disabled:t.length<=1,title:s("imageEditor.layers.flatten","Flatten All"),children:e.jsx(De,{size:14})})]}),e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-red-500/20 transition-colors disabled:opacity-30",style:{color:"var(--text-secondary)"},onClick:x,disabled:!r||t.length<=1,title:s("imageEditor.layers.delete","Delete Layer"),children:e.jsx(vt,{size:14})})]})]})}function fn(){const{t:s}=q(),t=L(N=>N.undoStack),r=L(N=>N.redoStack),n=L(N=>N.undo),a=L(N=>
679N.redo),o=L(N=>N.clearHistory),g=t.length>0,c=r.length>0,u=i.useCallback(N=>{const j=t.length-1-N;if(!(j<=0))for(let b=0;b<j;b++)n()},[t.length,n]),d=i.useCallback(N=>{const j=N+1;for(let b=0;b<j;b++)a()},[a]),w=N=>new Date(N).toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"}),k=[...t.map((N,j)=>({...N,type:"undo",stackIndex:j,isCurrent:!1})),{id:"current",name:s("imageEditor.history.currentState","Current State"),timestamp:Date.now(),type:"current",stackIndex:-1,isCurrent:!0},...[...r].reverse().map((N,j)=>({...N,type:"redo",stackIndex:j,isCurrent:!1}))];return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"p-3 border-b flex items-center justify-between",style:{borderColor:"var(--border-default)"},children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors disabled:opacity-30",style:{color:"var(--text-secondary)"},onClick:n,disabled:!g,title:s("imageEditor.history.undo","Undo"),children:e.jsx(sr,{size:14})}),e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-white/10 transition-colors disabled:opacity-30",style:{color:"var(--text-secondary)"},onClick:a,disabled:!c,title:s("imageEditor.history.redo","Redo"),children:e.jsx(dr,{size:14})})]}),e.jsx("button",{className:"w-7 h-7 flex items-center justify-center rounded hover:bg-red-500/20 transition-colors disabled:opacity-30",style:{color:"var(--text-secondary)"},onClick:o,disabled:t.length===0&&r.length===0,title:s("imageEditor.history.clear","Clear History"),children:e.jsx(vt,{size:14})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:k.length<=1?e.jsxs("div",{className:"p-4 text-center",children:[e.jsx(Et,{size:24,className:"mx-auto mb-2",style:{color:"var(--text-tertiary)"}}),e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:s("imageEditor.history.empty","No history yet. Start editing to see changes here.")})]}):k.map((N,j)=>e.jsxs("button",{className:`w-full flex items-center gap-3 px-3 py-2 text-left transition-colors ${N.isCurrent?"bg-blue-500/15":N.type==="redo"?"opacity-40 hover:opacity-60 hover:bg-white/5":"hover:bg-white/5"}`,onClick:()=>{N.isCurrent||(N.type==="undo"?u(N.stackIndex):N.type==="redo"&&d(N.stackIndex))},disabled:N.isCurrent,children:[e.jsxs("div",{className:"flex flex-col items-center shrink-0",children:[e.jsx("div",{className:"w-2 h-2 rounded-full",style:{background:N.isCurrent?"rgb(59, 130, 246)":N.type==="redo"?"var(--text-tertiary)":"var(--text-secondary)"}}),j<k.length-1&&e.jsx("div",{className:"w-px h-4 mt-1",style:{background:"var(--border-default)"}})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs font-medium truncate",style:{color:N.isCurrent?"rgb(59, 130, 246)":"var(--text-primary)"},children:N.name}),e.jsx("p",{className:"text-xs mt-0.5",style:{color:"var(--text-tertiary)"},children:w(N.timestamp)})]})]},N.id||`entry-${j}`))}),e.jsx("div",{className:"p-2 border-t text-center",style:{borderColor:"var(--border-default)"},children:e.jsx("p",{className:"text-xs",style:{color:"var(--text-tertiary)"},children:s("imageEditor.history.count","{{count}} step(s)",{count:t.length+r.length})})})]})}const xn=2e3,at=150;function me(){const[s,t]=i.useState(!1),[r,n]=i.useState(0),[a,o]=i.useState(null),[g,c]=i.useState(null),u=i.useRef(!1),d=i.useCallback(async M=>{let l=0;for(;l<at;){if(u.current)throw new Error("Operation cancelled");const{data:m}=await he.get(`/image/editor/ai/task/${M}`);if(m.status==="completed")return n(100),m;if(m.status==="failed")throw new Error(m.error||"Operation failed");const x=Math.min(90,Math.round(l/at*90+10));n(x),l++,await new Promise(T=>setTimeout(T,xn))}throw new Error("Operation timed out")},[]),w=i.useCallback(async(M,l,m)=>{t(!0),n(5),o(null),c(M),u.current=!1;try{const{data:x}=await he.post(l,m);if(x.status==="completed")return n(100),x;if(x.status==="failed")throw new Error(x.error||"Operation failed");return n(10),await d(x.taskId)}catch(x){const T=x instanceof Error?x.message:"Operation failed";throw o(T),x}finally{t(!1),c(null)}},[d]),k=i.useCallback(M=>w("outpaint","/image/editor/ai/outpaint",M),[w]),N=i.useCallback(M=>w("style-transfer","/image/editor/ai/style-transfer",M),[w]),j=i.useCallback(M=>w("segment","/image/editor/ai/segment",M),[w]),b=i.useCallback((M,l,m)=>w("inpaint","/image/editor/ai/inpaint",{imageUrl:M,maskUrl:l,prompt:m}),[w]),v=i.useCallback(M=>w("enhance","/image/editor/ai/enhance",{imageUrl:M}),[w]),y=i.useCallback(()=>{u.current=!0},[]),_=i.useCallback(()=>{o(null)},[]);return{isProcessing:s,progress:r,error:a,activeOperation:g,runOutpaint:k,runStyleTransfer:N,runSegment:j,runInpaint:b,runEnhance:v,pollTask:d,cancelOperation:y,clearError:_}}const pn=[{id:"smartSelect",icon:ir,available:!0},{id:"aiErase",icon:lt,available:!0},{id:"aiExpand",icon:dt,available:!0},{id:"aiReplace",icon:$t,available:!0},{id:"styleTransfer",icon:ht,available:!0},{id:"aiEnhance",icon:be,available:!0}];function yn(){const{t:s}=q(),[t,r]=i.useState(null),n=i.useCallback(()=>r(null),[]);return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("div",{className:"p-3 border-b",style:{borderColor:"var(--border-default)"},children:t?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:n,className:"p-1 rounded hover:bg-white/10 transition-colors",children:e.jsx(Xt,{size:16,style:{color:"var(--text-primary)"}})}),e.jsx("h3",{className:"text-sm font-medium",style:{color:"var(--text-primary)"},children:s(`imageEditor.ai.${t}.title`,t)})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(be,{size:16,className:"text-blue-400"}),e.jsx("h3",{className:"text-sm font-medium",style:{color:"var(--text-primary)"},children:s("imageEditor.ai.title","AI Tools")})]}),e.jsx("p",{className:"text-xs mt-1",style:{color:"var(--text-secondary)"},children:s("imageEditor.ai.subtitle","Intelligent image editing powered by AI")})]})}),e.jsx("div",{className:"flex-1 overflow-y-auto p-3",children:t?e.jsx(vn,{featureId:t,onBack:n}):e.jsx(bn,{onSelect:r})}),!t&&e.jsx("div",{className:"p-3 border-t",style:{borderColor:"var(--border-default)"},children:e.jsx("p",{className:"text-xs text-center",style:{color:"var(--text-tertiary)"},children:s("imageEditor.ai.footer","AI features require an active subscription and server connection.")})})]})}function bn({onSelect:s}){const{t}=q();return e.jsx("div",{className:"space-y-2",children:pn.map(r=>{const n=r.icon;return e.jsx("button",{className:"w-full p-3 rounded-lg border text-left transition-all group hover:border-blue-500/40 hover:bg-blue-500/5 cursor-pointer",style:{borderColor:"var(--border-default)",background:"var(--bg-tertiary)"},onClick:()=>s(r.id),children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"w-8 h-8 rounded-lg flex items-center justify-center shrink-0 mt-0.5",style:{background:"rgba(59, 130, 246, 0.15)"},children:e.jsx(n,{size:16,style:{color:"rgb(59, 130, 246)"}})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs font-medium mb-0.5",style:{color:"var(--text-primary)"},children:t(`imageEditor.ai.${r.id}.title`,r.id)}),e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t(`imageEditor.ai.${r.id}.desc`,"")})]})]})},r.id)})})}function vn({featureId:s,onBack:t}){switch(s){case"smartSelect":return e.jsx(wn,{onBack:t});case"aiErase":return e.jsx(jn,{onBack:t});case"aiExpand":return e.jsx(Cn,{onBack:t});case"aiReplace":return e.jsx(Nn,{onBack:t});case"styleTransfer":return e.jsx(Sn,{onBack:t});case"aiEnhance":return e.jsx(_n,{onBack:t});default:return null}}function ge({progress:s,label:t}){return e.jsxs("div",{className:"rounded-lg p-4 flex flex-col items-center gap-3 mb-4",style:{background:"var(--bg-secondary)"},children:[e.jsx(pe,{size:24,className:"animate-spin text-blue-400"}),e.jsx("p",{className:"text-xs",style:{color:"var(--text-primary)"},children:t}),e.jsx("div",{className:"w-full h-1.5 rounded-full overflow-hidden",style:{background:"var(--bg-tertiary)"},children:e.jsx("div",{className:"h-full rounded-full bg-blue-500 transition-all duration-300",style:{width:`${s}%`}})}),e.jsxs("p",{className:"text-xs",style:{color:"var(--text-tertiary)"},children:[s,"%"]})]})}function fe({onClick:s,disabled:t,children:r}){return e.jsx("button",{onClick:s,disabled:t,className:"w-full py-2 px-4 roun
679ded-lg text-sm font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed",style:{background:t?"var(--bg-secondary)":"#3b82f6",color:t?"var(--text-tertiary)":"#ffffff"},children:r})}function ve(s){const t=L(a=>a.loadImage),{t:r}=q();return i.useCallback(a=>{if(a.imageUrl&&a.width&&a.height)t(a.imageUrl,a.width,a.height),Z.success(r("imageEditor.ai.completed","Completed")),s();else if(a.imageUrl){const o=new Image;Kt(a.imageUrl)&&(o.crossOrigin="anonymous"),o.onload=()=>{t(a.imageUrl,o.naturalWidth,o.naturalHeight),Z.success(r("imageEditor.ai.completed","Completed")),s()},o.onerror=()=>{Z.error(r("imageEditor.ai.failed","Failed"))},o.src=a.imageUrl}},[t,s,r])}function wn({onBack:s}){const{t}=q(),r=L(y=>y.sourceImage),n=L(y=>y.setSelection),{isProcessing:a,progress:o,error:g,runSegment:c,clearError:u}=me(),[d,w]=i.useState([]),[k,N]=i.useState("point"),j=i.useCallback(()=>{const y=L.getState().canvasWidth/2,_=L.getState().canvasHeight/2;w(M=>[...M,{x:y,y:_}])},[]),b=i.useCallback(()=>{w([])},[]),v=i.useCallback(async()=>{if(!r){Z.error(t("imageEditor.adjust.noImage","Load an image first"));return}u();try{const y=k==="point"&&d.length>0?{imageUrl:r,points:d}:{imageUrl:r,box:{x:0,y:0,width:L.getState().canvasWidth,height:L.getState().canvasHeight}},_=await c(y);if(_.maskUrl){const M={x:0,y:0,width:_.width||L.getState().canvasWidth,height:_.height||L.getState().canvasHeight};n({type:"rect",path:[{x:M.x,y:M.y},{x:M.x+M.width,y:M.y},{x:M.x+M.width,y:M.y+M.height},{x:M.x,y:M.y+M.height}],bounds:M}),Z.success(t("imageEditor.ai.completed","Completed"))}}catch{Z.error(g||t("imageEditor.ai.failed","Failed"))}},[r,k,d,c,n,u,g,t]);return e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.smartSelect.desc","Use AI to intelligently select objects in the image")}),a&&e.jsx(ge,{progress:o,label:t("imageEditor.ai.processing","Processing...")}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{className:"flex-1 py-1.5 rounded-lg text-xs font-medium transition-colors",style:{background:k==="point"?"#3b82f6":"var(--bg-secondary)",color:k==="point"?"#fff":"var(--text-secondary)"},onClick:()=>N("point"),children:t("imageEditor.ai.smartSelect.clickToPlace","Click to Place Points")}),e.jsx("button",{className:"flex-1 py-1.5 rounded-lg text-xs font-medium transition-colors",style:{background:k==="box"?"#3b82f6":"var(--bg-secondary)",color:k==="box"?"#fff":"var(--text-secondary)"},onClick:()=>N("box"),children:t("imageEditor.ai.smartSelect.dragToBox","Drag to Box")})]}),k==="point"&&e.jsxs("div",{className:"space-y-2",children:[d.map((y,_)=>e.jsxs("div",{className:"flex items-center justify-between px-2 py-1 rounded text-xs",style:{background:"var(--bg-secondary)",color:"var(--text-secondary)"},children:[e.jsxs("span",{children:["Point ",_+1,": (",Math.round(y.x),", ",Math.round(y.y),")"]}),e.jsx("button",{className:"text-red-400 hover:text-red-300",onClick:()=>w(M=>M.filter((l,m)=>m!==_)),children:"x"})]},_)),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{className:"flex-1 py-1.5 rounded text-xs border transition-colors hover:border-blue-500/40",style:{borderColor:"var(--border-default)",color:"var(--text-secondary)"},onClick:j,children:["+ ",t("imageEditor.ai.smartSelect.clickToPlace","Add Point")]}),d.length>0&&e.jsx("button",{className:"py-1.5 px-3 rounded text-xs transition-colors hover:bg-red-500/10",style:{color:"var(--text-secondary)"},onClick:b,children:t("common.clear","Clear")})]})]}),g&&e.jsx("p",{className:"text-xs text-red-400",children:g}),e.jsx(fe,{onClick:v,disabled:a||!r,children:t("imageEditor.ai.smartSelect.apply","Apply Smart Selection")})]})}function jn({onBack:s}){const{t}=q(),r=L(k=>k.sourceImage),n=L(k=>k.selection),{isProcessing:a,progress:o,error:g,runInpaint:c,clearError:u}=me(),d=ve(s),w=i.useCallback(async()=>{if(!r){Z.error(t("imageEditor.adjust.noImage","Load an image first"));return}if(!n){Z.error(t("imageEditor.ai.aiErase.selectFirst","Select an area first"));return}u();try{const N=await c(r,r);d(N)}catch{Z.error(g||t("imageEditor.ai.failed","Failed"))}},[r,n,c,d,u,g,t]);return e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.aiErase.desc","Select an area and AI will erase the content, filling it naturally")}),a&&e.jsx(ge,{progress:o,label:t("imageEditor.ai.processing","Processing...")}),e.jsx("div",{className:"rounded-lg p-3",style:{background:"var(--bg-secondary)"},children:e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:n?e.jsxs(e.Fragment,{children:[t("imageEditor.ai.aiErase.eraseSelected","Area selected")," (",Math.round(n.bounds.width)," x"," ",Math.round(n.bounds.height),"px)"]}):t("imageEditor.ai.aiErase.selectFirst","Use a selection tool to select the area to erase")})}),g&&e.jsx("p",{className:"text-xs text-red-400",children:g}),e.jsx(fe,{onClick:w,disabled:a||!r||!n,children:t("imageEditor.ai.aiErase.eraseSelected","Erase Selected Area")})]})}const En={top:Yt,right:Gt,bottom:ur,left:mt},kn={top:"Up",right:"Right",bottom:"Down",left:"Left"};function Cn({onBack:s}){const{t}
679=q(),r=L(y=>y.sourceImage),{isProcessing:n,progress:a,error:o,runOutpaint:g,clearError:c}=me(),u=ve(s),[d,w]=i.useState("right"),[k,N]=i.useState(200),[j,b]=i.useState(""),v=i.useCallback(async()=>{if(!r){Z.error(t("imageEditor.adjust.noImage","Load an image first"));return}c();try{const y=await g({imageUrl:r,direction:d,size:k,prompt:j||void 0});u(y)}catch{Z.error(o||t("imageEditor.ai.failed","Failed"))}},[r,d,k,j,g,u,c,o,t]);return e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.aiExpand.desc","Expand the image in any direction using AI")}),n&&e.jsx(ge,{progress:a,label:t("imageEditor.ai.processing","Processing...")}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium block mb-2",style:{color:"var(--text-primary)"},children:t("imageEditor.ai.aiExpand.direction","Direction")}),e.jsx("div",{className:"grid grid-cols-4 gap-2",children:["top","right","bottom","left"].map(y=>{const _=En[y];return e.jsxs("button",{className:"flex flex-col items-center gap-1 py-2 rounded-lg text-xs transition-colors",style:{background:d===y?"#3b82f6":"var(--bg-secondary)",color:d===y?"#fff":"var(--text-secondary)"},onClick:()=>w(y),children:[e.jsx(_,{size:14}),e.jsx("span",{children:kn[y]})]},y)})})]}),e.jsxs("div",{children:[e.jsxs("label",{className:"text-xs font-medium block mb-2",style:{color:"var(--text-primary)"},children:[t("imageEditor.ai.aiExpand.size","Expansion Size"),": ",k,"px"]}),e.jsx("input",{type:"range",min:50,max:500,step:10,value:k,onChange:y=>N(Number(y.target.value)),className:"w-full accent-blue-500"}),e.jsxs("div",{className:"flex justify-between text-xs mt-1",style:{color:"var(--text-tertiary)"},children:[e.jsx("span",{children:"50px"}),e.jsx("span",{children:"500px"})]})]}),e.jsxs("div",{children:[e.jsxs("label",{className:"text-xs font-medium block mb-2",style:{color:"var(--text-primary)"},children:[t("imageEditor.ai.aiExpand.prompt","Content Description")," ",e.jsxs("span",{style:{color:"var(--text-tertiary)"},children:["(",t("common.optional","optional"),")"]})]}),e.jsx("textarea",{value:j,onChange:y=>b(y.target.value),placeholder:t("imageEditor.ai.aiExpand.prompt","Describe what should appear in the expanded area..."),className:"w-full px-3 py-2 rounded-lg text-xs resize-none border focus:border-blue-500 focus:outline-none",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)",color:"var(--text-primary)"},rows:3,maxLength:1e3})]}),o&&e.jsx("p",{className:"text-xs text-red-400",children:o}),e.jsx(fe,{onClick:v,disabled:n||!r,children:t("imageEditor.ai.aiExpand.apply","Expand Image")})]})}function Nn({onBack:s}){const{t}=q(),r=L(j=>j.sourceImage),n=L(j=>j.selection),{isProcessing:a,progress:o,error:g,runInpaint:c,clearError:u}=me(),d=ve(s),[w,k]=i.useState(""),N=i.useCallback(async()=>{if(!r){Z.error(t("imageEditor.adjust.noImage","Load an image first"));return}if(!n){Z.error(t("imageEditor.ai.aiErase.selectFirst","Select an area first"));return}if(!w.trim()){Z.error(t("imageEditor.ai.aiReplace.prompt","Enter a prompt"));return}u();try{const b=await c(r,r,w);d(b)}catch{Z.error(g||t("imageEditor.ai.failed","Failed"))}},[r,n,w,c,d,u,g,t]);return e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.aiReplace.desc","Select an area and describe what should replace it")}),a&&e.jsx(ge,{progress:o,label:t("imageEditor.ai.processing","Processing...")}),e.jsx("div",{className:"rounded-lg p-3",style:{background:"var(--bg-secondary)"},children:e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:n?`${t("imageEditor.ai.aiErase.eraseSelected","Area selected")} (${Math.round(n.bounds.width)} x ${Math.round(n.bounds.height)}px)`:t("imageEditor.ai.aiErase.selectFirst","Use a selection tool to select the area to replace")})}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium block mb-2",style:{color:"var(--text-primary)"},children:t("imageEditor.ai.aiReplace.prompt","Replacement Description")}),e.jsx("textarea",{value:w,onChange:j=>k(j.target.value),placeholder:t("imageEditor.ai.aiReplace.prompt","Describe what should appear in the selected area..."),className:"w-full px-3 py-2 rounded-lg text-xs resize-none border focus:border-blue-500 focus:outline-none",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)",color:"var(--text-primary)"},rows:3,maxLength:1e3})]}),g&&e.jsx("p",{className:"text-xs text-red-400",children:g}),e.jsx(fe,{onClick:N,disabled:a||!r||!n||!w.trim(),children:t("imageEditor.ai.aiReplace.apply","Replace Content")})]})}function Sn({onBack:s}){const{t}
679=q(),r=L(y=>y.sourceImage),{isProcessing:n,progress:a,error:o,runStyleTransfer:g,clearError:c}=me(),u=ve(s),[d,w]=i.useState(""),[k,N]=i.useState(.7),j=i.useRef(null),b=i.useCallback(y=>{var l;const _=(l=y.target.files)==null?void 0:l[0];if(!_)return;const M=new FileReader;M.onload=()=>{w(M.result)},M.readAsDataURL(_)},[]),v=i.useCallback(async()=>{if(!r){Z.error(t("imageEditor.adjust.noImage","Load an image first"));return}if(!d){Z.error(t("imageEditor.ai.styleTransfer.uploadRef","Upload a reference style image"));return}c();try{const y=await g({imageUrl:r,styleImageUrl:d,strength:k});u(y)}catch{Z.error(o||t("imageEditor.ai.failed","Failed"))}},[r,d,k,g,u,c,o,t]);return e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.styleTransfer.desc","Transfer the style of a reference image to your photo")}),n&&e.jsx(ge,{progress:a,label:t("imageEditor.ai.processing","Processing...")}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium block mb-2",style:{color:"var(--text-primary)"},children:t("imageEditor.ai.styleTransfer.reference","Reference Style Image")}),d?e.jsxs("div",{className:"relative group",children:[e.jsx("img",{src:d,alt:"Style reference",className:"w-full h-24 object-cover rounded-lg"}),e.jsx("button",{className:"absolute inset-0 flex items-center justify-center bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded-lg text-xs text-white",onClick:()=>{w(""),j.current&&(j.current.value="")},children:t("common.remove","Remove")})]}):e.jsxs("button",{className:"w-full py-6 rounded-lg border-2 border-dashed flex flex-col items-center gap-2 transition-colors hover:border-blue-500/40",style:{borderColor:"var(--border-default)",background:"var(--bg-secondary)"},onClick:()=>{var y;return(y=j.current)==null?void 0:y.click()},children:[e.jsx(Ge,{size:20,style:{color:"var(--text-tertiary)"}}),e.jsx("span",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.styleTransfer.uploadRef","Upload Reference Image")})]}),e.jsx("input",{ref:j,type:"file",accept:"image/*",className:"hidden",onChange:b}),e.jsx("input",{type:"text",value:d.startsWith("data:")?"":d,onChange:y=>w(y.target.value),placeholder:"https://...",maxLength:500,className:"w-full mt-2 px-3 py-1.5 rounded-lg text-xs border focus:border-blue-500 focus:outline-none",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)",color:"var(--text-primary)"}})]}),e.jsxs("div",{children:[e.jsxs("label",{className:"text-xs font-medium block mb-2",style:{color:"var(--text-primary)"},children:[t("imageEditor.ai.styleTransfer.strength","Style Strength"),":"," ",Math.round(k*100),"%"]}),e.jsx("input",{type:"range",min:0,max:100,step:5,value:k*100,onChange:y=>N(Number(y.target.value)/100),className:"w-full accent-blue-500"}),e.jsxs("div",{className:"flex justify-between text-xs mt-1",style:{color:"var(--text-tertiary)"},children:[e.jsx("span",{children:"0%"}),e.jsx("span",{children:"100%"})]})]}),o&&e.jsx("p",{className:"text-xs text-red-400",children:o}),e.jsx(fe,{onClick:v,disabled:n||!r||!d,children:t("imageEditor.ai.styleTransfer.apply","Apply Style Transfer")})]})}function _n({onBack:s}){const{t}=q(),r=L(w=>w.sourceImage),{isProcessing:n,progress:a,error:o,runEnhance:g,clearError:c}=me(),u=ve(s),d=i.useCallback(async()=>{if(!r){Z.error(t("imageEditor.adjust.noImage","Load an image first"));return}c();try{const w=await g(r);u(w)}catch{Z.error(o||t("imageEditor.ai.failed","Failed"))}},[r,g,u,c,o,t]);return e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-xs",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.aiEnhance.desc","Automatically enhance and upscale the image using AI")}),n?e.jsx(ge,{progress:a,label:t("imageEditor.ai.aiEnhance.enhancing","Enhancing...")}):e.jsxs("div",{className:"rounded-lg p-4 flex flex-col items-center gap-3",style:{background:"var(--bg-secondary)"},children:[e.jsx("div",{className:"w-12 h-12 rounded-full flex items-center justify-center",style:{background:"rgba(59, 130, 246, 0.15)"},children:e.jsx(be,{size:24,className:"text-blue-400"})}),e.jsx("p",{className:"text-xs text-center",style:{color:"var(--text-secondary)"},children:t("imageEditor.ai.aiEnhance.desc","One-click AI enhancement will upscale and improve image quality")}
679)]}),o&&e.jsx("p",{className:"text-xs text-red-400",children:o}),e.jsx(fe,{onClick:d,disabled:n||!r,children:n?t("imageEditor.ai.aiEnhance.enhancing","Enhancing..."):t("imageEditor.ai.aiEnhance.enhance","Enhance Image")})]})}const le=10,Te=8,Ln=16;function Oe(s){switch(s){case"free":return null;case"1:1":return 1;case"4:3":return 4/3;case"3:4":return 3/4;case"16:9":return 16/9;case"9:16":return 9/16;default:return null}}function He(s,t,r){let{x:n,y:a,width:o,height:g}=s;return o=Math.max(le,Math.min(o,t)),g=Math.max(le,Math.min(g,r)),n=Math.max(0,Math.min(n,t-o)),a=Math.max(0,Math.min(a,r-g)),{x:n,y:a,width:o,height:g}}function Rn({canvasWidth:s,canvasHeight:t,zoom:r,panX:n,panY:a,onApply:o,onCancel:g}){const{t:c}=q(),u=L(p=>p.toolOptions.crop.aspectRatio),[d,w]=i.useState(()=>{const p=Oe(u);if(p){let f=s,C=f/p;return C>t&&(C=t,f=C*p),{x:Math.round((s-f)/2),y:Math.round((t-C)/2),width:Math.round(f),height:Math.round(C)}}return{x:0,y:0,width:s,height:t}}),k=i.useRef(null),N=i.useRef(null);i.useEffect(()=>{const p=Oe(u);p&&w(f=>{const C=f.x+f.width/2,D=f.y+f.height/2;let E=f.width,h=E/p;return h>t&&(h=t,E=h*p),E>s&&(E=s,h=E/p),He({x:Math.round(C-E/2),y:Math.round(D-h/2),width:Math.round(E),height:Math.round(h)},s,t)})},[u,s,t]);const j=i.useCallback(p=>p*r+n,[r,n]),b=i.useCallback(p=>p*r+a,[r,a]),v=i.useCallback(()=>{const{x:p,y:f,width:C,height:D}=d,E=j(p),h=b(f),R=C*r,S=D*r;return{"top-left":{cx:E,cy:h},top:{cx:E+R/2,cy:h},"top-right":{cx:E+R,cy:h},right:{cx:E+R,cy:h+S/2},"bottom-right":{cx:E+R,cy:h+S},bottom:{cx:E+R/2,cy:h+S},"bottom-left":{cx:E,cy:h+S},left:{cx:E,cy:h+S/2}}},[d,j,b,r]),y=p=>({"top-left":"nwse-resize",top:"ns-resize","top-right":"nesw-resize",right:"ew-resize","bottom-right":"nwse-resize",bottom:"ns-resize","bottom-left":"nesw-resize",left:"ew-resize"})[p],_=i.useCallback((p,f,C,D)=>{let{x:E,y:h,width:R,height:S}=D;const W=Oe(u);switch(p){case"top-left":E+=f,h+=C,R-=f,S-=C;break;case"top":h+=C,S-=C;break;case"top-right":R+=f,h+=C,S-=C;break;case"right":R+=f;break;case"bottom-right":R+=f,S+=C;break;case"bottom":S+=C;break;case"bottom-left":E+=f,R-=f,S+=C;break;case"left":E+=f,R-=f;break}return R<le&&(p.includes("left")&&(E=D.x+D.width-le),R=le),S<le&&(p.includes("top")&&(h=D.y+D.height-le),S=le),W&&(p==="left"||p==="right"?S=R/W:p==="top"||p==="bottom"||R/S>W?R=S*W:S=R/W),He({x:Math.round(E),y:Math.round(h),width:Math.round(R),height:Math.round(S)},s,t)},[u,s,t]),M=i.useCallback(p=>{if(p.button!==0)return;p.preventDefault(),p.stopPropagation();const f=k.current;if(!f)return;const C=f.getBoundingClientRect(),D=p.clientX-C.left,E=p.clientY-C.top,h=v();for(const[B,O]of Object.entries(h))if(Math.hypot(D-O.cx,E-O.cy)<=Ln){N.current={type:"handle",handle:B,startX:D,startY:E,startRect:{...d}};return}const R=j(d.x),S=b(d.y),W=d.width*r,F=d.height*r;D>=R&&D<=R+W&&E>=S&&E<=S+F&&(N.current={type:"move",startX:D,startY:E,startRect:{...d}})},[d,v,j,b,r]),l=i.useCallback(p=>{const f=N.current;if(!f)return;p.preventDefault(),p.stopPropagation();const C=k.current;if(!C)return;const D=C.getBoundingClientRect(),E=p.clientX-D.left,h=p.clientY-D.top,R=E-f.startX,S=h-f.startY,W=R/r,F=S/r;f.type==="move"?w(He({x:Math.round(f.startRect.x+W),y:Math.round(f.startRect.y+F),width:f.startRect.width,height:f.startRect.height},s,t)):f.type==="handle"&&f.handle&&w(_(f.handle,W,F,f.startRect))},[r,s,t,_]),m=i.useCallback(()=>{N.current=null},[]);i.useEffect(()=>{const p=f=>{f.key==="Enter"?(f.preventDefault(),o(d)):f.key==="Escape"&&(f.preventDefault(),g())};return window.addEventListener("keydown",p),()=>window.removeEventListener("keydown",p)},[d,o,g]);const x={x:j(d.x),y:b(d.y),width:d.width*r,height:d.height*r},T=v();return e.jsxs("div",{ref:k,className:"absolute inset-0 z-20",onMouseDown:M,onMouseMove:l,onMouseUp:m,onMouseLeave:m,style:{cursor:N.current?"grabbing":"crosshair"},children:[e.jsxs("svg",{className:"absolute inset-0 w-full h-full pointer-events-none",children:[e.jsx("rect",{x:0,y:0,width:"100%",height:x.y,fill:"rgba(0,0,0,0.6)"}),e.jsx("rect",{x:0,y:x.y+x.height,width:"100%",height:`calc(100% - ${x.y+x.height}px)`,fill:"rgba(0,0,0,0.6)"}),e.jsx("rect",{x:0,y:x.y,width:x.x,height:x.height,fill:"rgba(0,0,0,0.6)"}),e.jsx("rect",{x:x.x+x.width,y:x.y,width:`calc(100% - ${x.x+x.width}px)`,height:x.height,fill:"rgba(0,0,0,0.6)"}),e.jsx("rect",{x:x.x,y:x.y,width:x.width,height:x.height,fill:"none",stroke:"white",strokeWidth:1.5}),e.jsx("line",{x1:x.x+x.width/3,y1:x.y,x2:x.x+x.width/3,y2:x.y+x.height,stroke:"rgba(255,255,255,0.3)",strokeWidth:.5}),e.jsx("line",{x1:x.x+x.width*2/3,y1:x.y,x2:x.x+x.width*2/3,y2:x.y+x.height,stroke:"rgba(255,255,255,0.3)",strokeWidth:.5}),e.jsx("line",{x1:x.x,y1:x.y+x.height/3,x2:x.x+x.width,y2:x.y+x.height/3,stroke:"rgba(255,255,255,0.3)",strokeWidth:.5}),e.jsx("line",{x1:x.x,y1:x.y+x.height*2/3,x2:x.x+x.width,y2:x.y+x.height*2/3,stroke:"rgba(255,255,255,0.3)",strokeWidth:.5})]}),Object.entries(T).map(([p,f])=>e.jsx("div",{className:"absolute pointer-events-auto",style:{left:f.cx-Te/2,top:f.cy-Te/2,width:Te,height:Te,background:"white",border:"1px solid rgba(0,0,0,0.3)",borderRadius:1,cursor:y(p),boxSh
679adow:"0 1px 3px rgba(0,0,0,0.4)"}},p)),e.jsxs("div",{className:"absolute flex items-center gap-2 px-2 py-1 rounded text-xs font-mono pointer-events-none",style:{left:x.x+x.width/2,top:x.y+x.height+8,transform:"translateX(-50%)",background:"rgba(0,0,0,0.75)",color:"white",whiteSpace:"nowrap"},children:[d.width," x ",d.height]}),e.jsxs("div",{className:"absolute flex items-center gap-2 pointer-events-auto",style:{left:x.x+x.width,top:x.y-40,transform:"translateX(-100%)"},children:[e.jsxs("button",{className:"h-7 px-3 flex items-center gap-1.5 rounded text-xs font-medium bg-blue-500 hover:bg-blue-600 text-white transition-colors shadow-lg",onClick:()=>o(d),title:c("imageEditor.crop.apply","Apply Crop"),children:[e.jsx(xt,{size:14}),c("imageEditor.property.apply","Apply")]}),e.jsxs("button",{className:"h-7 px-3 flex items-center gap-1.5 rounded text-xs hover:bg-white/20 transition-colors shadow-lg",style:{color:"white",background:"rgba(0,0,0,0.5)"},onClick:g,title:c("imageEditor.crop.cancel","Cancel Crop"),children:[e.jsx(Ye,{size:14}),c("common.cancel","Cancel")]})]})]})}function Tn(s,t){return{x:(s.x+t.x)/2,y:(s.y+t.y)/2}}function Dn({canvasWidth:s,canvasHeight:t,zoom:r,panX:n,panY:a,containerRef:o}){const g=i.useRef(null),c=i.useRef(!1),u=i.useRef([]),d=L(p=>p.toolOptions.brush),w=L(p=>p.activeLayerId),k=L(p=>p.layers),N=L(p=>p.addLayer),j=L(p=>p.updateLayer),b=L(p=>p.pushSnapshot),v=i.useCallback((p,f)=>{const C=o.current;if(!C)return null;const D=C.getBoundingClientRect(),E=p-D.left,h=f-D.top;return{x:(E-n)/r,y:(h-a)/r}},[r,n,a,o]),y=i.useCallback(()=>{const p=g.current;if(!p)return;const f=p.getContext("2d");f&&f.clearRect(0,0,p.width,p.height)},[]),_=i.useCallback(p=>{const f=g.current;if(!f||p.length<2)return;const C=f.getContext("2d");if(!C)return;C.clearRect(0,0,f.width,f.height),C.save(),C.globalAlpha=d.opacity/100,C.strokeStyle=d.color,C.lineWidth=d.size*r,C.lineCap="round",C.lineJoin="round";const D=(100-d.hardness)/100;D>.1&&(C.shadowColor=d.color,C.shadowBlur=d.size*r*D*.5),C.beginPath();const E=R=>R*r+n,h=R=>R*r+a;if(p.length===2)C.moveTo(E(p[0].x),h(p[0].y)),C.lineTo(E(p[1].x),h(p[1].y));else{C.moveTo(E(p[0].x),h(p[0].y));for(let S=1;S<p.length-1;S++){const W={x:E(p[S].x),y:h(p[S].y)},F={x:E(p[S+1].x),y:h(p[S+1].y)},B=Tn(W,F);C.quadraticCurveTo(W.x,W.y,B.x,B.y)}const R=p[p.length-1];C.lineTo(E(R.x),h(R.y))}C.stroke(),C.restore()},[d,r,n,a]),M=i.useCallback(()=>{const p=k.find(D=>D.id===w);if(p&&p.type==="drawing")return p.id;const f=k.find(D=>D.type==="drawing");return f?f.id:N({type:"drawing",name:"",visible:!0,opacity:100,blendMode:"normal",locked:!1,drawingData:{strokes:[]},transform:{x:0,y:0,width:s,height:t,rotation:0,flipH:!1,flipV:!1}})},[k,w,N,s,t]),l=i.useCallback(()=>{var h;const p=u.current;if(p.length<2){y();return}b("Brush Stroke");const f=M(),C=L.getState().layers.find(R=>R.id===f);if(!C)return;const D={points:[...p],color:d.color,width:d.size,hardness:d.hardness,opacity:d.opacity},E=((h=C.drawingData)==null?void 0:h.strokes)||[];j(f,{drawingData:{strokes:[...E,D]}}),y(),u.current=[]},[d,y,M,b,j]),m=i.useCallback(p=>{if(p.button!==0)return;const f=v(p.clientX,p.clientY);f&&(c.current=!0,u.current=[f])},[v]),x=i.useCallback(p=>{if(!c.current)return;const f=v(p.clientX,p.clientY);if(!f)return;const C=u.current[u.current.length-1];Math.hypot(f.x-C.x,f.y-C.y)<1||(u.current.push(f),_(u.current))},[v,_]),T=i.useCallback(()=>{c.current&&(c.current=!1,l())},[l]);return i.useEffect(()=>{const p=o.current;if(p)return p.addEventListener("mousedown",m),window.addEventListener("mousemove",x),window.addEventListener("mouseup",T),()=>{p.removeEventListener("mousedown",m),window.removeEventListener("mousemove",x),window.removeEventListener("mouseup",T)}},[o,m,x,T]),i.useEffect(()=>{const p=g.current,f=o.current;if(!p||!f)return;const C=new ResizeObserver(D=>{for(const E of D)p.width=E.contentRect.width,p.height=E.contentRect.height});return C.observe(f),p.width=f.clientWidth,p.height=f.clientHeight,()=>C.disconnect()},[o]),e.jsxs(e.Fragment,{children:[e.jsx("canvas",{ref:g,className:"absolute inset-0 z-10 pointer-events-none",style:{width:"100%",height:"100%"}}),e.jsx(Mn,{containerRef:o,size:d.size,zoom:r,color:d.color})]})}function Mn({containerRef:s,size:t,zoom:r,color:n}){const a=i.useRef(null);i.useEffect(()=>{const g=s.current;if(!g)return;const c=d=>{const w=a.current;if(!w)return;const k=g.getBoundingClientRect(),N=d.clientX-k.left,j=d.clientY-k.top;w.style.left=`${N}px`,w.style.top=`${j}px`,w.style.display="block"},u=()=>{const d=a.current;d&&(d.style.display="none")};return g.addEventListener("mousemove",c),g.addEventListener("mouseleave",u),()=>{g.removeEventListener("mousemove",c),g.removeEventListener("mouseleave",u)}},[s]);const o=t*r;return e.jsx("div",{ref:a,className:"absolute z-20 pointer-events-none rounded-full border",style:{width:o,height:o,transform:"translate(-50%, -50%)",borderColor:n==="#ffffff"||n==="#FFFFFF"?"rgba(0,0,0,0.5)":"rgba(255,255,255,0.6)",display:"none"}})}function An(s,t){return{x:(s.x+t.x)/2,y:(s.y+t.y)/2}}function In({canvasWidth:s,canvasHeight:t,zoom:r,panX:n,panY:a,containerRef:o}){const g=i.useRef(null),c=i.useRef(!1),u=i.useRef([]),d=L(f=>f.toolOptions.eraser),w=L(f=>f.activeLayerId),k=L(f=>f.layers),N=L(f=>f.addLayer),j=L(f=>f.updateLayer),b=L(f=>f.pushSnapshot),v="eraser",y=i.useCallback((f,C)=>{const D=o.current;if(!D)return null;const E=D.getBoundingClientRect(),h=f-E.left,R=C-E.top;return{x:(h-n)/r,y:(R-a)/r}},[r,n,a,o]),_=i.useCallback(()=>{const f=g.current;if(!f)return;const C=f.getContext("2d");C&&C.clearRect(0,0,f.width,f.height)},[]),M=i.useCallback(f=>{const C=g.current;if(!C||f.length<2)return;const D=C.getContext("2d");if(!D)return;D.clearRect(0,0,C.width,C.height),D.save(),D.globalAlpha=.6,D.strokeStyle="rgba(255,255,255,0.8)",D.lineWidth=d.size*r,D.lineCap="round",D.lineJoin="round",D.setLineDash([4,4]);const E=R=>R*r+n,h=R=>R*r+a;if(D.beginPath(),f.length===2)D.moveTo(E(f[0].x),h(f[0].y)),D.lineTo(E(f[1].x),h(f[1].y));else{D.moveTo(E(f[0].x),h(f[0].y));for(let S=1;S<f.length-1;S++){const W={x:E(f[S].x),y:h(f[S].y)},F={x:E(f[S+1].x),y:h(f[S+1].y)},B=An(W,F);D.quadraticCurveTo(W.x,W.y,B.x,B.y)}const R=f[f.length-1];D.lineTo(E(R.x),h(R.y))}
679D.stroke(),D.restore()},[d.size,r,n,a]),l=i.useCallback(()=>{const f=k.find(E=>E.id===w);if(f&&f.type==="drawing")return f.id;const C=k.find(E=>E.type==="drawing");return C?C.id:N({type:"drawing",name:"",visible:!0,opacity:100,blendMode:"normal",locked:!1,drawingData:{strokes:[]},transform:{x:0,y:0,width:s,height:t,rotation:0,flipH:!1,flipV:!1}})},[k,w,N,s,t]),m=i.useCallback(()=>{var R;const f=u.current;if(f.length<2){_();return}b("Eraser Stroke");const C=l(),D=L.getState().layers.find(S=>S.id===C);if(!D)return;const E={points:[...f],color:v,width:d.size,hardness:d.hardness,opacity:100},h=((R=D.drawingData)==null?void 0:R.strokes)||[];j(C,{drawingData:{strokes:[...h,E]}}),_(),u.current=[]},[d,_,l,b,j,v]),x=i.useCallback(f=>{if(f.button!==0)return;const C=y(f.clientX,f.clientY);C&&(c.current=!0,u.current=[C])},[y]),T=i.useCallback(f=>{if(!c.current)return;const C=y(f.clientX,f.clientY);if(!C)return;const D=u.current[u.current.length-1];Math.hypot(C.x-D.x,C.y-D.y)<1||(u.current.push(C),M(u.current))},[y,M]),p=i.useCallback(()=>{c.current&&(c.current=!1,m())},[m]);return i.useEffect(()=>{const f=o.current;if(f)return f.addEventListener("mousedown",x),window.addEventListener("mousemove",T),window.addEventListener("mouseup",p),()=>{f.removeEventListener("mousedown",x),window.removeEventListener("mousemove",T),window.removeEventListener("mouseup",p)}},[o,x,T,p]),i.useEffect(()=>{const f=g.current,C=o.current;if(!f||!C)return;const D=new ResizeObserver(E=>{for(const h of E)f.width=h.contentRect.width,f.height=h.contentRect.height});return D.observe(C),f.width=C.clientWidth,f.height=C.clientHeight,()=>D.disconnect()},[o]),e.jsxs(e.Fragment,{children:[e.jsx("canvas",{ref:g,className:"absolute inset-0 z-10 pointer-events-none",style:{width:"100%",height:"100%"}}),e.jsx(Pn,{containerRef:o,size:d.size,zoom:r})]})}function Pn({containerRef:s,size:t,zoom:r}){const n=i.useRef(null);i.useEffect(()=>{const o=s.current;if(!o)return;const g=u=>{const d=n.current;if(!d)return;const w=o.getBoundingClientRect();d.style.left=`${u.clientX-w.left}px`,d.style.top=`${u.clientY-w.top}px`,d.style.display="block"},c=()=>{const u=n.current;u&&(u.style.display="none")};return o.addEventListener("mousemove",g),o.addEventListener("mouseleave",c),()=>{o.removeEventListener("mousemove",g),o.removeEventListener("mouseleave",c)}},[s]);const a=t*r;return e.jsx("div",{ref:n,className:"absolute z-20 pointer-events-none rounded-full border border-dashed",style:{width:a,height:a,transform:"translate(-50%, -50%)",borderColor:"rgba(255,255,255,0.6)",display:"none"}})}function Fn({canvasWidth:s,canvasHeight:t,zoom:r,panX:n,panY:a,containerRef:o}){const{t:g}=q(),[c,u]=i.useState(null),d=i.useRef(null),w=L(x=>x.toolOptions.text),k=L(x=>x.addLayer),N=L(x=>x.pushSnapshot),j=i.useCallback((x,T)=>{const p=o.current;if(!p)return null;const f=p.getBoundingClientRect(),C=x-f.left,D=T-f.top;return{x:(C-n)/r,y:(D-a)/r}},[r,n,a,o]),b=i.useCallback((x,T)=>({x:x*r+n,y:T*r+a}),[r,n,a]),v=i.useCallback((x,T,p)=>{const f=x.trim();if(!f){u(null);return}N("Add Text"),k({type:"text",name:f.substring(0,20)+(f.length>20?"...":""),visible:!0,opacity:100,blendMode:"normal",locked:!1,textData:{content:f,fontSize:w.size,fontFamily:w.font,fontWeight:w.bold?"bold":"normal",fontStyle:w.italic?"italic":"normal",textDecoration:"none",color:w.color,align:w.align,lineHeight:1.4},transform:{x:Math.round(T),y:Math.round(p),width:Math.min(300,s-T),height:w.size*1.5,rotation:0,flipH:!1,flipV:!1}}),u(null)},[w,k,N,s]),y=i.useCallback(x=>{if(c){v(c.content,c.x,c.y);return}if(x.button!==0)return;const T=j(x.clientX,x.clientY);T&&(T.x<0||T.x>=s||T.y<0||T.y>=t||u({x:T.x,y:T.y,content:""}))},[c,j,s,t,v]);i.useEffect(()=>{const x=o.current;if(x)return x.addEventListener("click",y),()=>x.removeEventListener("click",y)},[o,y]),i.useEffect(()=>{c&&d.current&&d.current.focus()},[c]);const _=i.useCallback(x=>
679{x.key==="Enter"&&!x.shiftKey&&!x.nativeEvent.isComposing?(x.preventDefault(),c&&v(c.content,c.x,c.y)):x.key==="Escape"&&(x.preventDefault(),u(null))},[c,v]),M=i.useCallback(()=>{c&&v(c.content,c.x,c.y)},[c,v]);if(!c)return e.jsx("div",{className:"absolute inset-0 z-10",style:{cursor:"text"}});const l=b(c.x,c.y),m=w.size*r;return e.jsx("div",{className:"absolute inset-0 z-10",style:{cursor:"text"},children:e.jsx("textarea",{ref:d,className:"absolute border-2 border-blue-400 outline-none resize-none",style:{left:l.x,top:l.y,minWidth:Math.max(100,200*r),minHeight:m*1.6,maxWidth:`calc(100% - ${l.x}px)`,maxHeight:`calc(100% - ${l.y}px)`,fontSize:m,fontFamily:w.font,fontWeight:w.bold?"bold":"normal",fontStyle:w.italic?"italic":"normal",textAlign:w.align,color:w.color,background:"rgba(0,0,0,0.1)",padding:"4px 6px",lineHeight:1.4,caretColor:w.color},placeholder:g("imageEditor.text.placeholder","Type here..."),value:c.content,onChange:x=>u({...c,content:x.target.value}),onKeyDown:_,onBlur:M,maxLength:1e3})})}function Bn({zoom:s,panX:t,panY:r,containerRef:n}){const[a,o]=i.useState(null),g=i.useRef(!1),c=i.useRef(null),u=L(l=>l.toolOptions.shape),d=L(l=>l.addLayer),w=L(l=>l.pushSnapshot),k=i.useCallback((l,m)=>{const x=n.current;if(!x)return null;const T=x.getBoundingClientRect(),p=l-T.left,f=m-T.top;return{x:(p-t)/s,y:(f-r)/s}},[s,t,r,n]),N=i.useCallback(l=>l*s+t,[s,t]),j=i.useCallback(l=>l*s+r,[s,r]),b=i.useCallback(l=>{const m=Math.min(l.startX,l.currentX),x=Math.min(l.startY,l.currentY),T=Math.max(l.startX,l.currentX),p=Math.max(l.startY,l.currentY),f=T-m,C=p-x;u.type!=="line"&&(f<2||C<2)||u.type==="line"&&Math.hypot(l.currentX-l.startX,l.currentY-l.startY)<2||(w("Add Shape"),u.type==="line"?d({type:"shape",name:"",visible:!0,opacity:100,blendMode:"normal",locked:!1,shapeData:{shapeType:"line",fill:"transparent",stroke:u.stroke,strokeWidth:u.strokeWidth,points:[l.startX-m,l.startY-x,l.currentX-m,l.currentY-x]},transform:{x:Math.round(m),y:Math.round(x),width:Math.max(1,Math.round(f)),height:Math.max(1,Math.round(C)),rotation:0,flipH:!1,flipV:!1}}):d({type:"shape",name:"",visible:!0,opacity:100,blendMode:"normal",locked:!1,shapeData:{shapeType:u.type,fill:u.fill,stroke:u.stroke,strokeWidth:u.strokeWidth},transform:{x:Math.round(m),y:Math.round(x),width:Math.round(f),height:Math.round(C),rotation:0,flipH:!1,flipV:!1}}))},[u,d,w]),v=i.useCallback(l=>{if(l.button!==0)return;const m=k(l.clientX,l.clientY);if(!m)return;const x={startX:m.x,startY:m.y,currentX:m.x,currentY:m.y};g.current=!0,c.current=x,o(x)},[k]),y=i.useCallback(l=>{if(!g.current||!c.current)return;const m=k(l.clientX,l.clientY);if(!m)return;const x={...c.current,currentX:m.x,currentY:m.y};c.current=x,o(x)},[k]),_=i.useCallback(()=>{!g.current||!c.current||(g.current=!1,b(c.current),c.current=null,o(null))},[b]);i.useEffect(()=>{const l=n.current;if(l)return l.addEventListener("mousedown",v),window.addEventListener("mousemove",y),window.addEventListener("mouseup",_),()=>{l.removeEventListener("mousedown",v),window.removeEventListener("mousemove",y),window.removeEventListener("mouseup",_)}},[n,v,y,_]);const M=()=>{if(!a)return null;const l=N(a.startX),m=j(a.startY),x=N(a.currentX),T=j(a.currentY),p=Math.min(l,x),f=Math.min(m,T),C=Math.abs(x-l),D=Math.abs(T-m),E={stroke:u.stroke,strokeWidth:u.strokeWidth*s,fill:u.type==="line"?"none":u.fill,strokeDasharray:"4 4",opacity:.8};return e.jsxs("svg",{className:"absolute inset-0 w-full h-full pointer-events-none z-10",children:[u.type==="rect"&&e.jsx("rect",{x:p,y:f,width:C,height:D,...E}),u.type==="ellipse"&&e.jsx("ellipse",{cx:p+C/2,cy:f+D/2,rx:C/2,ry:D/2,...E}),u.type==="line"&&e.jsx("line",{x1:l,y1:m,x2:x,y2:T,...E})]})};return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"absolute inset-0 z-10",style:{cursor:"crosshair"}}),M()]})}const Un=3,st="selection-marching-ants-style";function Wn(){if(document.getElementById(st))return;const s=document.createElement("style");s.id=st,s.textContent=`
680    @keyframes marching-ants {
681      to { stroke-dashoffset: -16; }
682    }
683    .marching-ants {
684      animation: marching-ants 0.5s linear infinite;
685    }
686  `,document.head.appendChild(s)}function zn(s,t,r,n,a){const{width:o,height:g,data:c}=s,u=Math.round(t),d=Math.round(r);if(u<0||u>=o||d<0||d>=g)return{path:[],bounds:{x:0,y:0,width:0,height:0}};const w=(d*o+u)*4,k=c[w],N=c[w+1],j=c[w+2],b=c[w+3],v=new Uint8Array(o*g),y=p=>{const f=c[p*4],C=c[p*4+1],D=c[p*4+2],E=c[p*4+3];return Math.abs(f-k)+Math.abs(C-N)+Math.abs(D-j)+Math.abs(E-b)<=n*4};{const p=[],f=d*o+u;for(p.push(f),v[f]=1;p.length>0;){const C=p.shift(),D=C%o,E=Math.floor(C/o),h=[{nx:D-1,ny:E},{nx:D+1,ny:E},{nx:D,ny:E-1},{nx:D,ny:E+1}];for(const{nx:R,ny:S}of h){if(R<0||R>=o||S<0||S>=g)continue;const W=S*o+R;v[W]||y(W)&&(v[W]=1,p.push(W))}}}let _=o,M=g,l=0,m=0;for(let p=0;p<g;p++)for(let f=0;f<o;f++)v[p*o+f]&&(_=Math.min(_,f),M=Math.min(M,p),l=Math.max(l,f),m=Math.max(m,p));if(_>l||M>m)return{path:[],bounds:{x:0,y:0,width:0,height:0}};const x={x:_,y:M,width:l-_+1,height:m-M+1};return{path:On(v,o,g,x),bounds:x}}function On(s,t,r,n){const a=[],o=Math.max(0,n.x-1),g=Math.max(0,n.y-1),c=Math.min(t-1,n.x+n.width),u=Math.min(r-1,n.y+n.height);for(let v=g;v<=u;v++)for(let y=o;y<=c;y++){const _=v*t+y;if(!s[_])continue;(y===0||y===t-1||v===0||v===r-1||!s[_-1]||!s[_+1]||!s[(v-1)*t+y]||!s[(v+1)*t+y])&&a.push({x:y,y:v})}if(a.length===0)return[{x:n.x,y:n.y},{x:n.x+n.width,y:n.y},{x:n.x+n.width,y:n.y+n.height},{x:n.x,y:n.y+n.height}];const d=a.reduce((v,y)=>v+y.x,0)/a.length,w=a.reduce((v,y)=>v+y.y,0)/a.length,k=a.map(v=>({...v,angle:Math.atan2(v.y-w,v.x-d)})).sort((v,y)=>v.angle-y.angle),N=200;if(k.length<=N)return k.map(({x:v,y})=>({x:v,y}));const j=k.length/N,b=[];for(let v=0;v<N;v++){const y=Math.floor(v*j);b.push({x:k[y].x,y:k[y].y})}return b}function ot(s){if(s.length===0)return{x:0,y:0,width:0,height:0};let t=1/0,r=1/0,n=-1/0,a=-1/0;
686for(const o of s)t=Math.min(t,o.x),r=Math.min(r,o.y),n=Math.max(n,o.x),a=Math.max(a,o.y);return{x:t,y:r,width:n-t,height:a-r}}function $e(s){let t=s.startX,r=s.startY,n=s.currentX,a=s.currentY;if(s.shiftKey){const d=n-t,w=a-r,k=Math.max(Math.abs(d),Math.abs(w));n=t+k*Math.sign(d||1),a=r+k*Math.sign(w||1)}const o=Math.min(t,n),g=Math.min(r,a),c=Math.max(t,n),u=Math.max(r,a);return[{x:o,y:g},{x:c,y:g},{x:c,y:u},{x:o,y:u}]}function Hn({canvasWidth:s,canvasHeight:t,zoom:r,panX:n,panY:a,containerRef:o}){const{t:g}=q(),c=L(P=>P.activeTool),u=L(P=>P.toolOptions.selection),d=L(P=>P.selection),w=L(P=>P.setSelection),k=L(P=>P.clearSelection),N=L(P=>P.sourceImage),[j,b]=i.useState(null),[v,y]=i.useState([]),[_,M]=i.useState(!1),[l,m]=i.useState(!1),x=i.useRef(!1),T=i.useRef(null),p=i.useRef([]),f=i.useRef(c);i.useEffect(()=>{f.current=c},[c]),i.useEffect(()=>{Wn()},[]);const C=i.useCallback((P,U)=>{const H=o.current;if(!H)return null;const I=H.getBoundingClientRect(),G=P-I.left,Q=U-I.top;return{x:(G-n)/r,y:(Q-a)/r}},[r,n,a,o]),D=i.useCallback(P=>P*r+n,[r,n]),E=i.useCallback(P=>P*r+a,[r,a]),h=i.useCallback((P,U)=>{if(P.length===0)return"";const H=P.map((I,G)=>{const Q=D(I.x),A=E(I.y);return G===0?`M ${Q} ${A}`:`L ${Q} ${A}`});return U&&H.push("Z"),H.join(" ")},[D,E]),R=i.useCallback(()=>new Promise(P=>{if(!N){P(null);return}const U=new Image;U.crossOrigin="anonymous",U.onload=()=>{const H=document.createElement("canvas");H.width=U.naturalWidth,H.height=U.naturalHeight;const I=H.getContext("2d");if(!I){P(null);return}I.drawImage(U,0,0);const G=I.getImageData(0,0,H.width,H.height);P(G)},U.onerror=()=>P(null),U.src=N}),[N]),S=i.useCallback(P=>{const U=$e(P),H=ot(U);if(H.width<2||H.height<2)return;w({type:"rect",path:U,bounds:H})},[w]),W=i.useCallback(P=>{if(P.length<3)return;const U=ot(P);if(U.width<2||U.height<2)return;w({type:"lasso",path:P,bounds:U})},[w]),F=i.useCallback(async P=>{m(!0);try{const U=await R();if(!U)return;const H=u.tolerance,I=!0,{path:G,bounds:Q}=zn(U,P.x,P.y,H,I);if(G.length===0)return;w({type:"magic-wand",path:G,bounds:Q})}finally{m(!1)}},[R,u.tolerance,w]),B=i.useCallback(P=>{if(P.button!==0)return;const U=C(P.clientX,P.clientY);if(!U)return;const H=f.current;if(H==="rect-select"){const I={startX:U.x,startY:U.y,currentX:U.x,currentY:U.y,shift
686Key:P.shiftKey};x.current=!0,T.current=I,b(I),M(!0)}else H==="lasso"?(x.current=!0,p.current=[U],y([U]),M(!0)):H==="magic-wand"&&F(U)},[C,F]),O=i.useCallback(P=>{if(!x.current)return;const U=C(P.clientX,P.clientY);if(!U)return;const H=f.current;if(H==="rect-select"&&T.current){const I={...T.current,currentX:U.x,currentY:U.y,shiftKey:P.shiftKey};T.current=I,b(I)}else if(H==="lasso"){const I=p.current,G=I[I.length-1];if(Math.hypot(U.x-G.x,U.y-G.y)>=Un){const A=[...I,U];p.current=A,y(A)}}},[C]),X=i.useCallback(()=>{if(!x.current)return;x.current=!1,M(!1);const P=f.current;P==="rect-select"&&T.current?(S(T.current),T.current=null,b(null)):P==="lasso"&&(W(p.current),p.current=[],y([]))},[S,W]);i.useEffect(()=>{const P=U=>{const H=U.metaKey||U.ctrlKey;if(U.key==="Escape"){U.preventDefault(),k();return}if(H&&U.key==="a"&&!U.shiftKey){U.preventDefault(),w({type:"rect",path:[{x:0,y:0},{x:s,y:0},{x:s,y:t},{x:0,y:t}],bounds:{x:0,y:0,width:s,height:t}});return}if(H&&U.shiftKey&&(U.key==="i"||U.key==="I")){U.preventDefault(),d?k():w({type:"rect",path:[{x:0,y:0},{x:s,y:0},{x:s,y:t},{x:0,y:t}],bounds:{x:0,y:0,width:s,height:t}});return}};return window.addEventListener("keydown",P),()=>window.removeEventListener("keydown",P)},[s,t,d,w,k]),i.useEffect(()=>{const P=o.current;if(P)return P.addEventListener("mousedown",B),window.addEventListener("mousemove",O),window.addEventListener("mouseup",X),()=>{P.removeEventListener("mousedown",B),window.removeEventListener("mousemove",O),window.removeEventListener("mouseup",X)}},[o,B,O,X]);const $=()=>{if(!j)return null;const P=$e(j),U=D(P[0].x),H=E(P[0].y),I=(P[1].x-P[0].x)*r,G=(P[2].y-P[1].y)*r;return e.jsxs("g",{children:[e.jsx("rect",{x:U,y:H,width:Math.abs(I),height:Math.abs(G),fill:"rgba(59, 130, 246, 0.15)",stroke:"none"}),e.jsx("rect",{x:U,y:H,width:Math.abs(I),height:Math.abs(G),fill:"none",stroke:"white",strokeWidth:1,strokeDasharray:"6 4"}),e.jsx("rect",{x:U,y:H,width:Math.abs(I),height:Math.abs(G),fill:"none",stroke:"rgba(0,0,0,0.6)",strokeWidth:1,strokeDasharray:"6 4",strokeDashoffset:6})]})},te=()=>{if(v.length<2)return null;const P=h(v,!1);return e.jsxs("g",{children:[e.jsx("path",{d:P,fill:"none",stroke:"white",strokeWidth:1.5,strokeDasharray:"6 4",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:P,fill:"none",stroke:"rgba(0,0,0,0.5)",strokeWidth:1.5,strokeDasharray:"6 4",strokeDashoffset:6,strokeLinecap:"round",strokeLinejoin:"round"}),v.length>2&&e.jsx("line",{x1:D(v[v.length-1].x),y1:E(v[v.length-1].y),x2:D(v[0].x),y2:E(v[0].y),stroke:"rgba(255,255,255,0.4)",strokeWidth:1,strokeDasharray:"4 4"})]})},J=()=>{if(!d||_)return null;const P=h(d.path,!0);return e.jsxs("g",{children:[e.jsx("path",{d:P,fill:"rgba(59, 130, 246, 0.08)",stroke:"none"}),e.jsx("path",{d:P,fill:"none",stroke:"white",strokeWidth:1}),e.jsx("path",{d:P,fill:"none",stroke:"rgba(0,0,0,0.7)",strokeWidth:1,strokeDasharray:"8 8",className:"marching-ants"})]})},re=()=>l?"wait":"crosshair";return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"absolute inset-0 z-10",style:{cursor:re()}}),e.jsxs("svg",{className:"absolute inset-0 w-full h-full pointer-events-none z-10",style:{overflow:"visible"},children:[J(),c==="rect-select"&&$(),c==="lasso"&&te()]}),l&&e.jsx("div",{className:"absolute top-4 left-1/2 -translate-x-1/2 z-20 px-3 py-1.5 rounded-md text-xs font-medium",style:{background:"rgba(0,0,0,0.75)",color:"white"},children:g("imageEditor.selection.processing","Processing...")}),j&&e.jsx(Xn,{drag:j,toScreenX:D,toScreenY:E})]})}function Xn({drag:s,toScreenX:t,toScreenY:r}){const n=$e(s),a=Math.round(Math.abs(n[1].x-n[0].x)),o=Math.round(Math.abs(n[2].y-n[1].y));if(a<2&&o<2)return null;const g=r(n[2].y),c=(t(n[0].x)+t(n[1].x))/2;return e.jsxs("div",{className:"absolute z-20 px-2 py-1 rounded text-xs font-mono pointer-events-none",style:{left:c,top:g+8,transform:"translateX(-50%)",background:"rgba(0,0,0,0.75)",color:"white",whiteSpace:"nowrap"},children:[a," x ",o]})}const $n=3e4;function Gn(s){return s.map(t=>{const r={...t,transform:{...t.transform}};return r.mask&&typeof r.mask!="string"&&delete r.mask,r.adjustments&&(r.adjustments=r.adjustments.map(n=>({...n}))),r.textData&&(r.textData={...r.textData}),r.shapeData&&(r.shapeData={...r.shapeData}),r.drawingData&&(r.drawingData={strokes:r.drawingData.strokes.map(n=>({...n,points:n.points.map(a=>({...a}))}))}),r})}function Yn(){const{t:s}=q(),[t,r]=i.useState(null),[n,a]=i.useState(!1),[o,g]=i.useState(null),[c,u]=i.useState(!0),d=i.useRef(""),w=L(m=>m.sourceImage),k=L(m=>
686m.layers),N=L(m=>m.canvasWidth),j=L(m=>m.canvasHeight),b=L(m=>m.activeLayerId),v=L(m=>m.isDirty),y=L(m=>m.setDirty),_=L(m=>m.loadImage),M=i.useCallback(async()=>{var p,f;if(!w)return null;const m=Gn(k),x={sourceImage:w,layers:m,metadata:{canvasWidth:N,canvasHeight:j,activeLayerId:b}},T=JSON.stringify(x);if(T===d.current)return t;a(!0);try{const C=await he.post("/image/editor/save",{projectId:t||void 0,sourceImage:x.sourceImage,layers:x.layers,metadata:x.metadata}),D=((p=C.data)==null?void 0:p.projectId)||((f=C.data)==null?void 0:f.id)||t;return D&&r(D),g(Date.now()),y(!1),d.current=T,D}catch(C){return console.error("Failed to save project:",C),Z.error(s("imageEditor.save.failed","Failed to save project")),null}finally{a(!1)}},[w,k,N,j,b,t,y,s]),l=i.useCallback(async m=>{try{const T=(await he.get(`/image/editor/${m}`)).data;if(!T)return!1;const{sourceImage:p,layers:f,metadata:C}=T;if(p){const E=new Image;E.crossOrigin="anonymous",await new Promise((h,R)=>{E.onload=()=>{_(p,(C==null?void 0:C.canvasWidth)||E.naturalWidth,(C==null?void 0:C.canvasHeight)||E.naturalHeight),h()},E.onerror=()=>R(new Error("Failed to load image")),E.src=p})}if(f&&Array.isArray(f)){const E=L.getState();for(const h of E.layers)E.removeLayer(h.id);for(const h of f)E.addLayer(h);C!=null&&C.activeLayerId&&E.setActiveLayer(C.activeLayerId)}r(m),g(Date.now()),y(!1);const D={sourceImage:p,layers:f||[],metadata:C||{canvasWidth:0,canvasHeight:0,activeLayerId:""}};return d.current=JSON.stringify(D),!0}catch(x){return console.error("Failed to load project:",x),Z.error(s("imageEditor.save.loadFailed","Failed to load project")),!1}},[_,y,s]);return i.useEffect(()=>{if(!c||!w)return;const m=setInterval(()=>{L.getState().isDirty&&M()},$n);return()=>clearInterval(m)},[c,w,M]),{projectId:t,setProjectId:r,isSaving:n,lastSaved:o,autoSaveEnabled:c,setAutoSaveEnabled:u,save:M,load:l,isDirty:v}}function Kn(s){const{t}=q(),r=Vt(),[n,a]=i.useState(!1),[o,g]=i.useState(!1),c=L(b=>b.loadImage),u=L(b=>b.sourceImage),d=L(b=>b.canvasWidth),w=L(b=>b.canvasHeight),k=i.useCallback(async()=>{if(s){g(!0);try{const v=(await he.get(`/art/projects/${s.projectId}`)).data;if(!(v!=null&&v.elements))throw new Error("Project or elements not found");const y=v.elements.find(m=>m.id===s.elementId);if(!y)throw new Error("Element not found in project");const _=y.data,M=(_!=null&&_.images?_.images[_.coverIndex??0]||_.images[0]:null)||(_==null?void 0:_.resolvedUrl)||(_==null?void 0:_.url);if(!M)throw new Error("Element has no image URL");const l=new Image;l.crossOrigin="anonymous",await new Promise((m,x)=>{l.onload=()=>{c(M,l.naturalWidth,l.naturalHeight),m()},l.onerror=()=>x(new Error("Failed to load image from Art element")),l.src=M})}catch(b){console.error("Failed to load from Art:",b),Z.error(t("imageEditor.art.loadFailed","Failed to load image from Art"))}finally{g(!1)}}},[s,c,t]);i.useEffect(()=>{s&&!u&&k()},[s]);const N=i.useCallback(async()=>{var b;if(s){a(!0);try{const v=document.querySelector(".image-editor-canvas canvas, .editor-canvas canvas");let y;if(v)y=await new Promise((m,x)=>{v.toBlob(T=>{T?m(T):x(new Error("Canvas export failed"))},"image/png",1)});else{const m=new Image;m.crossOrigin="anonymous",await new Promise((p,f)=>{m.onload=()=>p(),m.onerror=()=>f(new Error("Failed to load source image")),m.src=u||""});const x=document.createElement("canvas");x.width=d||m.naturalWidth,x.height=w||m.naturalHeight;const T=x.getContext("2d");if(!T)throw new Error("Cannot create canvas context");T.drawImage(m,0,0,x.width,x.height),y=await new Promise((p,f)=>{x.toBlob(C=>{C?p(C):f(new Error("Canvas export failed"))},"image/png",1)})}const _=new File([y],`edited-${s.elementId}.png`,{type:"image/png"}),l=(b=(await qt.uploadImage(_)).data)==null?void 0:b.url;if(!l)throw new Error("No URL returned from upload");await he.patch(`/art/projects/${s.projectId}/elements/${s.elementId}`,{assetId:"",data:{assetId:"",url:l,originalWidth:d,originalHeight:w,resolvedUrl:void 0,persistenceStatus:void 0}}),Z.success(t("imageEditor.art.applySuccess","Applied changes to Art canvas")),r(`/art/${s.projectId}`)}catch(v){console.error("Failed to apply to Art:",v),Z.error(t("imageEditor.art.applyFailed","Failed to apply changes to Art"))}finally{a(!1)}}},[s,u,d,w,r,t]),j=i.useCallback(()=>{s&&r(`/art/${s.projectId}`)},[s,r]);return{isApplying:n,isLoadingFromArt:o,loadFromArt:k,applyToArt:N,returnToArt:j}}function Vn({artSource:s,initialImageUrl:t}){const{t:r}=q(),n=i.useRef(null),a=i.useRef(null),o=i.useRef(null),[g,c]=i.useState(!1),[u,d]=i.useState(!1),w=L(I=>I.sourceImage),k=L(I=>I.canvasWidth),N=L(I=>I.canvasHeight),j=L(I=>I.zoom),b=L(I=>I.panX),v=L(I=>I.panY),y=L(I=>I.activeTool),_=L(I=>I.loadImage),M=L(I=>I.setArtSource),l=L(I=>I.setActiveTool),m=L(I=>I.activePanel),x=L(I=>I.updateLayer),T=L(I=>I.activeLayerId),p=L(I=>I.pushSnapshot),f=L(I=>I.reset),C=Yn(),D=Kn(s||null);i.useEffect(()=>{f(),s&&M(s)},[]),i.useEffect(()=>{t&&!w&&!s&&E(t)},[t]);const E=i.useCallback(I=>{const G=new Image;G.crossOrigin="anonymous",G.onload=()=>
686{_(I,G.naturalWidth,G.naturalHeight)},G.onerror=()=>{console.error("Failed to load image from URL:",I)},G.src=I},[_]),h=i.useCallback(I=>{if(!I.type.startsWith("image/"))return;const G=URL.createObjectURL(I),Q=new Image;Q.onload=()=>{_(G,Q.naturalWidth,Q.naturalHeight)},Q.src=G},[_]),R=i.useCallback(I=>{var Q;const G=(Q=I.target.files)==null?void 0:Q[0];G&&h(G),I.target.value=""},[h]),S=i.useCallback(I=>{I.preventDefault(),I.stopPropagation(),c(!0)},[]),W=i.useCallback(I=>{I.preventDefault(),I.stopPropagation(),c(!1)},[]),F=i.useCallback(I=>{var Q;I.preventDefault(),I.stopPropagation(),c(!1);const G=(Q=I.dataTransfer.files)==null?void 0:Q[0];G&&h(G)},[h]),B=i.useCallback(()=>{var I;(I=n.current)==null||I.click()},[]),O=i.useCallback(I=>{T&&(p("Crop"),x(T,{transform:{x:I.x,y:I.y,width:I.width,height:I.height,rotation:0,flipH:!1,flipV:!1}}),l("move"))},[T,p,x,l]),X=i.useCallback(()=>{l("move")},[l]),$=o.current,te=($==null?void 0:$.clientWidth)??0,J=($==null?void 0:$.clientHeight)??0,re=k*j,P=N*j,U=(te-re)/2+b,H=(J-P)/2+v;return w?e.jsxs("div",{className:"h-full w-full flex flex-col overflow-hidden",style:{background:"var(--bg-base)"},children:[e.jsx(_r,{onExport:()=>d(!0),artSource:s||null,onApplyToArt:D.applyToArt,onReturnToArt:D.returnToArt,isApplyingToArt:D.isApplying,onSave:C.save,isSaving:C.isSaving,lastSaved:C.lastSaved}),e.jsxs("div",{className:"flex-1 flex min-h-0",children:[e.jsx(Er,{}),e.jsxs("div",{ref:o,className:"relative flex-1 overflow-hidden",children:[e.jsx(Gr,{}),(y==="rect-select"||y==="lasso"||y==="magic-wand")&&w&&e.jsx(Hn,{canvasWidth:k,canvasHeight:N,zoom:j,panX:U,panY:H,containerRef:o}),y==="crop"&&w&&e.jsx(Rn,{canvasWidth:k,canvasHeight:N,zoom:j,panX:U,panY:H,onApply:O,onCancel:X}
686),y==="brush"&&w&&e.jsx(Dn,{canvasWidth:k,canvasHeight:N,zoom:j,panX:U,panY:H,containerRef:o}),y==="eraser"&&w&&e.jsx(In,{canvasWidth:k,canvasHeight:N,zoom:j,panX:U,panY:H,containerRef:o}),y==="text"&&w&&e.jsx(Fn,{canvasWidth:k,canvasHeight:N,zoom:j,panX:U,panY:H,containerRef:o}),y==="shape"&&w&&e.jsx(Bn,{canvasWidth:k,canvasHeight:N,zoom:j,panX:U,panY:H,containerRef:o})]}),m&&e.jsxs("div",{className:"w-72 border-l flex flex-col",style:{background:"var(--bg-secondary)",borderColor:"var(--border-default)"},children:[(m==="adjust"||m==="filter")&&e.jsx("div",{className:"p-4 border-b",style:{borderColor:"var(--border-default)"},children:e.jsx("h3",{className:"text-sm font-medium",style:{color:"var(--text-primary)"},children:r(`imageEditor.panels.${m}`)})}),e.jsxs("div",{className:"flex-1 overflow-y-auto min-h-0",children:[m==="adjust"&&e.jsx(sn,{}),m==="filter"&&e.jsx(cn,{}),m==="layers"&&e.jsx(gn,{}),m==="history"&&e.jsx(fn,{}),m==="ai"&&e.jsx(yn,{})]})]})]}),e.jsx(Yr,{open:u,onClose:()=>d(!1)})]}):e.jsxs("div",{className:"h-full w-full flex items-center justify-center",style:{background:"var(--bg-base)"},children:[e.jsx("input",{ref:n,type:"file",accept:"image/*",className:"hidden",onChange:R}),e.jsxs("div",{ref:a,onClick:B,onDragOver:S,onDragLeave:W,onDrop:F,className:`
687            flex flex-col items-center justify-center gap-6 p-16 rounded-2xl border-2 border-dashed
688            cursor-pointer transition-all duration-200
689            ${g?"border-blue-400 bg-blue-500/10 scale-[1.02]":"border-white/10 hover:border-white/20 hover:bg-white/5"}
690          `,style:{maxWidth:"480px"},children:[e.jsx("div",{className:"w-20 h-20 rounded-2xl flex items-center justify-center",style:{background:"var(--bg-tertiary)"},children:g?e.jsx(Ge,{size:36,className:"text-blue-400"}):e.jsx(Zt,{size:36,style:{color:"var(--text-secondary)"}})}),e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-base font-medium mb-2",style:{color:"var(--text-primary)"},children:r("imageEditor.dropzone.title","Drop image here or click to upload")}),e.jsx("p",{className:"text-sm",style:{color:"var(--text-secondary)"},children:r("imageEditor.dropzone.subtitle","Supports PNG, JPG, WebP, BMP, GIF")})]}),e.jsx("button",{className:"px-6 py-2.5 rounded-lg text-sm font-medium transition-colors bg-blue-500 hover:bg-blue-600 text-white",children:r("imageEditor.dropzone.browse","Browse Files")})]})]})}function wa(){const[s]=Jt(),t=s.get("source"),r=s.get("projectId"),n=s.get("elementId"),a=s.get("imageUrl");return e.jsx("div",{className:"h-full w-full overflow-hidden",style:{background:"var(--bg-base)"},children:e.jsx(Vn,{artSource:t==="art"?{projectId:r,elementId:n}:void 0,initialImageUrl:a||void 0})})}export{wa as default};

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.