@antontranelis/money-printer 1.0.23 → 1.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,11 +1,11 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),mt=require("zustand"),gt=require("zustand/middleware"),m=require("react"),ft=require("jspdf");var ne=typeof document<"u"?document.currentScript:null;const He={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de",templateHue:160},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,panX:0,panY:0,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1},b=mt.create()(gt.persist(e=>({...He,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>e(r=>({portrait:{...r.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:r.portrait.original&&t?r.portrait.zoom:1,panX:r.portrait.original&&t?r.portrait.panX:0,panY:r.portrait.original&&t?r.portrait.panY:0}})),setEnhancedPortrait:t=>e(n=>({portrait:{...n.portrait,enhanced:t,useEnhanced:t!==null}})),toggleUseEnhanced:()=>e(t=>({portrait:{...t.portrait,useEnhanced:t.portrait.enhanced?!t.portrait.useEnhanced:!1}})),setPortraitZoom:t=>e(n=>({portrait:{...n.portrait,zoom:t}})),setPortraitPan:(t,n)=>e(r=>({portrait:{...r.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>e(r=>({portrait:{...r.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:r.portrait.bgRemovedImage}})),setPortraitBgOpacity:t=>e(n=>({portrait:{...n.portrait,bgOpacity:t}})),setPortraitBgBlur:t=>e(n=>({portrait:{...n.portrait,bgBlur:t}})),setPortraitEngravingIntensity:t=>e(n=>({portrait:{...n.portrait,engravingIntensity:t}})),setCurrentSide:t=>e({currentSide:t}),flipSide:()=>e(t=>({currentSide:t.currentSide==="front"?"back":"front"})),setIsEnhancing:t=>e({isEnhancing:t}),setIsExporting:t=>e({isExporting:t}),setLanguage:t=>e(n=>({voucherConfig:{...n.voucherConfig,language:t}})),setHours:t=>e(n=>({voucherConfig:{...n.voucherConfig,hours:t}})),setTemplateHue:t=>e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}})),reset:()=>e(He)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig,portrait:{original:null,enhanced:null,useEnhanced:e.portrait.useEnhanced,zoom:e.portrait.zoom,panX:e.portrait.panX,panY:e.portrait.panY,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:e.portrait.engravingIntensity}})})),bt={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?"},billColor:{title:"Scheinfarbe",label:"Farbton"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},xt={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},wt={de:bt,en:xt};function F(e){return wt[e]}function Te(e,t,n){if(n&&n.trim())return n;const r=F(e),a=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",a)}function yt(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.personalInfo),n=b(a=>a.setPersonalInfo),r=F(e);return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),o.jsx("input",{type:"text",placeholder:r.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:a=>n({name:a.target.value})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),o.jsx("input",{type:"email",placeholder:r.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:a=>n({email:a.target.value})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),o.jsx("input",{type:"tel",placeholder:r.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:a=>n({phone:a.target.value})})]})]})}const vt=1024,ee=new Map;let W=null,De=null;function je(e,t){return W||(W=document.createElement("canvas"),De=W.getContext("2d",{willReadFrequently:!0})),(W.width!==e||W.height!==t)&&(W.width=e,W.height=t),De}function ie(e){const t=ee.get(e);return t?Promise.resolve(t):new Promise((n,r)=>{const a=new Image;a.onload=()=>{if(ee.size>10){const i=ee.keys().next().value;i&&ee.delete(i)}ee.set(e,a),n(a)},a.onerror=()=>r(new Error("Failed to load image")),a.src=e})}function It(){ee.clear()}async function kt(e,t=vt){const n=await ie(e),r=Math.max(n.width,n.height);if(r<=t)return e;const a=t/r,i=Math.round(n.width*a),s=Math.round(n.height*a),d=document.createElement("canvas"),c=d.getContext("2d");if(!c)throw new Error("Failed to get canvas context");return d.width=i,d.height=s,c.drawImage(n,0,0,i,s),d.toDataURL("image/jpeg",.9)}async function ye(e,t,n,r=0){const[a,i]=await Promise.all([ie(e),ie(t)]),s=je(a.width,a.height);if(s.clearRect(0,0,a.width,a.height),n>0){const d=r*20;s.save(),s.globalAlpha=n,d>0&&(s.filter=`blur(${d}px)`),s.drawImage(i,0,0,a.width,a.height),s.restore()}return s.drawImage(a,0,0),W.toDataURL("image/png")}async function _e(e,t=.5){const n=await ie(e),r=je(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),i=a.data,s=new Uint32Array(i.buffer),d=1+t*.8,c=1-t;for(let u=0;u<s.length;u++){const p=s[u],h=p&255,w=p>>8&255,g=p>>16&255,v=p>>24&255;if(v===0)continue;let k=(((77*h+150*w+29*g>>8)/255-.5)*d+.5)*255;k<0?k=0:k>255&&(k=255);let P=k*.9+25,j=k*.78+15,I=k*.55+5;P>255&&(P=255),j>255&&(j=255),I>255&&(I=255);const C=h*c+P*t|0,R=w*c+j*t|0,H=g*c+I*t|0;s[u]=v<<24|H<<16|R<<8|C}return r.putImageData(a,0,0),W.toDataURL("image/png")}function Pt(e,t,n){e/=255,t/=255,n/=255;const r=Math.max(e,t,n),a=Math.min(e,t,n),i=(r+a)/2;let s=0,d=0;if(r!==a){const c=r-a;switch(d=i>.5?c/(2-r-a):c/(r+a),r){case e:s=((t-n)/c+(t<n?6:0))/6;break;case t:s=((n-e)/c+2)/6;break;case n:s=((e-t)/c+4)/6;break}}return[s,d,i]}function Ct(e,t,n){if(t===0){const s=Math.round(n*255);return[s,s,s]}const r=(s,d,c)=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?s+(d-s)*6*c:c<1/2?d:c<2/3?s+(d-s)*(2/3-c)*6:s),a=n<.5?n*(1+t):n+t-n*t,i=2*n-a;return[Math.round(r(i,a,e+1/3)*255),Math.round(r(i,a,e)*255),Math.round(r(i,a,e-1/3)*255)]}async function ze(e,t){if(t>=155&&t<=165)return e;const n=await ie(e),r=je(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),i=a.data,s=new Uint32Array(i.buffer),d=t%360/360,c=60/360,u=260/360,p=1e5,h=s.length;for(let w=0;w<h;w+=p){const g=Math.min(w+p,h);for(let v=w;v<g;v++){const x=s[v],k=x&255,P=x>>8&255,j=x>>16&255,I=x>>24&255;if(I===0)continue;const[C,R,H]=Pt(k,P,j);if(R<.06||C<c||C>u)continue;const B=d,[N,_,E]=Ct(B,R,H);s[v]=I<<24|E<<16|_<<8|N}g<h&&await new Promise(v=>setTimeout(v,0))}return r.putImageData(a,0,0),W.toDataURL("image/png")}const Tt="https://api.stability.ai/v1/generation",jt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",We="stability_api_key";let ae=null;function St(e){ae=e}function Rt(){return ae}function Et(){return ae!==null}const Bt={vintage:"portrait in the style of vintage currency engraving, fine line work, crosshatching, sepia tones, detailed stippling, classic bank note portrait style",engraved:"portrait as detailed intaglio engraving, currency bill style, fine parallel lines, high contrast, official government portrait",currency:"portrait rendered as US dollar bill engraving, official currency portrait style, green tint, fine line engraving technique"},Me=[{width:1024,height:1024},{width:1152,height:896},{width:1216,height:832},{width:1344,height:768},{width:1536,height:640},{width:640,height:1536},{width:768,height:1344},{width:832,height:1216},{width:896,height:1152}];function Nt(e,t){const n=e/t;let r=Me[0],a=1/0;for(const i of Me){const s=i.width/i.height,d=Math.abs(n-s);d<a&&(a=d,r=i)}return r}function Lt(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{const a=Nt(r.width,r.height),i=document.createElement("canvas");i.width=a.width,i.height=a.height;const s=i.getContext("2d");if(!s){n(new Error("Failed to get canvas context"));return}const d=r.width/r.height,c=a.width/a.height;let u=0,p=0,h=r.width,w=r.height;d>c?(h=r.height*c,u=(r.width-h)/2):(w=r.width/c,p=(r.height-w)/2),s.drawImage(r,u,p,h,w,0,0,a.width,a.height),t(i.toDataURL("image/png"))},r.onerror=()=>n(new Error("Failed to load image")),r.src=e})}function Xe(e){var s;const t=e.split(","),n=((s=t[0].match(/:(.*?);/))==null?void 0:s[1])||"image/png",r=atob(t[1]),a=r.length,i=new Uint8Array(a);for(let d=0;d<a;d++)i[d]=r.charCodeAt(d);return new Blob([i],{type:n})}function he(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.src||new URL("index.cjs",document.baseURI).href}<"u"&&"sk-7mEKklrqaltdtgbX0VoZbkA8E1cl939Spn75jSIYRvp1BW0b"||typeof process<"u"&&((t=process.env)==null?void 0:t.NEXT_PUBLIC_STABILITY_API_KEY);return e&&e!=="your-api-key-here"?e:typeof localStorage<"u"?localStorage.getItem(We):null}function $e(e){localStorage.setItem(We,e)}function Pe(){return ae?!0:he()!==null}async function Ht(e){const t=he();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,i=await Lt(n),s=Xe(i),d=new FormData;d.append("init_image",s,"portrait.png"),d.append("init_image_mode","IMAGE_STRENGTH"),d.append("image_strength",String(1-a)),d.append("text_prompts[0][text]",Bt[r]),d.append("text_prompts[0][weight]","1"),d.append("cfg_scale","7"),d.append("samples","1"),d.append("steps","30");const u=await fetch(`${Tt}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:d});if(!u.ok){const h=await u.text();throw console.error("Stability AI error:",h),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const p=await u.json();if(!p.artifacts||p.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${p.artifacts[0].base64}`}async function Oe(e){if(ae){const s=await fetch(ae,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!s.ok){const c=await s.json().catch(()=>({}));throw new Error(c.error||`API error: ${s.status}`)}return(await s.json()).imageDataUrl}const t=he();if(!t)throw new Error("No Stability AI API key configured");const n=Xe(e),r=new FormData;r.append("image",n,"image.png"),r.append("output_format","png");const a=await fetch(jt,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:r});if(!a.ok){const s=await a.text();throw console.error("Stability AI remove background error:",s),a.status===401?new Error("Invalid API key"):a.status===402?new Error("Insufficient credits"):a.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${a.status}`)}const i=await a.blob();return new Promise((s,d)=>{const c=new FileReader;c.onload=()=>s(c.result),c.onerror=()=>d(new Error("Failed to read result")),c.readAsDataURL(i)})}function Dt(){const[e,t]=m.useState(!1),[n,r]=m.useState(!1),[a,i]=m.useState(null),[s,d]=m.useState(()=>Pe());m.useEffect(()=>{d(Pe())},[]);const c=m.useCallback(()=>i(null),[]),u=m.useCallback(w=>{$e(w),d(!0),i(null)},[]),p=m.useCallback(async(w,g=.5)=>{t(!0),i(null);try{return await _e(w,g)}catch(v){const x=v instanceof Error?v.message:"Enhancement failed";throw i(x),v}finally{t(!1)}},[]),h=m.useCallback(async w=>{r(!0),i(null);try{return await Oe(w)}catch(g){const v=g instanceof Error?g.message:"Background removal failed";throw i(v),g}finally{r(!1)}},[]);return{enhance:p,removeBg:h,isEnhancing:e,isRemovingBg:n,error:a,hasKey:s,setApiKey:u,clearError:c}}function Fe({isOpen:e,onClose:t,onSubmit:n}){const r=b(u=>u.voucherConfig.language),[a,i]=m.useState("");if(!e)return null;const s=u=>{u.preventDefault(),a.trim()&&(n(a.trim()),i(""),t())},c={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[r];return o.jsxs("dialog",{className:"modal modal-open",children:[o.jsxs("div",{className:"modal-box",children:[o.jsx("h3",{className:"font-bold text-lg",children:c.title}),o.jsx("p",{className:"py-4 text-sm opacity-80",children:c.description}),o.jsxs("form",{onSubmit:s,children:[o.jsxs("div",{className:"form-control",children:[o.jsx("input",{type:"password",placeholder:c.placeholder,className:"input input-bordered w-full",value:a,onChange:u=>i(u.target.value),autoFocus:!0}),o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text-alt",children:c.hint})})]}),o.jsxs("div",{className:"modal-action",children:[o.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:c.cancel}),o.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:c.submit})]})]})]}),o.jsx("form",{method:"dialog",className:"modal-backdrop",children:o.jsx("button",{onClick:t,children:"close"})})]})}function Mt(){const e=b(l=>l.voucherConfig.language),t=b(l=>l.portrait),n=b(l=>l.setPortrait),r=b(l=>l.setPortraitZoom),a=b(l=>l.setPortraitPan),i=b(l=>l.setPortraitRawImage),s=b(l=>l.setPortraitBgRemoved),d=b(l=>l.setPortraitBgOpacity),c=b(l=>l.setPortraitBgBlur),u=b(l=>l.setPortraitEngravingIntensity),{enhance:p,removeBg:h,isEnhancing:w,isRemovingBg:g,error:v,hasKey:x,setApiKey:k}=Dt(),P=F(e),j=m.useRef(null),I=m.useRef(null),[C,R]=m.useState(!1),[H,B]=m.useState(!1),[N,_]=m.useState(!1),E=m.useRef(null),D=m.useRef(null),M=m.useRef(null),S=t.rawImage,z=t.bgRemovedImage,A=t.bgRemoved,X=t.bgOpacity,V=t.bgBlur,se=t.engravingIntensity;m.useEffect(()=>{t.original&&!t.rawImage&&i(t.original)},[t.original,t.rawImage,i]),m.useEffect(()=>()=>{D.current&&clearTimeout(D.current),M.current&&clearTimeout(M.current)},[]);const re=m.useCallback(async l=>{if(!l.type.startsWith("image/"))return;const y=new FileReader;y.onload=async T=>{var ue;const U=(ue=T.target)==null?void 0:ue.result,de=await kt(U);i(de),n(de),s(!1,null),u(0)},y.readAsDataURL(l)},[n,i,s,u]),ge=m.useCallback(l=>{l.preventDefault(),R(!1);const y=l.dataTransfer.files[0];y&&re(y)},[re]),f=m.useCallback(l=>{l.preventDefault(),R(!0)},[]),L=m.useCallback(l=>{l.preventDefault(),R(!1)},[]),$=()=>{var l;(l=j.current)==null||l.click()},Z=l=>{var T;const y=(T=l.target.files)==null?void 0:T[0];y&&re(y)},O=m.useCallback(async(l,y)=>{try{return await p(l,y)}catch(T){return console.error("Enhancement failed:",T),l}},[p]),J=m.useCallback(async l=>{try{const y=await h(l);return s(!0,y),y}catch(y){return console.error("Background removal failed:",y),l}},[h,s]),q=m.useCallback(async()=>{const l=b.getState().portrait;if(!l.rawImage)return;let y;l.bgRemoved&&l.bgRemovedImage?y=await ye(l.bgRemovedImage,l.rawImage,l.bgOpacity,l.bgBlur):y=l.rawImage,l.engravingIntensity>0&&(y=await O(y,l.engravingIntensity)),n(y)},[O,n]),oe=async()=>{if(!S)return;if(!A&&!x){B(!0);return}if(!A){const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)}else{s(!1,null);const y=b.getState().portrait.engravingIntensity;if(y>0){const T=await O(S,y);n(T)}else n(S)}},fe=l=>{u(l),D.current&&clearTimeout(D.current),S&&(D.current=setTimeout(q,150))},be=async l=>{if(k(l),!S)return;const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)},xe=l=>{d(l),M.current&&clearTimeout(M.current),!(!S||!z)&&(M.current=setTimeout(q,150))},le=l=>{c(l),M.current&&clearTimeout(M.current),!(!S||!z)&&(M.current=setTimeout(q,150))},ce=()=>{n(null),i(null),s(!1,null),d(0),c(0),u(0),It()},Ne=(l,y)=>{t.zoom<=1||(_(!0),E.current={x:l,y,panX:t.panX,panY:t.panY})},Le=(l,y)=>{if(!N||!E.current||!I.current)return;const T=I.current.getBoundingClientRect(),U=2/Math.max(T.width,T.height),de=(l-E.current.x)*U,ue=(y-E.current.y)*U,pt=Math.max(-1,Math.min(1,E.current.panX+de)),ht=Math.max(-1,Math.min(1,E.current.panY+ue));a(pt,ht)},we=()=>{_(!1),E.current=null},ot=l=>{l.preventDefault(),Ne(l.clientX,l.clientY)},it=l=>{Le(l.clientX,l.clientY)},st=()=>{we()},lt=()=>{we()},ct=l=>{l.touches.length===1&&Ne(l.touches[0].clientX,l.touches[0].clientY)},dt=l=>{l.touches.length===1&&Le(l.touches[0].clientX,l.touches[0].clientY)},ut=()=>{we()};return o.jsxs("div",{className:"space-y-4",children:[t.original?o.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[o.jsxs("div",{className:"relative",children:[o.jsx("div",{ref:I,className:`w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg ${t.zoom>1?"cursor-grab":""} ${N?"cursor-grabbing":""}`,onMouseDown:ot,onMouseMove:it,onMouseUp:st,onMouseLeave:lt,onTouchStart:ct,onTouchMove:dt,onTouchEnd:ut,children:o.jsx("img",{src:t.original||"",alt:"Portrait",className:"w-full h-full object-cover pointer-events-none select-none",style:{transform:`scale(${t.zoom}) translate(${t.panX*50*(t.zoom-1)}%, ${t.panY*50*(t.zoom-1)}%)`},draggable:!1})}),o.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:ce,children:o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:P.form.portrait.zoom}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),o.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:l=>{const y=parseFloat(l.target.value);r(y),y<=1&&(t.panX!==0||t.panY!==0)&&a(0,0)},className:"range range-primary range-sm"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Sepia-Effekt":"Sepia effect",w&&o.jsx("span",{className:"loading loading-spinner loading-xs"})]}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(se*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:se,onChange:l=>fe(parseFloat(l.target.value)),className:"range range-secondary range-sm",disabled:w||!S})]})]}),A?o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(X*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:X,onChange:l=>xe(parseFloat(l.target.value)),className:"range range-primary range-sm"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:V,onChange:l=>le(parseFloat(l.target.value)),className:"range range-primary range-sm"})]})]}):o.jsx("div",{className:"form-control",children:o.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[o.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${g?"opacity-50":""}`,checked:A,onChange:oe,disabled:g||!S}),o.jsxs("span",{className:"label-text flex items-center gap-2",children:[g?o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!x&&o.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),v&&o.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"stroke-current shrink-0 h-5 w-5",fill:"none",viewBox:"0 0 24 24",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),o.jsx("span",{children:v})]})]}):o.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${g?"border-primary bg-primary/10 pointer-events-none":C?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:ge,onDragOver:f,onDragLeave:L,onClick:$,children:[o.jsx("input",{ref:j,type:"file",accept:"image/*",className:"hidden",onChange:Z}),g?o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),o.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),o.jsx("p",{className:"font-medium",children:P.form.portrait.upload}),o.jsx("p",{className:"text-sm text-base-content/60",children:P.form.portrait.dragDrop})]})]}),o.jsx(Fe,{isOpen:H,onClose:()=>B(!1),onSubmit:be})]})}function At(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.voucherConfig.templateHue),n=b(a=>a.setTemplateHue),r=F(e);return o.jsx("div",{className:"space-y-4",children:o.jsxs("div",{className:"form-control",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text font-medium",children:r.form.billColor.label}),o.jsxs("span",{className:"label-text-alt",children:[t,"°"]})]}),o.jsx("input",{type:"range",min:"0",max:"360",value:t,onChange:a=>n(Number(a.target.value)),className:"range range-primary",style:{background:`linear-gradient(to right,
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),pt=require("zustand"),gt=require("zustand/middleware"),p=require("react"),ft=require("jspdf");var ne=typeof document<"u"?document.currentScript:null;const He={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de",templateHue:160},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,panX:0,panY:0,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1},b=pt.create()(gt.persist(e=>({...He,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>e(r=>({portrait:{...r.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:r.portrait.original&&t?r.portrait.zoom:1,panX:r.portrait.original&&t?r.portrait.panX:0,panY:r.portrait.original&&t?r.portrait.panY:0}})),setEnhancedPortrait:t=>e(n=>({portrait:{...n.portrait,enhanced:t,useEnhanced:t!==null}})),toggleUseEnhanced:()=>e(t=>({portrait:{...t.portrait,useEnhanced:t.portrait.enhanced?!t.portrait.useEnhanced:!1}})),setPortraitZoom:t=>e(n=>({portrait:{...n.portrait,zoom:t}})),setPortraitPan:(t,n)=>e(r=>({portrait:{...r.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>e(r=>({portrait:{...r.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:r.portrait.bgRemovedImage}})),setPortraitBgOpacity:t=>e(n=>({portrait:{...n.portrait,bgOpacity:t}})),setPortraitBgBlur:t=>e(n=>({portrait:{...n.portrait,bgBlur:t}})),setPortraitEngravingIntensity:t=>e(n=>({portrait:{...n.portrait,engravingIntensity:t}})),setCurrentSide:t=>e({currentSide:t}),flipSide:()=>e(t=>({currentSide:t.currentSide==="front"?"back":"front"})),setIsEnhancing:t=>e({isEnhancing:t}),setIsExporting:t=>e({isExporting:t}),setLanguage:t=>e(n=>({voucherConfig:{...n.voucherConfig,language:t}})),setHours:t=>e(n=>({voucherConfig:{...n.voucherConfig,hours:t}})),setTemplateHue:t=>e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}})),reset:()=>e(He)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig,portrait:{original:null,enhanced:null,useEnhanced:e.portrait.useEnhanced,zoom:e.portrait.zoom,panX:e.portrait.panX,panY:e.portrait.panY,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:e.portrait.engravingIntensity}})})),bt={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?"},billColor:{title:"Scheinfarbe",label:"Farbton"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},xt={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},wt={de:bt,en:xt};function F(e){return wt[e]}function Te(e,t,n){if(n&&n.trim())return n;const r=F(e),a=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",a)}function yt(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.personalInfo),n=b(a=>a.setPersonalInfo),r=F(e);return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),o.jsx("input",{type:"text",placeholder:r.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:a=>n({name:a.target.value})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),o.jsx("input",{type:"email",placeholder:r.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:a=>n({email:a.target.value})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),o.jsx("input",{type:"tel",placeholder:r.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:a=>n({phone:a.target.value})})]})]})}const vt=1024,ee=new Map;let W=null,De=null;function je(e,t){return W||(W=document.createElement("canvas"),De=W.getContext("2d",{willReadFrequently:!0})),(W.width!==e||W.height!==t)&&(W.width=e,W.height=t),De}function ie(e){const t=ee.get(e);return t?Promise.resolve(t):new Promise((n,r)=>{const a=new Image;a.onload=()=>{if(ee.size>10){const i=ee.keys().next().value;i&&ee.delete(i)}ee.set(e,a),n(a)},a.onerror=()=>r(new Error("Failed to load image")),a.src=e})}function It(){ee.clear()}async function kt(e,t=vt){const n=await ie(e),r=Math.max(n.width,n.height);if(r<=t)return e;const a=t/r,i=Math.round(n.width*a),s=Math.round(n.height*a),d=document.createElement("canvas"),c=d.getContext("2d");if(!c)throw new Error("Failed to get canvas context");return d.width=i,d.height=s,c.drawImage(n,0,0,i,s),d.toDataURL("image/jpeg",.9)}async function ye(e,t,n,r=0){const[a,i]=await Promise.all([ie(e),ie(t)]),s=je(a.width,a.height);if(s.clearRect(0,0,a.width,a.height),n>0){const d=r*20;s.save(),s.globalAlpha=n,d>0&&(s.filter=`blur(${d}px)`),s.drawImage(i,0,0,a.width,a.height),s.restore()}return s.drawImage(a,0,0),W.toDataURL("image/png")}async function Ye(e,t=.5){const n=await ie(e),r=je(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),i=a.data,s=new Uint32Array(i.buffer),d=1+t*.8,c=1-t;for(let u=0;u<s.length;u++){const h=s[u],m=h&255,w=h>>8&255,g=h>>16&255,v=h>>24&255;if(v===0)continue;let k=(((77*m+150*w+29*g>>8)/255-.5)*d+.5)*255;k<0?k=0:k>255&&(k=255);let P=k*.9+25,j=k*.78+15,I=k*.55+5;P>255&&(P=255),j>255&&(j=255),I>255&&(I=255);const C=m*c+P*t|0,R=w*c+j*t|0,H=g*c+I*t|0;s[u]=v<<24|H<<16|R<<8|C}return r.putImageData(a,0,0),W.toDataURL("image/png")}function Pt(e,t,n){e/=255,t/=255,n/=255;const r=Math.max(e,t,n),a=Math.min(e,t,n),i=(r+a)/2;let s=0,d=0;if(r!==a){const c=r-a;switch(d=i>.5?c/(2-r-a):c/(r+a),r){case e:s=((t-n)/c+(t<n?6:0))/6;break;case t:s=((n-e)/c+2)/6;break;case n:s=((e-t)/c+4)/6;break}}return[s,d,i]}function Ct(e,t,n){if(t===0){const s=Math.round(n*255);return[s,s,s]}const r=(s,d,c)=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?s+(d-s)*6*c:c<1/2?d:c<2/3?s+(d-s)*(2/3-c)*6:s),a=n<.5?n*(1+t):n+t-n*t,i=2*n-a;return[Math.round(r(i,a,e+1/3)*255),Math.round(r(i,a,e)*255),Math.round(r(i,a,e-1/3)*255)]}async function _e(e,t){if(t>=155&&t<=165)return e;const n=await ie(e),r=je(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),i=a.data,s=new Uint32Array(i.buffer),d=t%360/360,c=60/360,u=260/360,h=1e5,m=s.length;for(let w=0;w<m;w+=h){const g=Math.min(w+h,m);for(let v=w;v<g;v++){const x=s[v],k=x&255,P=x>>8&255,j=x>>16&255,I=x>>24&255;if(I===0)continue;const[C,R,H]=Pt(k,P,j);if(R<.06||C<c||C>u)continue;const B=d,[N,Y,E]=Ct(B,R,H);s[v]=I<<24|E<<16|Y<<8|N}g<m&&await new Promise(v=>setTimeout(v,0))}return r.putImageData(a,0,0),W.toDataURL("image/png")}const Tt="https://api.stability.ai/v1/generation",jt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",We="stability_api_key";let ae=null;function St(e){ae=e}function Rt(){return ae}function Et(){return ae!==null}const Bt={vintage:"portrait in the style of vintage currency engraving, fine line work, crosshatching, sepia tones, detailed stippling, classic bank note portrait style",engraved:"portrait as detailed intaglio engraving, currency bill style, fine parallel lines, high contrast, official government portrait",currency:"portrait rendered as US dollar bill engraving, official currency portrait style, green tint, fine line engraving technique"},Me=[{width:1024,height:1024},{width:1152,height:896},{width:1216,height:832},{width:1344,height:768},{width:1536,height:640},{width:640,height:1536},{width:768,height:1344},{width:832,height:1216},{width:896,height:1152}];function Nt(e,t){const n=e/t;let r=Me[0],a=1/0;for(const i of Me){const s=i.width/i.height,d=Math.abs(n-s);d<a&&(a=d,r=i)}return r}function Lt(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{const a=Nt(r.width,r.height),i=document.createElement("canvas");i.width=a.width,i.height=a.height;const s=i.getContext("2d");if(!s){n(new Error("Failed to get canvas context"));return}const d=r.width/r.height,c=a.width/a.height;let u=0,h=0,m=r.width,w=r.height;d>c?(m=r.height*c,u=(r.width-m)/2):(w=r.width/c,h=(r.height-w)/2),s.drawImage(r,u,h,m,w,0,0,a.width,a.height),t(i.toDataURL("image/png"))},r.onerror=()=>n(new Error("Failed to load image")),r.src=e})}function Xe(e){var s;const t=e.split(","),n=((s=t[0].match(/:(.*?);/))==null?void 0:s[1])||"image/png",r=atob(t[1]),a=r.length,i=new Uint8Array(a);for(let d=0;d<a;d++)i[d]=r.charCodeAt(d);return new Blob([i],{type:n})}function me(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.src||new URL("index.cjs",document.baseURI).href}<"u"&&"sk-7mEKklrqaltdtgbX0VoZbkA8E1cl939Spn75jSIYRvp1BW0b"||typeof process<"u"&&((t=process.env)==null?void 0:t.NEXT_PUBLIC_STABILITY_API_KEY);return e&&e!=="your-api-key-here"?e:typeof localStorage<"u"?localStorage.getItem(We):null}function $e(e){localStorage.setItem(We,e)}function Pe(){return ae?!0:me()!==null}async function Ht(e){const t=me();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,i=await Lt(n),s=Xe(i),d=new FormData;d.append("init_image",s,"portrait.png"),d.append("init_image_mode","IMAGE_STRENGTH"),d.append("image_strength",String(1-a)),d.append("text_prompts[0][text]",Bt[r]),d.append("text_prompts[0][weight]","1"),d.append("cfg_scale","7"),d.append("samples","1"),d.append("steps","30");const u=await fetch(`${Tt}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:d});if(!u.ok){const m=await u.text();throw console.error("Stability AI error:",m),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const h=await u.json();if(!h.artifacts||h.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${h.artifacts[0].base64}`}async function Oe(e){if(ae){const s=await fetch(ae,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!s.ok){const c=await s.json().catch(()=>({}));throw new Error(c.error||`API error: ${s.status}`)}return(await s.json()).imageDataUrl}const t=me();if(!t)throw new Error("No Stability AI API key configured");const n=Xe(e),r=new FormData;r.append("image",n,"image.png"),r.append("output_format","png");const a=await fetch(jt,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:r});if(!a.ok){const s=await a.text();throw console.error("Stability AI remove background error:",s),a.status===401?new Error("Invalid API key"):a.status===402?new Error("Insufficient credits"):a.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${a.status}`)}const i=await a.blob();return new Promise((s,d)=>{const c=new FileReader;c.onload=()=>s(c.result),c.onerror=()=>d(new Error("Failed to read result")),c.readAsDataURL(i)})}function Dt(){const[e,t]=p.useState(!1),[n,r]=p.useState(!1),[a,i]=p.useState(null),[s,d]=p.useState(()=>Pe());p.useEffect(()=>{d(Pe())},[]);const c=p.useCallback(()=>i(null),[]),u=p.useCallback(w=>{$e(w),d(!0),i(null)},[]),h=p.useCallback(async(w,g=.5)=>{t(!0),i(null);try{return await Ye(w,g)}catch(v){const x=v instanceof Error?v.message:"Enhancement failed";throw i(x),v}finally{t(!1)}},[]),m=p.useCallback(async w=>{r(!0),i(null);try{return await Oe(w)}catch(g){const v=g instanceof Error?g.message:"Background removal failed";throw i(v),g}finally{r(!1)}},[]);return{enhance:h,removeBg:m,isEnhancing:e,isRemovingBg:n,error:a,hasKey:s,setApiKey:u,clearError:c}}function Fe({isOpen:e,onClose:t,onSubmit:n}){const r=b(u=>u.voucherConfig.language),[a,i]=p.useState("");if(!e)return null;const s=u=>{u.preventDefault(),a.trim()&&(n(a.trim()),i(""),t())},c={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[r];return o.jsxs("dialog",{className:"modal modal-open",children:[o.jsxs("div",{className:"modal-box",children:[o.jsx("h3",{className:"font-bold text-lg",children:c.title}),o.jsx("p",{className:"py-4 text-sm opacity-80",children:c.description}),o.jsxs("form",{onSubmit:s,children:[o.jsxs("div",{className:"form-control",children:[o.jsx("input",{type:"password",placeholder:c.placeholder,className:"input input-bordered w-full",value:a,onChange:u=>i(u.target.value),autoFocus:!0}),o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text-alt",children:c.hint})})]}),o.jsxs("div",{className:"modal-action",children:[o.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:c.cancel}),o.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:c.submit})]})]})]}),o.jsx("form",{method:"dialog",className:"modal-backdrop",children:o.jsx("button",{onClick:t,children:"close"})})]})}function Mt(){const e=b(l=>l.voucherConfig.language),t=b(l=>l.portrait),n=b(l=>l.setPortrait),r=b(l=>l.setPortraitZoom),a=b(l=>l.setPortraitPan),i=b(l=>l.setPortraitRawImage),s=b(l=>l.setPortraitBgRemoved),d=b(l=>l.setPortraitBgOpacity),c=b(l=>l.setPortraitBgBlur),u=b(l=>l.setPortraitEngravingIntensity),{enhance:h,removeBg:m,isEnhancing:w,isRemovingBg:g,error:v,hasKey:x,setApiKey:k}=Dt(),P=F(e),j=p.useRef(null),I=p.useRef(null),[C,R]=p.useState(!1),[H,B]=p.useState(!1),[N,Y]=p.useState(!1),E=p.useRef(null),D=p.useRef(null),M=p.useRef(null),S=t.rawImage,_=t.bgRemovedImage,A=t.bgRemoved,X=t.bgOpacity,V=t.bgBlur,se=t.engravingIntensity;p.useEffect(()=>{t.original&&!t.rawImage&&i(t.original)},[t.original,t.rawImage,i]),p.useEffect(()=>()=>{D.current&&clearTimeout(D.current),M.current&&clearTimeout(M.current)},[]);const re=p.useCallback(async l=>{if(!l.type.startsWith("image/"))return;const y=new FileReader;y.onload=async T=>{var ue;const U=(ue=T.target)==null?void 0:ue.result,de=await kt(U);i(de),n(de),s(!1,null),u(0)},y.readAsDataURL(l)},[n,i,s,u]),ge=p.useCallback(l=>{l.preventDefault(),R(!1);const y=l.dataTransfer.files[0];y&&re(y)},[re]),f=p.useCallback(l=>{l.preventDefault(),R(!0)},[]),L=p.useCallback(l=>{l.preventDefault(),R(!1)},[]),$=()=>{var l;(l=j.current)==null||l.click()},Z=l=>{var T;const y=(T=l.target.files)==null?void 0:T[0];y&&re(y)},O=p.useCallback(async(l,y)=>{try{return await h(l,y)}catch(T){return console.error("Enhancement failed:",T),l}},[h]),J=p.useCallback(async l=>{try{const y=await m(l);return s(!0,y),y}catch(y){return console.error("Background removal failed:",y),l}},[m,s]),q=p.useCallback(async()=>{const l=b.getState().portrait;if(!l.rawImage)return;let y;l.bgRemoved&&l.bgRemovedImage?y=await ye(l.bgRemovedImage,l.rawImage,l.bgOpacity,l.bgBlur):y=l.rawImage,l.engravingIntensity>0&&(y=await O(y,l.engravingIntensity)),n(y)},[O,n]),oe=async()=>{if(!S)return;if(!A&&!x){B(!0);return}if(!A){const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)}else{s(!1,null);const y=b.getState().portrait.engravingIntensity;if(y>0){const T=await O(S,y);n(T)}else n(S)}},fe=l=>{u(l),D.current&&clearTimeout(D.current),S&&(D.current=setTimeout(q,150))},be=async l=>{if(k(l),!S)return;const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)},xe=l=>{d(l),M.current&&clearTimeout(M.current),!(!S||!_)&&(M.current=setTimeout(q,150))},le=l=>{c(l),M.current&&clearTimeout(M.current),!(!S||!_)&&(M.current=setTimeout(q,150))},ce=()=>{n(null),i(null),s(!1,null),d(0),c(0),u(0),It()},Ne=(l,y)=>{t.zoom<=1||(Y(!0),E.current={x:l,y,panX:t.panX,panY:t.panY})},Le=(l,y)=>{if(!N||!E.current||!I.current)return;const T=I.current.getBoundingClientRect(),U=2/Math.max(T.width,T.height),de=(l-E.current.x)*U,ue=(y-E.current.y)*U,ht=Math.max(-1,Math.min(1,E.current.panX+de)),mt=Math.max(-1,Math.min(1,E.current.panY+ue));a(ht,mt)},we=()=>{Y(!1),E.current=null},ot=l=>{l.preventDefault(),Ne(l.clientX,l.clientY)},it=l=>{Le(l.clientX,l.clientY)},st=()=>{we()},lt=()=>{we()},ct=l=>{l.touches.length===1&&Ne(l.touches[0].clientX,l.touches[0].clientY)},dt=l=>{l.touches.length===1&&Le(l.touches[0].clientX,l.touches[0].clientY)},ut=()=>{we()};return o.jsxs("div",{className:"space-y-4",children:[t.original?o.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[o.jsxs("div",{className:"relative",children:[o.jsx("div",{ref:I,className:`w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg ${t.zoom>1?"cursor-grab":""} ${N?"cursor-grabbing":""}`,onMouseDown:ot,onMouseMove:it,onMouseUp:st,onMouseLeave:lt,onTouchStart:ct,onTouchMove:dt,onTouchEnd:ut,children:o.jsx("img",{src:t.original||"",alt:"Portrait",className:"w-full h-full object-cover pointer-events-none select-none",style:{transform:`scale(${t.zoom}) translate(${t.panX*50*(t.zoom-1)}%, ${t.panY*50*(t.zoom-1)}%)`},draggable:!1})}),o.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:ce,children:o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:P.form.portrait.zoom}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),o.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:l=>{const y=parseFloat(l.target.value);r(y),y<=1&&(t.panX!==0||t.panY!==0)&&a(0,0)},className:"range range-primary range-sm"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Sepia-Effekt":"Sepia effect",w&&o.jsx("span",{className:"loading loading-spinner loading-xs"})]}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(se*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:se,onChange:l=>fe(parseFloat(l.target.value)),className:"range range-secondary range-sm",disabled:w||!S})]})]}),A?o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(X*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:X,onChange:l=>xe(parseFloat(l.target.value)),className:"range range-primary range-sm"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:V,onChange:l=>le(parseFloat(l.target.value)),className:"range range-primary range-sm"})]})]}):o.jsx("div",{className:"form-control",children:o.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[o.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${g?"opacity-50":""}`,checked:A,onChange:oe,disabled:g||!S}),o.jsxs("span",{className:"label-text flex items-center gap-2",children:[g?o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!x&&o.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),v&&o.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"stroke-current shrink-0 h-5 w-5",fill:"none",viewBox:"0 0 24 24",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),o.jsx("span",{children:v})]})]}):o.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${g?"border-primary bg-primary/10 pointer-events-none":C?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:ge,onDragOver:f,onDragLeave:L,onClick:$,children:[o.jsx("input",{ref:j,type:"file",accept:"image/*",className:"hidden",onChange:Z}),g?o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),o.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),o.jsx("p",{className:"font-medium",children:P.form.portrait.upload}),o.jsx("p",{className:"text-sm text-base-content/60",children:P.form.portrait.dragDrop})]})]}),o.jsx(Fe,{isOpen:H,onClose:()=>B(!1),onSubmit:be})]})}function At(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.voucherConfig.templateHue),n=b(a=>a.setTemplateHue),r=F(e);return o.jsx("div",{className:"space-y-4",children:o.jsxs("div",{className:"form-control",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text font-medium",children:r.form.billColor.label}),o.jsxs("span",{className:"label-text-alt",children:[t,"°"]})]}),o.jsx("input",{type:"range",min:"0",max:"360",value:t,onChange:a=>n(Number(a.target.value)),className:"w-full h-3 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:shadow-md [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-gray-300 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white [&::-moz-range-thumb]:shadow-md [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-gray-300",style:{background:`linear-gradient(to right,
2
2
  hsl(0, 70%, 50%),
3
3
  hsl(60, 70%, 50%),
4
4
  hsl(120, 70%, 50%),
5
5
  hsl(180, 70%, 50%),
6
6
  hsl(240, 70%, 50%),
7
7
  hsl(300, 70%, 50%),
8
- hsl(360, 70%, 50%))`}}),o.jsxs("div",{className:"flex justify-between text-xs px-1 mt-1 opacity-60",children:[o.jsx("span",{children:"0°"}),o.jsx("span",{children:"90°"}),o.jsx("span",{children:"180°"}),o.jsx("span",{children:"270°"}),o.jsx("span",{children:"360°"})]})]})})}const Y=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",Se={en:{1:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200}}},K={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},G={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function Re(e){return e==="de"?G:K}function qe(e,t){return Se[e][t]}const Ce=.25;function Ut(e){const t=Re(e),n=Ce,r=a=>({portrait:{x:a.portrait.x*n,y:a.portrait.y*n,radiusX:a.portrait.radiusX*n,radiusY:a.portrait.radiusY*n},namePlate:{x:a.namePlate.x*n,y:a.namePlate.y*n,fontSize:a.namePlate.fontSize*n,maxWidth:a.namePlate.maxWidth?a.namePlate.maxWidth*n:void 0,lineHeight:a.namePlate.lineHeight?a.namePlate.lineHeight*n:void 0,align:a.namePlate.align},contactInfo:a.contactInfo?{x:a.contactInfo.x*n,y:a.contactInfo.y*n,fontSize:a.contactInfo.fontSize*n,maxWidth:a.contactInfo.maxWidth?a.contactInfo.maxWidth*n:void 0,lineHeight:a.contactInfo.lineHeight?a.contactInfo.lineHeight*n:void 0,align:a.contactInfo.align}:void 0,description:a.description?{x:a.description.x*n,y:a.description.y*n,fontSize:a.description.fontSize*n,maxWidth:a.description.maxWidth?a.description.maxWidth*n:void 0,lineHeight:a.description.lineHeight?a.description.lineHeight*n:void 0,align:a.description.align}:void 0});return{front:r(t.front),back:r(t.back)}}function Yt(e,t){const n=Se[e][t];return{...n,width:Math.round(n.width*Ce),height:Math.round(n.height*Ce)}}const ve=new Map,Q=new Map;async function te(e){return ve.has(e)?ve.get(e):new Promise((t,n)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{ve.set(e,r),t(r)},r.onerror=n,r.src=e})}function Ee(e,t,n,r){e.drawImage(t,0,0,n,r)}async function Ke(e,t,n,r){if(t>=155&&t<=165)return te(e);const a=`${e}:${t}:${n}x${r}`;if(Q.has(a))return te(Q.get(a));const i=await te(e),s=document.createElement("canvas");s.width=n,s.height=r;const d=s.getContext("2d");if(!d)throw new Error("Failed to get canvas context");d.drawImage(i,0,0,n,r);const c=s.toDataURL("image/png"),u=await ze(c,t);if(Q.size>20){const p=Q.keys().next().value;p&&Q.delete(p)}return Q.set(a,u),te(u)}function Ge(e,t,n,r,a,i,s=1,d=0,c=0){e.save(),e.beginPath(),e.ellipse(n,r,a,i,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,p=a/i,h=a*2,w=i*2;let g,v;u>p?(v=w,g=w*u):(g=h,v=h/u),g*=s,v*=s;const x=Math.max(0,(g-h)/2),k=Math.max(0,(v-w)/2),P=n-g/2+d*x,j=r-v/2+c*k;e.drawImage(t,P,j,g,v),e.restore()}function Be(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=r,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function Ve(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=r;const a=n.maxWidth||400,i=n.lineHeight||n.fontSize*1.4,s=t.split(" "),d=[];let c="";for(const h of s){const w=c?`${c} ${h}`:h;e.measureText(w).width>a&&c?(d.push(c),c=h):c=w}c&&d.push(c);const u=d.length*i;let p=n.y-u/2;for(const h of d)e.fillText(h,n.x,p),p+=i;e.restore()}function Ze(e,t,n,r,a,i="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=i;const s=a.lineHeight||a.fontSize*1.8,d=[t,n,r].filter(Boolean),c=(d.length-1)*s;let u=a.y-c/2;for(const p of d)p&&(e.fillText(p,a.x,u),u+=s);e.restore()}async function Je(e,t,n,r,a,i,s,d=1,c=0,u=0,p=0){const h=e.getContext("2d");if(!h)return;e.width=i,e.height=s,h.clearRect(0,0,i,s);const w=await Ke(t,p,i,s);if(Ee(h,w,i,s),n)try{const g=await te(n);Ge(h,g,a.portrait.x,a.portrait.y,a.portrait.radiusX,a.portrait.radiusY,d,c,u)}catch(g){console.error("Failed to load portrait:",g)}r&&Be(h,r,a.namePlate)}async function Qe(e,t,n,r,a,i,s,d,c,u=0){const p=e.getContext("2d");if(!p)return;e.width=d,e.height=c,p.clearRect(0,0,d,c);const h=await Ke(t,u,d,c);Ee(p,h,d,c),s.contactInfo&&(n||r||a)&&Ze(p,n,r,a,s.contactInfo),s.description&&i&&Ve(p,i,s.description),n&&Be(p,n,s.namePlate)}function _t(e,t){const[n,r]=m.useState(e);return m.useEffect(()=>{const a=setTimeout(()=>r(e),t);return()=>clearTimeout(a)},[e,t]),n}function zt(){const e=b(f=>f.voucherConfig.language),t=b(f=>f.voucherConfig.hours),n=b(f=>f.voucherConfig.description),r=b(f=>f.voucherConfig.templateHue),a=b(f=>f.personalInfo),i=b(f=>f.portrait),s=b(f=>f.currentSide),d=b(f=>f.flipSide),c=b(f=>f.setPortraitPan),u=_t(r,150),p=F(e),h=m.useRef(null),w=m.useRef(null),g=m.useRef(null),[v,x]=m.useState(!1),[k,P]=m.useState(!1),j=m.useRef(null),I=Yt(e,t),C=Ut(e),R=i.useEnhanced&&i.enhanced?i.enhanced:i.original,H=Te(e,t,n);m.useEffect(()=>{h.current&&Je(h.current,I.front,R,a.name,C.front,I.width,I.height,i.zoom,i.panX,i.panY,u)},[I,R,a.name,C,i.zoom,i.panX,i.panY,u]),m.useEffect(()=>{w.current&&Qe(w.current,I.back,a.name,a.email,a.phone,H,C.back,I.width,I.height,u)},[I,a,H,C,u]);const B=()=>{x(!0),setTimeout(()=>{d(),x(!1)},150)},N=m.useCallback((f,L)=>{if(!g.current||s!=="front"||!i.original)return!1;const $=g.current.getBoundingClientRect(),Z=$.width/I.width,O=$.height/I.height,J=(f-$.left)/Z,q=(L-$.top)/O,{x:oe,y:fe,radiusX:be,radiusY:xe}=C.front.portrait,le=(J-oe)/be,ce=(q-fe)/xe;return le*le+ce*ce<=1},[s,i.original,I.width,I.height,C.front.portrait]),_=m.useCallback((f,L)=>{i.zoom<=1||!N(f,L)||(P(!0),j.current={x:f,y:L,panX:i.panX,panY:i.panY})},[i.zoom,i.panX,i.panY,N]),E=m.useCallback((f,L)=>{if(!k||!j.current||!g.current)return;const $=g.current.getBoundingClientRect(),Z=3/Math.max($.width,$.height),O=(f-j.current.x)*Z,J=(L-j.current.y)*Z,q=Math.max(-1,Math.min(1,j.current.panX+O)),oe=Math.max(-1,Math.min(1,j.current.panY+J));c(q,oe)},[k,c]),D=m.useCallback(()=>{P(!1),j.current=null},[]),M=f=>{i.zoom>1&&N(f.clientX,f.clientY)&&(f.preventDefault(),_(f.clientX,f.clientY))},S=f=>{E(f.clientX,f.clientY)},z=()=>D(),A=()=>D(),X=f=>{if(f.touches.length===1){const L=f.touches[0];i.zoom>1&&N(L.clientX,L.clientY)&&_(L.clientX,L.clientY)}},V=f=>{f.touches.length===1&&E(f.touches[0].clientX,f.touches[0].clientY)},se=()=>D(),re=s==="front"&&i.original&&i.zoom>1,ge=I.width/I.height;return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex justify-between items-center",children:[o.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[o.jsx("button",{className:`tab ${s==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="front"&&B(),children:p.preview.front}),o.jsx("button",{className:`tab ${s==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="back"&&B(),children:p.preview.back})]}),o.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:B,children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),p.preview.flip]})]}),o.jsxs("div",{ref:g,className:`relative w-full overflow-hidden shadow-lg ${re?k?"cursor-grabbing":"cursor-grab":""}`,style:{aspectRatio:ge},onMouseDown:M,onMouseMove:S,onMouseUp:z,onMouseLeave:A,onTouchStart:X,onTouchMove:V,onTouchEnd:se,children:[o.jsx("canvas",{ref:h,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="front"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),o.jsx("canvas",{ref:w,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="back"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Wt(){const e=m.useRef(null),t=m.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Xt=`
8
+ hsl(360, 70%, 50%))`}}),o.jsxs("div",{className:"flex justify-between text-xs px-1 mt-1 opacity-60",children:[o.jsx("span",{children:"0°"}),o.jsx("span",{children:"90°"}),o.jsx("span",{children:"180°"}),o.jsx("span",{children:"270°"}),o.jsx("span",{children:"360°"})]})]})})}const z=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",Se={en:{1:{front:`${z}templates/front_ldpi_en.png`,back:`${z}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${z}templates/front_ldpi_en.png`,back:`${z}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${z}templates/front_ldpi_en.png`,back:`${z}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${z}templates/front_hdpi_de.webp`,back:`${z}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${z}templates/front_hdpi_de.webp`,back:`${z}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${z}templates/front_hdpi_de.webp`,back:`${z}templates/back_hdpi_de.webp`,width:6144,height:3200}}},K={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},G={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function Re(e){return e==="de"?G:K}function qe(e,t){return Se[e][t]}const Ce=.25;function Ut(e){const t=Re(e),n=Ce,r=a=>({portrait:{x:a.portrait.x*n,y:a.portrait.y*n,radiusX:a.portrait.radiusX*n,radiusY:a.portrait.radiusY*n},namePlate:{x:a.namePlate.x*n,y:a.namePlate.y*n,fontSize:a.namePlate.fontSize*n,maxWidth:a.namePlate.maxWidth?a.namePlate.maxWidth*n:void 0,lineHeight:a.namePlate.lineHeight?a.namePlate.lineHeight*n:void 0,align:a.namePlate.align},contactInfo:a.contactInfo?{x:a.contactInfo.x*n,y:a.contactInfo.y*n,fontSize:a.contactInfo.fontSize*n,maxWidth:a.contactInfo.maxWidth?a.contactInfo.maxWidth*n:void 0,lineHeight:a.contactInfo.lineHeight?a.contactInfo.lineHeight*n:void 0,align:a.contactInfo.align}:void 0,description:a.description?{x:a.description.x*n,y:a.description.y*n,fontSize:a.description.fontSize*n,maxWidth:a.description.maxWidth?a.description.maxWidth*n:void 0,lineHeight:a.description.lineHeight?a.description.lineHeight*n:void 0,align:a.description.align}:void 0});return{front:r(t.front),back:r(t.back)}}function zt(e,t){const n=Se[e][t];return{...n,width:Math.round(n.width*Ce),height:Math.round(n.height*Ce)}}const ve=new Map,Q=new Map;async function te(e){return ve.has(e)?ve.get(e):new Promise((t,n)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{ve.set(e,r),t(r)},r.onerror=n,r.src=e})}function Ee(e,t,n,r){e.drawImage(t,0,0,n,r)}async function Ke(e,t,n,r){if(t>=155&&t<=165)return te(e);const a=`${e}:${t}:${n}x${r}`;if(Q.has(a))return te(Q.get(a));const i=await te(e),s=document.createElement("canvas");s.width=n,s.height=r;const d=s.getContext("2d");if(!d)throw new Error("Failed to get canvas context");d.drawImage(i,0,0,n,r);const c=s.toDataURL("image/png"),u=await _e(c,t);if(Q.size>20){const h=Q.keys().next().value;h&&Q.delete(h)}return Q.set(a,u),te(u)}function Ge(e,t,n,r,a,i,s=1,d=0,c=0){e.save(),e.beginPath(),e.ellipse(n,r,a,i,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,h=a/i,m=a*2,w=i*2;let g,v;u>h?(v=w,g=w*u):(g=m,v=m/u),g*=s,v*=s;const x=Math.max(0,(g-m)/2),k=Math.max(0,(v-w)/2),P=n-g/2+d*x,j=r-v/2+c*k;e.drawImage(t,P,j,g,v),e.restore()}function Be(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=r,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function Ve(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=r;const a=n.maxWidth||400,i=n.lineHeight||n.fontSize*1.4,s=t.split(" "),d=[];let c="";for(const m of s){const w=c?`${c} ${m}`:m;e.measureText(w).width>a&&c?(d.push(c),c=m):c=w}c&&d.push(c);const u=d.length*i;let h=n.y-u/2;for(const m of d)e.fillText(m,n.x,h),h+=i;e.restore()}function Ze(e,t,n,r,a,i="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=i;const s=a.lineHeight||a.fontSize*1.8,d=[t,n,r].filter(Boolean),c=(d.length-1)*s;let u=a.y-c/2;for(const h of d)h&&(e.fillText(h,a.x,u),u+=s);e.restore()}async function Je(e,t,n,r,a,i,s,d=1,c=0,u=0,h=0){const m=e.getContext("2d");if(!m)return;e.width=i,e.height=s,m.clearRect(0,0,i,s);const w=await Ke(t,h,i,s);if(Ee(m,w,i,s),n)try{const g=await te(n);Ge(m,g,a.portrait.x,a.portrait.y,a.portrait.radiusX,a.portrait.radiusY,d,c,u)}catch(g){console.error("Failed to load portrait:",g)}r&&Be(m,r,a.namePlate)}async function Qe(e,t,n,r,a,i,s,d,c,u=0){const h=e.getContext("2d");if(!h)return;e.width=d,e.height=c,h.clearRect(0,0,d,c);const m=await Ke(t,u,d,c);Ee(h,m,d,c),s.contactInfo&&(n||r||a)&&Ze(h,n,r,a,s.contactInfo),s.description&&i&&Ve(h,i,s.description),n&&Be(h,n,s.namePlate)}function Yt(e,t){const[n,r]=p.useState(e);return p.useEffect(()=>{const a=setTimeout(()=>r(e),t);return()=>clearTimeout(a)},[e,t]),n}function _t(){const e=b(f=>f.voucherConfig.language),t=b(f=>f.voucherConfig.hours),n=b(f=>f.voucherConfig.description),r=b(f=>f.voucherConfig.templateHue),a=b(f=>f.personalInfo),i=b(f=>f.portrait),s=b(f=>f.currentSide),d=b(f=>f.flipSide),c=b(f=>f.setPortraitPan),u=Yt(r,150),h=F(e),m=p.useRef(null),w=p.useRef(null),g=p.useRef(null),[v,x]=p.useState(!1),[k,P]=p.useState(!1),j=p.useRef(null),I=zt(e,t),C=Ut(e),R=i.useEnhanced&&i.enhanced?i.enhanced:i.original,H=Te(e,t,n);p.useEffect(()=>{m.current&&Je(m.current,I.front,R,a.name,C.front,I.width,I.height,i.zoom,i.panX,i.panY,u)},[I,R,a.name,C,i.zoom,i.panX,i.panY,u]),p.useEffect(()=>{w.current&&Qe(w.current,I.back,a.name,a.email,a.phone,H,C.back,I.width,I.height,u)},[I,a,H,C,u]);const B=()=>{x(!0),setTimeout(()=>{d(),x(!1)},150)},N=p.useCallback((f,L)=>{if(!g.current||s!=="front"||!i.original)return!1;const $=g.current.getBoundingClientRect(),Z=$.width/I.width,O=$.height/I.height,J=(f-$.left)/Z,q=(L-$.top)/O,{x:oe,y:fe,radiusX:be,radiusY:xe}=C.front.portrait,le=(J-oe)/be,ce=(q-fe)/xe;return le*le+ce*ce<=1},[s,i.original,I.width,I.height,C.front.portrait]),Y=p.useCallback((f,L)=>{i.zoom<=1||!N(f,L)||(P(!0),j.current={x:f,y:L,panX:i.panX,panY:i.panY})},[i.zoom,i.panX,i.panY,N]),E=p.useCallback((f,L)=>{if(!k||!j.current||!g.current)return;const $=g.current.getBoundingClientRect(),Z=3/Math.max($.width,$.height),O=(f-j.current.x)*Z,J=(L-j.current.y)*Z,q=Math.max(-1,Math.min(1,j.current.panX+O)),oe=Math.max(-1,Math.min(1,j.current.panY+J));c(q,oe)},[k,c]),D=p.useCallback(()=>{P(!1),j.current=null},[]),M=f=>{i.zoom>1&&N(f.clientX,f.clientY)&&(f.preventDefault(),Y(f.clientX,f.clientY))},S=f=>{E(f.clientX,f.clientY)},_=()=>D(),A=()=>D(),X=f=>{if(f.touches.length===1){const L=f.touches[0];i.zoom>1&&N(L.clientX,L.clientY)&&Y(L.clientX,L.clientY)}},V=f=>{f.touches.length===1&&E(f.touches[0].clientX,f.touches[0].clientY)},se=()=>D(),re=s==="front"&&i.original&&i.zoom>1,ge=I.width/I.height;return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex justify-between items-center",children:[o.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[o.jsx("button",{className:`tab ${s==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="front"&&B(),children:h.preview.front}),o.jsx("button",{className:`tab ${s==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="back"&&B(),children:h.preview.back})]}),o.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:B,children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),h.preview.flip]})]}),o.jsxs("div",{ref:g,className:`relative w-full overflow-hidden shadow-lg ${re?k?"cursor-grabbing":"cursor-grab":""}`,style:{aspectRatio:ge},onMouseDown:M,onMouseMove:S,onMouseUp:_,onMouseLeave:A,onTouchStart:X,onTouchMove:V,onTouchEnd:se,children:[o.jsx("canvas",{ref:m,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="front"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),o.jsx("canvas",{ref:w,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="back"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Wt(){const e=p.useRef(null),t=p.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Xt=`
9
9
  // RGB to HSL conversion
10
10
  function rgbToHsl(r, g, b) {
11
11
  r /= 255;
@@ -358,4 +358,4 @@ self.onmessage = async (e) => {
358
358
  });
359
359
  }
360
360
  };
361
- `;let Ie=null,Ae=null;function $t(){if(!Ie){const e=new Blob([Xt],{type:"application/javascript"});Ae=URL.createObjectURL(e),Ie=new Worker(Ae,{type:"module"})}return Ie}async function ke(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function Ue(e,t){const n=new Uint8Array(e);let r="";for(let a=0;a<n.length;a++)r+=String.fromCharCode(n[a]);return`data:${t};base64,${btoa(r)}`}async function et(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:r,templateHeight:a,layout:i,portrait:s,portraitZoom:d=1,portraitPanX:c=0,portraitPanY:u=0,templateHue:p=160,name:h,email:w,phone:g,description:v}=e,[x,k]=await Promise.all([ke(t),ke(n)]);let P=null;return s&&(P=await ke(s)),new Promise((j,I)=>{const C=$t(),R=B=>{if(C.removeEventListener("message",R),C.removeEventListener("error",H),URL.revokeObjectURL(x),URL.revokeObjectURL(k),P&&URL.revokeObjectURL(P),B.data.type==="success")try{const{frontImageData:N,backImageData:_,width:E,height:D}=B.data;if(!N||!_||!E||!D){I(new Error("Invalid response from worker"));return}const M=Ue(N,"image/jpeg"),S=Ue(_,"image/jpeg"),z=E/96*25.4,A=D/96*25.4,X=new ft.jsPDF({orientation:z>A?"landscape":"portrait",unit:"mm",format:[z,A]});X.addImage(M,"JPEG",0,0,z,A),X.addPage([z,A]),X.addImage(S,"JPEG",0,0,z,A);const V=X.output("blob");j(V)}catch(N){I(N)}else I(new Error(B.data.error))},H=B=>{C.removeEventListener("message",R),C.removeEventListener("error",H),URL.revokeObjectURL(x),URL.revokeObjectURL(k),P&&URL.revokeObjectURL(P),I(new Error(B.message))};C.addEventListener("message",R),C.addEventListener("error",H),C.postMessage({type:"generate",frontTemplateUrl:x,backTemplateUrl:k,portraitUrl:P,templateWidth:r,templateHeight:a,templateHue:p,portraitZoom:d,portraitPanX:c,portraitPanY:u,layout:{front:{portrait:i.front.portrait,namePlate:i.front.namePlate},back:{namePlate:i.back.namePlate,contactInfo:i.back.contactInfo,description:i.back.description}},name:h,email:w,phone:g,description:v})})}function tt(e,t){const n=URL.createObjectURL(e),r=document.createElement("a");r.href=n,r.download=t,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}async function nt(e){const t=await et(e);tt(t,e.filename)}function Ot(){const e=b(x=>x.voucherConfig.language),t=b(x=>x.voucherConfig.hours),n=b(x=>x.voucherConfig.description),r=b(x=>x.voucherConfig.templateHue),a=b(x=>x.personalInfo),i=b(x=>x.portrait),s=b(x=>x.isExporting),d=b(x=>x.setIsExporting),c=F(e),u=qe(e,t),p=Re(e),h=i.useEnhanced&&i.enhanced?i.enhanced:i.original,w=Te(e,t,n),g=a.name.trim().length>0&&a.email.trim().length>0&&a.phone.trim().length>0&&i.original!==null,v=async()=>{if(!(!g||s)){d(!0);try{const x=`zeitgutschein-${t}h-${a.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await nt({frontTemplateSrc:u.front,backTemplateSrc:u.back,templateWidth:u.width,templateHeight:u.height,layout:p,portrait:h,portraitZoom:i.zoom,portraitPanX:i.panX,portraitPanY:i.panY,templateHue:r,name:a.name,email:a.email,phone:a.phone,description:w,filename:x})}catch(x){console.error("PDF export failed:",x)}finally{d(!1)}}};return o.jsxs("button",{className:`btn btn-primary flex-1 ${g?"":"btn-disabled"}`,onClick:v,disabled:!g,"aria-busy":s,children:[s?o.jsx("span",{className:"loading loading-spinner loading-sm"}):o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),c.export.button]})}function at(){const e=b(r=>r.voucherConfig.language),t=b(r=>r.setLanguage),n=r=>{t(r)};return o.jsxs("div",{className:"join",children:[o.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),o.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Ft(){const e=b(n=>n.voucherConfig.language),t=F(e);return o.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[o.jsx("div",{className:"navbar-start",children:o.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),o.jsx("div",{className:"navbar-center hidden sm:flex",children:o.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),o.jsx("div",{className:"navbar-end",children:o.jsx(at,{})})]})}const pe="/",qt={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${pe}templates/front_hdpi_de.jpg`,back:`${pe}templates/back_hdpi_de.jpg`,width:6144,height:4096},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:G.front.portrait,name:G.front.namePlate},back:{name:G.back.namePlate,contactInfo:G.back.contactInfo,description:G.back.description}},languages:["de"]},Kt={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${pe}templates/front_ldpi_en.png`,back:`${pe}templates/back_ldpi_en.png`,width:1536,height:1024},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:K.front.portrait,name:K.front.namePlate},back:{name:K.back.namePlate,contactInfo:K.back.contactInfo,description:K.back.description}},languages:["en"]},Ye=[qt,Kt],rt={async listTemplates(e){let t=[...Ye];return e!=null&&e.type&&(t=t.filter(n=>n.type===e.type)),e!=null&&e.category&&(t=t.filter(n=>n.category===e.category)),e!=null&&e.language&&(t=t.filter(n=>n.languages.includes(e.language))),t},async getTemplate(e){const t=Ye.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Gt(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let me=rt;function Vt(e){me=e}function Zt(){return me}async function Jt(e){return me.listTemplates(e)}async function Qt(e){return me.getTemplate(e)}exports.ApiKeyModal=Fe;exports.BillPreview=zt;exports.ExportButton=Ot;exports.Header=Ft;exports.LAYOUT_HDPI=G;exports.LAYOUT_LDPI=K;exports.LanguageToggle=at;exports.PersonalInfoForm=yt;exports.PortraitUpload=Mt;exports.TEMPLATES=Se;exports.VoucherConfig=At;exports.applyEngravingEffect=_e;exports.applyHueShift=ze;exports.downloadBlob=tt;exports.drawContactInfo=Ze;exports.drawMultilineText=Ve;exports.drawOvalPortrait=Ge;exports.drawTemplate=Ee;exports.drawText=Be;exports.enhancePortrait=Ht;exports.exportBillAsPDF=nt;exports.formatDescription=Te;exports.generateBillPDF=et;exports.getApiKey=he;exports.getDefaultTemplateId=Gt;exports.getLayout=Re;exports.getRemoveBackgroundEndpoint=Rt;exports.getTemplate=qe;exports.getTemplateById=Qt;exports.getTemplateProvider=Zt;exports.hasApiKey=Pe;exports.hasCustomEndpoint=Et;exports.listTemplates=Jt;exports.loadImage=te;exports.removeBackground=Oe;exports.renderBackSide=Qe;exports.renderFrontSide=Je;exports.setApiKey=$e;exports.setRemoveBackgroundEndpoint=St;exports.setTemplateProvider=Vt;exports.staticTemplateProvider=rt;exports.t=F;exports.useBillCanvasRefs=Wt;exports.useBillStore=b;
361
+ `;let Ie=null,Ae=null;function $t(){if(!Ie){const e=new Blob([Xt],{type:"application/javascript"});Ae=URL.createObjectURL(e),Ie=new Worker(Ae,{type:"module"})}return Ie}async function ke(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function Ue(e,t){const n=new Uint8Array(e);let r="";for(let a=0;a<n.length;a++)r+=String.fromCharCode(n[a]);return`data:${t};base64,${btoa(r)}`}async function et(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:r,templateHeight:a,layout:i,portrait:s,portraitZoom:d=1,portraitPanX:c=0,portraitPanY:u=0,templateHue:h=160,name:m,email:w,phone:g,description:v}=e,[x,k]=await Promise.all([ke(t),ke(n)]);let P=null;return s&&(P=await ke(s)),new Promise((j,I)=>{const C=$t(),R=B=>{if(C.removeEventListener("message",R),C.removeEventListener("error",H),URL.revokeObjectURL(x),URL.revokeObjectURL(k),P&&URL.revokeObjectURL(P),B.data.type==="success")try{const{frontImageData:N,backImageData:Y,width:E,height:D}=B.data;if(!N||!Y||!E||!D){I(new Error("Invalid response from worker"));return}const M=Ue(N,"image/jpeg"),S=Ue(Y,"image/jpeg"),_=E/96*25.4,A=D/96*25.4,X=new ft.jsPDF({orientation:_>A?"landscape":"portrait",unit:"mm",format:[_,A]});X.addImage(M,"JPEG",0,0,_,A),X.addPage([_,A]),X.addImage(S,"JPEG",0,0,_,A);const V=X.output("blob");j(V)}catch(N){I(N)}else I(new Error(B.data.error))},H=B=>{C.removeEventListener("message",R),C.removeEventListener("error",H),URL.revokeObjectURL(x),URL.revokeObjectURL(k),P&&URL.revokeObjectURL(P),I(new Error(B.message))};C.addEventListener("message",R),C.addEventListener("error",H),C.postMessage({type:"generate",frontTemplateUrl:x,backTemplateUrl:k,portraitUrl:P,templateWidth:r,templateHeight:a,templateHue:h,portraitZoom:d,portraitPanX:c,portraitPanY:u,layout:{front:{portrait:i.front.portrait,namePlate:i.front.namePlate},back:{namePlate:i.back.namePlate,contactInfo:i.back.contactInfo,description:i.back.description}},name:m,email:w,phone:g,description:v})})}function tt(e,t){const n=URL.createObjectURL(e),r=document.createElement("a");r.href=n,r.download=t,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}async function nt(e){const t=await et(e);tt(t,e.filename)}function Ot(){const e=b(x=>x.voucherConfig.language),t=b(x=>x.voucherConfig.hours),n=b(x=>x.voucherConfig.description),r=b(x=>x.voucherConfig.templateHue),a=b(x=>x.personalInfo),i=b(x=>x.portrait),s=b(x=>x.isExporting),d=b(x=>x.setIsExporting),c=F(e),u=qe(e,t),h=Re(e),m=i.useEnhanced&&i.enhanced?i.enhanced:i.original,w=Te(e,t,n),g=a.name.trim().length>0&&a.email.trim().length>0&&a.phone.trim().length>0&&i.original!==null,v=async()=>{if(!(!g||s)){d(!0);try{const x=`zeitgutschein-${t}h-${a.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await nt({frontTemplateSrc:u.front,backTemplateSrc:u.back,templateWidth:u.width,templateHeight:u.height,layout:h,portrait:m,portraitZoom:i.zoom,portraitPanX:i.panX,portraitPanY:i.panY,templateHue:r,name:a.name,email:a.email,phone:a.phone,description:w,filename:x})}catch(x){console.error("PDF export failed:",x)}finally{d(!1)}}};return o.jsxs("button",{className:`btn btn-primary flex-1 ${g?"":"btn-disabled"}`,onClick:v,disabled:!g,"aria-busy":s,children:[s?o.jsx("span",{className:"loading loading-spinner loading-sm"}):o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),c.export.button]})}function at(){const e=b(r=>r.voucherConfig.language),t=b(r=>r.setLanguage),n=r=>{t(r)};return o.jsxs("div",{className:"join",children:[o.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),o.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Ft(){const e=b(n=>n.voucherConfig.language),t=F(e);return o.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[o.jsx("div",{className:"navbar-start",children:o.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),o.jsx("div",{className:"navbar-center hidden sm:flex",children:o.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),o.jsx("div",{className:"navbar-end",children:o.jsx(at,{})})]})}const he="/",qt={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${he}templates/front_hdpi_de.jpg`,back:`${he}templates/back_hdpi_de.jpg`,width:6144,height:4096},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:G.front.portrait,name:G.front.namePlate},back:{name:G.back.namePlate,contactInfo:G.back.contactInfo,description:G.back.description}},languages:["de"]},Kt={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${he}templates/front_ldpi_en.png`,back:`${he}templates/back_ldpi_en.png`,width:1536,height:1024},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:K.front.portrait,name:K.front.namePlate},back:{name:K.back.namePlate,contactInfo:K.back.contactInfo,description:K.back.description}},languages:["en"]},ze=[qt,Kt],rt={async listTemplates(e){let t=[...ze];return e!=null&&e.type&&(t=t.filter(n=>n.type===e.type)),e!=null&&e.category&&(t=t.filter(n=>n.category===e.category)),e!=null&&e.language&&(t=t.filter(n=>n.languages.includes(e.language))),t},async getTemplate(e){const t=ze.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Gt(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let pe=rt;function Vt(e){pe=e}function Zt(){return pe}async function Jt(e){return pe.listTemplates(e)}async function Qt(e){return pe.getTemplate(e)}exports.ApiKeyModal=Fe;exports.BillPreview=_t;exports.ExportButton=Ot;exports.Header=Ft;exports.LAYOUT_HDPI=G;exports.LAYOUT_LDPI=K;exports.LanguageToggle=at;exports.PersonalInfoForm=yt;exports.PortraitUpload=Mt;exports.TEMPLATES=Se;exports.VoucherConfig=At;exports.applyEngravingEffect=Ye;exports.applyHueShift=_e;exports.downloadBlob=tt;exports.drawContactInfo=Ze;exports.drawMultilineText=Ve;exports.drawOvalPortrait=Ge;exports.drawTemplate=Ee;exports.drawText=Be;exports.enhancePortrait=Ht;exports.exportBillAsPDF=nt;exports.formatDescription=Te;exports.generateBillPDF=et;exports.getApiKey=me;exports.getDefaultTemplateId=Gt;exports.getLayout=Re;exports.getRemoveBackgroundEndpoint=Rt;exports.getTemplate=qe;exports.getTemplateById=Qt;exports.getTemplateProvider=Zt;exports.hasApiKey=Pe;exports.hasCustomEndpoint=Et;exports.listTemplates=Jt;exports.loadImage=te;exports.removeBackground=Oe;exports.renderBackSide=Qe;exports.renderFrontSide=Je;exports.setApiKey=$e;exports.setRemoveBackgroundEndpoint=St;exports.setTemplateProvider=Vt;exports.staticTemplateProvider=rt;exports.t=F;exports.useBillCanvasRefs=Wt;exports.useBillStore=b;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { jsxs as p, jsx as d, Fragment as tt } from "react/jsx-runtime";
1
+ import { jsxs as m, jsx as d, Fragment as tt } from "react/jsx-runtime";
2
2
  import { create as nt } from "zustand";
3
3
  import { persist as at } from "zustand/middleware";
4
4
  import { useState as X, useEffect as re, useCallback as B, useRef as W } from "react";
@@ -265,7 +265,7 @@ const Be = {
265
265
  function V(e) {
266
266
  return st[e];
267
267
  }
268
- function Ye(e, t, n) {
268
+ function Ue(e, t, n) {
269
269
  if (n && n.trim())
270
270
  return n;
271
271
  const r = V(e), a = t === 1 ? r.form.voucher.hourLabel : r.form.voucher.hoursLabel;
@@ -273,8 +273,8 @@ function Ye(e, t, n) {
273
273
  }
274
274
  function Kt() {
275
275
  const e = b((a) => a.voucherConfig.language), t = b((a) => a.personalInfo), n = b((a) => a.setPersonalInfo), r = V(e);
276
- return /* @__PURE__ */ p("div", { className: "space-y-4", children: [
277
- /* @__PURE__ */ p("div", { className: "form-control", children: [
276
+ return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
277
+ /* @__PURE__ */ m("div", { className: "form-control", children: [
278
278
  /* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.personalInfo.name }) }),
279
279
  /* @__PURE__ */ d(
280
280
  "input",
@@ -287,7 +287,7 @@ function Kt() {
287
287
  }
288
288
  )
289
289
  ] }),
290
- /* @__PURE__ */ p("div", { className: "form-control", children: [
290
+ /* @__PURE__ */ m("div", { className: "form-control", children: [
291
291
  /* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.personalInfo.email }) }),
292
292
  /* @__PURE__ */ d(
293
293
  "input",
@@ -300,7 +300,7 @@ function Kt() {
300
300
  }
301
301
  )
302
302
  ] }),
303
- /* @__PURE__ */ p("div", { className: "form-control", children: [
303
+ /* @__PURE__ */ m("div", { className: "form-control", children: [
304
304
  /* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.personalInfo.phone }) }),
305
305
  /* @__PURE__ */ d(
306
306
  "input",
@@ -360,13 +360,13 @@ async function ut(e, t = 0.5) {
360
360
  r.clearRect(0, 0, n.width, n.height), r.drawImage(n, 0, 0);
361
361
  const a = r.getImageData(0, 0, n.width, n.height), o = a.data, i = new Uint32Array(o.buffer), c = 1 + t * 0.8, l = 1 - t;
362
362
  for (let u = 0; u < i.length; u++) {
363
- const h = i[u], m = h & 255, y = h >> 8 & 255, g = h >> 16 & 255, x = h >> 24 & 255;
363
+ const h = i[u], p = h & 255, y = h >> 8 & 255, g = h >> 16 & 255, x = h >> 24 & 255;
364
364
  if (x === 0) continue;
365
- let k = (((77 * m + 150 * y + 29 * g >> 8) / 255 - 0.5) * c + 0.5) * 255;
365
+ let k = (((77 * p + 150 * y + 29 * g >> 8) / 255 - 0.5) * c + 0.5) * 255;
366
366
  k < 0 ? k = 0 : k > 255 && (k = 255);
367
367
  let P = k * 0.9 + 25, S = k * 0.78 + 15, I = k * 0.55 + 5;
368
368
  P > 255 && (P = 255), S > 255 && (S = 255), I > 255 && (I = 255);
369
- const C = m * l + P * t | 0, N = y * l + S * t | 0, M = g * l + I * t | 0;
369
+ const C = p * l + P * t | 0, N = y * l + S * t | 0, M = g * l + I * t | 0;
370
370
  i[u] = x << 24 | M << 16 | N << 8 | C;
371
371
  }
372
372
  return r.putImageData(a, 0, 0), j.toDataURL("image/png");
@@ -391,7 +391,7 @@ function ht(e, t, n) {
391
391
  }
392
392
  return [i, c, o];
393
393
  }
394
- function pt(e, t, n) {
394
+ function mt(e, t, n) {
395
395
  if (t === 0) {
396
396
  const i = Math.round(n * 255);
397
397
  return [i, i, i];
@@ -403,27 +403,27 @@ function pt(e, t, n) {
403
403
  Math.round(r(o, a, e - 1 / 3) * 255)
404
404
  ];
405
405
  }
406
- async function mt(e, t) {
406
+ async function pt(e, t) {
407
407
  if (t >= 155 && t <= 165)
408
408
  return e;
409
409
  const n = await ce(e), r = Se(n.width, n.height);
410
410
  r.clearRect(0, 0, n.width, n.height), r.drawImage(n, 0, 0);
411
- const a = r.getImageData(0, 0, n.width, n.height), o = a.data, i = new Uint32Array(o.buffer), c = t % 360 / 360, l = 60 / 360, u = 260 / 360, h = 1e5, m = i.length;
412
- for (let y = 0; y < m; y += h) {
413
- const g = Math.min(y + h, m);
411
+ const a = r.getImageData(0, 0, n.width, n.height), o = a.data, i = new Uint32Array(o.buffer), c = t % 360 / 360, l = 60 / 360, u = 260 / 360, h = 1e5, p = i.length;
412
+ for (let y = 0; y < p; y += h) {
413
+ const g = Math.min(y + h, p);
414
414
  for (let x = y; x < g; x++) {
415
415
  const w = i[x], k = w & 255, P = w >> 8 & 255, S = w >> 16 & 255, I = w >> 24 & 255;
416
416
  if (I === 0) continue;
417
417
  const [C, N, M] = ht(k, P, S);
418
418
  if (N < 0.06 || C < l || C > u) continue;
419
- const L = c, [H, $, R] = pt(L, N, M);
419
+ const L = c, [H, $, R] = mt(L, N, M);
420
420
  i[x] = I << 24 | R << 16 | $ << 8 | H;
421
421
  }
422
- g < m && await new Promise((x) => setTimeout(x, 0));
422
+ g < p && await new Promise((x) => setTimeout(x, 0));
423
423
  }
424
424
  return r.putImageData(a, 0, 0), j.toDataURL("image/png");
425
425
  }
426
- const gt = "https://api.stability.ai/v1/generation", ft = "https://api.stability.ai/v2beta/stable-image/edit/remove-background", ze = "stability_api_key";
426
+ const gt = "https://api.stability.ai/v1/generation", ft = "https://api.stability.ai/v2beta/stable-image/edit/remove-background", Ye = "stability_api_key";
427
427
  let oe = null;
428
428
  function qt(e) {
429
429
  oe = e;
@@ -470,8 +470,8 @@ function yt(e) {
470
470
  return;
471
471
  }
472
472
  const c = r.width / r.height, l = a.width / a.height;
473
- let u = 0, h = 0, m = r.width, y = r.height;
474
- c > l ? (m = r.height * l, u = (r.width - m) / 2) : (y = r.width / l, h = (r.height - y) / 2), i.drawImage(r, u, h, m, y, 0, 0, a.width, a.height), t(o.toDataURL("image/png"));
473
+ let u = 0, h = 0, p = r.width, y = r.height;
474
+ c > l ? (p = r.height * l, u = (r.width - p) / 2) : (y = r.width / l, h = (r.height - y) / 2), i.drawImage(r, u, h, p, y, 0, 0, a.width, a.height), t(o.toDataURL("image/png"));
475
475
  }, r.onerror = () => n(new Error("Failed to load image")), r.src = e;
476
476
  });
477
477
  }
@@ -485,10 +485,10 @@ function _e(e) {
485
485
  function Ee() {
486
486
  var t;
487
487
  const e = typeof import.meta < "u" && "sk-7mEKklrqaltdtgbX0VoZbkA8E1cl939Spn75jSIYRvp1BW0b" || typeof process < "u" && ((t = process.env) == null ? void 0 : t.NEXT_PUBLIC_STABILITY_API_KEY);
488
- return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem(ze) : null;
488
+ return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem(Ye) : null;
489
489
  }
490
490
  function vt(e) {
491
- localStorage.setItem(ze, e);
491
+ localStorage.setItem(Ye, e);
492
492
  }
493
493
  function De() {
494
494
  return oe ? !0 : Ee() !== null;
@@ -508,8 +508,8 @@ async function Zt(e) {
508
508
  body: c
509
509
  });
510
510
  if (!u.ok) {
511
- const m = await u.text();
512
- throw console.error("Stability AI error:", m), u.status === 401 ? new Error("Invalid API key") : u.status === 402 ? new Error("Insufficient credits") : u.status === 429 ? new Error("Rate limit exceeded. Please try again later.") : new Error(`API error: ${u.status}`);
511
+ const p = await u.text();
512
+ throw console.error("Stability AI error:", p), u.status === 401 ? new Error("Invalid API key") : u.status === 402 ? new Error("Insufficient credits") : u.status === 429 ? new Error("Rate limit exceeded. Please try again later.") : new Error(`API error: ${u.status}`);
513
513
  }
514
514
  const h = await u.json();
515
515
  if (!h.artifacts || h.artifacts.length === 0)
@@ -574,7 +574,7 @@ function It() {
574
574
  }
575
575
  },
576
576
  []
577
- ), m = B(
577
+ ), p = B(
578
578
  async (y) => {
579
579
  r(!0), o(null);
580
580
  try {
@@ -590,7 +590,7 @@ function It() {
590
590
  );
591
591
  return {
592
592
  enhance: h,
593
- removeBg: m,
593
+ removeBg: p,
594
594
  isEnhancing: e,
595
595
  isRemovingBg: n,
596
596
  error: a,
@@ -622,12 +622,12 @@ function kt({ isOpen: e, onClose: t, onSubmit: n }) {
622
622
  hint: "The key is stored locally in your browser."
623
623
  }
624
624
  }[r];
625
- return /* @__PURE__ */ p("dialog", { className: "modal modal-open", children: [
626
- /* @__PURE__ */ p("div", { className: "modal-box", children: [
625
+ return /* @__PURE__ */ m("dialog", { className: "modal modal-open", children: [
626
+ /* @__PURE__ */ m("div", { className: "modal-box", children: [
627
627
  /* @__PURE__ */ d("h3", { className: "font-bold text-lg", children: l.title }),
628
628
  /* @__PURE__ */ d("p", { className: "py-4 text-sm opacity-80", children: l.description }),
629
- /* @__PURE__ */ p("form", { onSubmit: i, children: [
630
- /* @__PURE__ */ p("div", { className: "form-control", children: [
629
+ /* @__PURE__ */ m("form", { onSubmit: i, children: [
630
+ /* @__PURE__ */ m("div", { className: "form-control", children: [
631
631
  /* @__PURE__ */ d(
632
632
  "input",
633
633
  {
@@ -641,7 +641,7 @@ function kt({ isOpen: e, onClose: t, onSubmit: n }) {
641
641
  ),
642
642
  /* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text-alt", children: l.hint }) })
643
643
  ] }),
644
- /* @__PURE__ */ p("div", { className: "modal-action", children: [
644
+ /* @__PURE__ */ m("div", { className: "modal-action", children: [
645
645
  /* @__PURE__ */ d("button", { type: "button", className: "btn btn-ghost", onClick: t, children: l.cancel }),
646
646
  /* @__PURE__ */ d("button", { type: "submit", className: "btn btn-primary", disabled: !a.trim(), children: l.submit })
647
647
  ] })
@@ -651,11 +651,11 @@ function kt({ isOpen: e, onClose: t, onSubmit: n }) {
651
651
  ] });
652
652
  }
653
653
  function Jt() {
654
- const e = b((s) => s.voucherConfig.language), t = b((s) => s.portrait), n = b((s) => s.setPortrait), r = b((s) => s.setPortraitZoom), a = b((s) => s.setPortraitPan), o = b((s) => s.setPortraitRawImage), i = b((s) => s.setPortraitBgRemoved), c = b((s) => s.setPortraitBgOpacity), l = b((s) => s.setPortraitBgBlur), u = b((s) => s.setPortraitEngravingIntensity), { enhance: h, removeBg: m, isEnhancing: y, isRemovingBg: g, error: x, hasKey: w, setApiKey: k } = It(), P = V(e), S = W(null), I = W(null), [C, N] = X(!1), [M, L] = X(!1), [H, $] = X(!1), R = W(null), A = W(null), U = W(null), E = t.rawImage, O = t.bgRemovedImage, Y = t.bgRemoved, F = t.bgOpacity, Z = t.bgBlur, de = t.engravingIntensity;
654
+ const e = b((s) => s.voucherConfig.language), t = b((s) => s.portrait), n = b((s) => s.setPortrait), r = b((s) => s.setPortraitZoom), a = b((s) => s.setPortraitPan), o = b((s) => s.setPortraitRawImage), i = b((s) => s.setPortraitBgRemoved), c = b((s) => s.setPortraitBgOpacity), l = b((s) => s.setPortraitBgBlur), u = b((s) => s.setPortraitEngravingIntensity), { enhance: h, removeBg: p, isEnhancing: y, isRemovingBg: g, error: x, hasKey: w, setApiKey: k } = It(), P = V(e), S = W(null), I = W(null), [C, N] = X(!1), [M, L] = X(!1), [H, $] = X(!1), R = W(null), A = W(null), z = W(null), E = t.rawImage, O = t.bgRemovedImage, U = t.bgRemoved, F = t.bgOpacity, Z = t.bgBlur, de = t.engravingIntensity;
655
655
  re(() => {
656
656
  t.original && !t.rawImage && o(t.original);
657
657
  }, [t.original, t.rawImage, o]), re(() => () => {
658
- A.current && clearTimeout(A.current), U.current && clearTimeout(U.current);
658
+ A.current && clearTimeout(A.current), z.current && clearTimeout(z.current);
659
659
  }, []);
660
660
  const ie = B(
661
661
  async (s) => {
@@ -663,9 +663,9 @@ function Jt() {
663
663
  return;
664
664
  const v = new FileReader();
665
665
  v.onload = async (T) => {
666
- var me;
667
- const z = (me = T.target) == null ? void 0 : me.result, pe = await dt(z);
668
- o(pe), n(pe), i(!1, null), u(0);
666
+ var pe;
667
+ const Y = (pe = T.target) == null ? void 0 : pe.result, me = await dt(Y);
668
+ o(me), n(me), i(!1, null), u(0);
669
669
  }, v.readAsDataURL(s);
670
670
  },
671
671
  [n, o, i, u]
@@ -695,26 +695,26 @@ function Jt() {
695
695
  }
696
696
  }, [h]), Q = B(async (s) => {
697
697
  try {
698
- const v = await m(s);
698
+ const v = await p(s);
699
699
  return i(!0, v), v;
700
700
  } catch (v) {
701
701
  return console.error("Background removal failed:", v), s;
702
702
  }
703
- }, [m, i]), G = B(async () => {
703
+ }, [p, i]), G = B(async () => {
704
704
  const s = b.getState().portrait;
705
705
  if (!s.rawImage) return;
706
706
  let v;
707
707
  s.bgRemoved && s.bgRemovedImage ? v = await Ie(s.bgRemovedImage, s.rawImage, s.bgOpacity, s.bgBlur) : v = s.rawImage, s.engravingIntensity > 0 && (v = await q(v, s.engravingIntensity)), n(v);
708
708
  }, [q, n]), se = async () => {
709
709
  if (!E) return;
710
- if (!Y && !w) {
710
+ if (!U && !w) {
711
711
  L(!0);
712
712
  return;
713
713
  }
714
- if (!Y) {
714
+ if (!U) {
715
715
  const v = await Q(E), T = b.getState().portrait;
716
- let z = await Ie(v, E, T.bgOpacity, T.bgBlur);
717
- T.engravingIntensity > 0 && (z = await q(z, T.engravingIntensity)), n(z);
716
+ let Y = await Ie(v, E, T.bgOpacity, T.bgBlur);
717
+ T.engravingIntensity > 0 && (Y = await q(Y, T.engravingIntensity)), n(Y);
718
718
  } else {
719
719
  i(!1, null);
720
720
  const v = b.getState().portrait.engravingIntensity;
@@ -729,12 +729,12 @@ function Jt() {
729
729
  }, ye = async (s) => {
730
730
  if (k(s), !E) return;
731
731
  const v = await Q(E), T = b.getState().portrait;
732
- let z = await Ie(v, E, T.bgOpacity, T.bgBlur);
733
- T.engravingIntensity > 0 && (z = await q(z, T.engravingIntensity)), n(z);
732
+ let Y = await Ie(v, E, T.bgOpacity, T.bgBlur);
733
+ T.engravingIntensity > 0 && (Y = await q(Y, T.engravingIntensity)), n(Y);
734
734
  }, ve = (s) => {
735
- c(s), U.current && clearTimeout(U.current), !(!E || !O) && (U.current = setTimeout(G, 150));
735
+ c(s), z.current && clearTimeout(z.current), !(!E || !O) && (z.current = setTimeout(G, 150));
736
736
  }, ue = (s) => {
737
- l(s), U.current && clearTimeout(U.current), !(!E || !O) && (U.current = setTimeout(G, 150));
737
+ l(s), z.current && clearTimeout(z.current), !(!E || !O) && (z.current = setTimeout(G, 150));
738
738
  }, he = () => {
739
739
  n(null), o(null), i(!1, null), c(0), l(0), u(0), ct();
740
740
  }, Ne = (s, v) => {
@@ -746,7 +746,7 @@ function Jt() {
746
746
  });
747
747
  }, Re = (s, v) => {
748
748
  if (!H || !R.current || !I.current) return;
749
- const T = I.current.getBoundingClientRect(), z = 2 / Math.max(T.width, T.height), pe = (s - R.current.x) * z, me = (v - R.current.y) * z, Qe = Math.max(-1, Math.min(1, R.current.panX + pe)), et = Math.max(-1, Math.min(1, R.current.panY + me));
749
+ const T = I.current.getBoundingClientRect(), Y = 2 / Math.max(T.width, T.height), me = (s - R.current.x) * Y, pe = (v - R.current.y) * Y, Qe = Math.max(-1, Math.min(1, R.current.panX + me)), et = Math.max(-1, Math.min(1, R.current.panY + pe));
750
750
  a(Qe, et);
751
751
  }, xe = () => {
752
752
  $(!1), R.current = null;
@@ -765,9 +765,9 @@ function Jt() {
765
765
  }, Je = () => {
766
766
  xe();
767
767
  };
768
- return /* @__PURE__ */ p("div", { className: "space-y-4", children: [
769
- t.original ? /* @__PURE__ */ p("div", { className: "flex flex-col items-center space-y-4", children: [
770
- /* @__PURE__ */ p("div", { className: "relative", children: [
768
+ return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
769
+ t.original ? /* @__PURE__ */ m("div", { className: "flex flex-col items-center space-y-4", children: [
770
+ /* @__PURE__ */ m("div", { className: "relative", children: [
771
771
  /* @__PURE__ */ d(
772
772
  "div",
773
773
  {
@@ -821,11 +821,11 @@ function Jt() {
821
821
  }
822
822
  )
823
823
  ] }),
824
- /* @__PURE__ */ p("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 w-full", children: [
825
- /* @__PURE__ */ p("div", { className: "form-control w-full", children: [
826
- /* @__PURE__ */ p("label", { className: "label", children: [
824
+ /* @__PURE__ */ m("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 w-full", children: [
825
+ /* @__PURE__ */ m("div", { className: "form-control w-full", children: [
826
+ /* @__PURE__ */ m("label", { className: "label", children: [
827
827
  /* @__PURE__ */ d("span", { className: "label-text", children: P.form.portrait.zoom }),
828
- /* @__PURE__ */ p("span", { className: "label-text-alt", children: [
828
+ /* @__PURE__ */ m("span", { className: "label-text-alt", children: [
829
829
  Math.round(t.zoom * 100),
830
830
  "%"
831
831
  ] })
@@ -846,13 +846,13 @@ function Jt() {
846
846
  }
847
847
  )
848
848
  ] }),
849
- /* @__PURE__ */ p("div", { className: "form-control w-full", children: [
850
- /* @__PURE__ */ p("label", { className: "label", children: [
851
- /* @__PURE__ */ p("span", { className: "label-text flex items-center gap-2", children: [
849
+ /* @__PURE__ */ m("div", { className: "form-control w-full", children: [
850
+ /* @__PURE__ */ m("label", { className: "label", children: [
851
+ /* @__PURE__ */ m("span", { className: "label-text flex items-center gap-2", children: [
852
852
  e === "de" ? "Sepia-Effekt" : "Sepia effect",
853
853
  y && /* @__PURE__ */ d("span", { className: "loading loading-spinner loading-xs" })
854
854
  ] }),
855
- /* @__PURE__ */ p("span", { className: "label-text-alt", children: [
855
+ /* @__PURE__ */ m("span", { className: "label-text-alt", children: [
856
856
  Math.round(de * 100),
857
857
  "%"
858
858
  ] })
@@ -872,13 +872,13 @@ function Jt() {
872
872
  )
873
873
  ] })
874
874
  ] }),
875
- Y ? (
875
+ U ? (
876
876
  // Show opacity and blur sliders when background has been removed
877
- /* @__PURE__ */ p("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 w-full", children: [
878
- /* @__PURE__ */ p("div", { className: "form-control w-full", children: [
879
- /* @__PURE__ */ p("label", { className: "label", children: [
877
+ /* @__PURE__ */ m("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 w-full", children: [
878
+ /* @__PURE__ */ m("div", { className: "form-control w-full", children: [
879
+ /* @__PURE__ */ m("label", { className: "label", children: [
880
880
  /* @__PURE__ */ d("span", { className: "label-text", children: e === "de" ? "Hintergrund" : "Background" }),
881
- /* @__PURE__ */ p("span", { className: "label-text-alt", children: [
881
+ /* @__PURE__ */ m("span", { className: "label-text-alt", children: [
882
882
  Math.round(F * 100),
883
883
  "%"
884
884
  ] })
@@ -896,10 +896,10 @@ function Jt() {
896
896
  }
897
897
  )
898
898
  ] }),
899
- /* @__PURE__ */ p("div", { className: "form-control w-full", children: [
900
- /* @__PURE__ */ p("label", { className: "label", children: [
899
+ /* @__PURE__ */ m("div", { className: "form-control w-full", children: [
900
+ /* @__PURE__ */ m("label", { className: "label", children: [
901
901
  /* @__PURE__ */ d("span", { className: "label-text", children: e === "de" ? "Unschärfe" : "Blur" }),
902
- /* @__PURE__ */ p("span", { className: "label-text-alt", children: [
902
+ /* @__PURE__ */ m("span", { className: "label-text-alt", children: [
903
903
  Math.round(Z * 100),
904
904
  "%"
905
905
  ] })
@@ -920,19 +920,19 @@ function Jt() {
920
920
  ] })
921
921
  ) : (
922
922
  // Show toggle when background not yet removed
923
- /* @__PURE__ */ d("div", { className: "form-control", children: /* @__PURE__ */ p("label", { className: "label cursor-pointer justify-start gap-3", children: [
923
+ /* @__PURE__ */ d("div", { className: "form-control", children: /* @__PURE__ */ m("label", { className: "label cursor-pointer justify-start gap-3", children: [
924
924
  /* @__PURE__ */ d(
925
925
  "input",
926
926
  {
927
927
  type: "checkbox",
928
928
  className: `toggle toggle-primary ${g ? "opacity-50" : ""}`,
929
- checked: Y,
929
+ checked: U,
930
930
  onChange: se,
931
931
  disabled: g || !E
932
932
  }
933
933
  ),
934
- /* @__PURE__ */ p("span", { className: "label-text flex items-center gap-2", children: [
935
- g ? /* @__PURE__ */ p(tt, { children: [
934
+ /* @__PURE__ */ m("span", { className: "label-text flex items-center gap-2", children: [
935
+ g ? /* @__PURE__ */ m(tt, { children: [
936
936
  /* @__PURE__ */ d("span", { className: "loading loading-spinner loading-xs" }),
937
937
  e === "de" ? "Hintergrund wird entfernt..." : "Removing background..."
938
938
  ] }) : e === "de" ? "Hintergrund entfernen" : "Remove background",
@@ -940,11 +940,11 @@ function Jt() {
940
940
  ] })
941
941
  ] }) })
942
942
  ),
943
- x && /* @__PURE__ */ p("div", { className: "alert alert-warning text-sm py-2", children: [
943
+ x && /* @__PURE__ */ m("div", { className: "alert alert-warning text-sm py-2", children: [
944
944
  /* @__PURE__ */ d("svg", { xmlns: "http://www.w3.org/2000/svg", className: "stroke-current shrink-0 h-5 w-5", fill: "none", viewBox: "0 0 24 24", children: /* @__PURE__ */ d("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
945
945
  /* @__PURE__ */ d("span", { children: x })
946
946
  ] })
947
- ] }) : /* @__PURE__ */ p(
947
+ ] }) : /* @__PURE__ */ m(
948
948
  "div",
949
949
  {
950
950
  className: `border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${g ? "border-primary bg-primary/10 pointer-events-none" : C ? "border-primary bg-primary/10" : "border-base-300 hover:border-primary hover:bg-base-200"}`,
@@ -963,10 +963,10 @@ function Jt() {
963
963
  onChange: J
964
964
  }
965
965
  ),
966
- g ? /* @__PURE__ */ p("div", { className: "flex flex-col items-center gap-2", children: [
966
+ g ? /* @__PURE__ */ m("div", { className: "flex flex-col items-center gap-2", children: [
967
967
  /* @__PURE__ */ d("span", { className: "loading loading-spinner loading-lg text-primary" }),
968
968
  /* @__PURE__ */ d("p", { className: "font-medium", children: e === "de" ? "Hintergrund wird entfernt..." : "Removing background..." })
969
- ] }) : /* @__PURE__ */ p("div", { className: "flex flex-col items-center gap-2", children: [
969
+ ] }) : /* @__PURE__ */ m("div", { className: "flex flex-col items-center gap-2", children: [
970
970
  /* @__PURE__ */ d(
971
971
  "svg",
972
972
  {
@@ -1004,10 +1004,10 @@ function Jt() {
1004
1004
  }
1005
1005
  function Qt() {
1006
1006
  const e = b((a) => a.voucherConfig.language), t = b((a) => a.voucherConfig.templateHue), n = b((a) => a.setTemplateHue), r = V(e);
1007
- return /* @__PURE__ */ d("div", { className: "space-y-4", children: /* @__PURE__ */ p("div", { className: "form-control", children: [
1008
- /* @__PURE__ */ p("label", { className: "label", children: [
1007
+ return /* @__PURE__ */ d("div", { className: "space-y-4", children: /* @__PURE__ */ m("div", { className: "form-control", children: [
1008
+ /* @__PURE__ */ m("label", { className: "label", children: [
1009
1009
  /* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.billColor.label }),
1010
- /* @__PURE__ */ p("span", { className: "label-text-alt", children: [
1010
+ /* @__PURE__ */ m("span", { className: "label-text-alt", children: [
1011
1011
  t,
1012
1012
  "°"
1013
1013
  ] })
@@ -1020,7 +1020,7 @@ function Qt() {
1020
1020
  max: "360",
1021
1021
  value: t,
1022
1022
  onChange: (a) => n(Number(a.target.value)),
1023
- className: "range range-primary",
1023
+ className: "w-full h-3 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:shadow-md [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-gray-300 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white [&::-moz-range-thumb]:shadow-md [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-gray-300",
1024
1024
  style: {
1025
1025
  background: `linear-gradient(to right,
1026
1026
  hsl(0, 70%, 50%),
@@ -1033,7 +1033,7 @@ function Qt() {
1033
1033
  }
1034
1034
  }
1035
1035
  ),
1036
- /* @__PURE__ */ p("div", { className: "flex justify-between text-xs px-1 mt-1 opacity-60", children: [
1036
+ /* @__PURE__ */ m("div", { className: "flex justify-between text-xs px-1 mt-1 opacity-60", children: [
1037
1037
  /* @__PURE__ */ d("span", { children: "0°" }),
1038
1038
  /* @__PURE__ */ d("span", { children: "90°" }),
1039
1039
  /* @__PURE__ */ d("span", { children: "180°" }),
@@ -1252,7 +1252,7 @@ async function Oe(e, t, n, r) {
1252
1252
  const c = i.getContext("2d");
1253
1253
  if (!c) throw new Error("Failed to get canvas context");
1254
1254
  c.drawImage(o, 0, 0, n, r);
1255
- const l = i.toDataURL("image/png"), u = await mt(l, t);
1255
+ const l = i.toDataURL("image/png"), u = await pt(l, t);
1256
1256
  if (ee.size > 20) {
1257
1257
  const h = ee.keys().next().value;
1258
1258
  h && ee.delete(h);
@@ -1261,10 +1261,10 @@ async function Oe(e, t, n, r) {
1261
1261
  }
1262
1262
  function St(e, t, n, r, a, o, i = 1, c = 0, l = 0) {
1263
1263
  e.save(), e.beginPath(), e.ellipse(n, r, a, o, 0, 0, Math.PI * 2), e.closePath(), e.clip();
1264
- const u = t.width / t.height, h = a / o, m = a * 2, y = o * 2;
1264
+ const u = t.width / t.height, h = a / o, p = a * 2, y = o * 2;
1265
1265
  let g, x;
1266
- u > h ? (x = y, g = y * u) : (g = m, x = m / u), g *= i, x *= i;
1267
- const w = Math.max(0, (g - m) / 2), k = Math.max(0, (x - y) / 2), P = n - g / 2 + c * w, S = r - x / 2 + l * k;
1266
+ u > h ? (x = y, g = y * u) : (g = p, x = p / u), g *= i, x *= i;
1267
+ const w = Math.max(0, (g - p) / 2), k = Math.max(0, (x - y) / 2), P = n - g / 2 + c * w, S = r - x / 2 + l * k;
1268
1268
  e.drawImage(t, P, S, g, x), e.restore();
1269
1269
  }
1270
1270
  function je(e, t, n, r = "#2a3a2a") {
@@ -1274,15 +1274,15 @@ function Et(e, t, n, r = "#2a3a2a") {
1274
1274
  e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "top", e.fillStyle = r;
1275
1275
  const a = n.maxWidth || 400, o = n.lineHeight || n.fontSize * 1.4, i = t.split(" "), c = [];
1276
1276
  let l = "";
1277
- for (const m of i) {
1278
- const y = l ? `${l} ${m}` : m;
1279
- e.measureText(y).width > a && l ? (c.push(l), l = m) : l = y;
1277
+ for (const p of i) {
1278
+ const y = l ? `${l} ${p}` : p;
1279
+ e.measureText(y).width > a && l ? (c.push(l), l = p) : l = y;
1280
1280
  }
1281
1281
  l && c.push(l);
1282
1282
  const u = c.length * o;
1283
1283
  let h = n.y - u / 2;
1284
- for (const m of c)
1285
- e.fillText(m, n.x, h), h += o;
1284
+ for (const p of c)
1285
+ e.fillText(p, n.x, h), h += o;
1286
1286
  e.restore();
1287
1287
  }
1288
1288
  function Nt(e, t, n, r, a, o = "#2a3a2a") {
@@ -1294,15 +1294,15 @@ function Nt(e, t, n, r, a, o = "#2a3a2a") {
1294
1294
  e.restore();
1295
1295
  }
1296
1296
  async function Rt(e, t, n, r, a, o, i, c = 1, l = 0, u = 0, h = 0) {
1297
- const m = e.getContext("2d");
1298
- if (!m) return;
1299
- e.width = o, e.height = i, m.clearRect(0, 0, o, i);
1297
+ const p = e.getContext("2d");
1298
+ if (!p) return;
1299
+ e.width = o, e.height = i, p.clearRect(0, 0, o, i);
1300
1300
  const y = await Oe(t, h, o, i);
1301
- if ($e(m, y, o, i), n)
1301
+ if ($e(p, y, o, i), n)
1302
1302
  try {
1303
1303
  const g = await le(n);
1304
1304
  St(
1305
- m,
1305
+ p,
1306
1306
  g,
1307
1307
  a.portrait.x,
1308
1308
  a.portrait.y,
@@ -1315,14 +1315,14 @@ async function Rt(e, t, n, r, a, o, i, c = 1, l = 0, u = 0, h = 0) {
1315
1315
  } catch (g) {
1316
1316
  console.error("Failed to load portrait:", g);
1317
1317
  }
1318
- r && je(m, r, a.namePlate);
1318
+ r && je(p, r, a.namePlate);
1319
1319
  }
1320
1320
  async function Bt(e, t, n, r, a, o, i, c, l, u = 0) {
1321
1321
  const h = e.getContext("2d");
1322
1322
  if (!h) return;
1323
1323
  e.width = c, e.height = l, h.clearRect(0, 0, c, l);
1324
- const m = await Oe(t, u, c, l);
1325
- $e(h, m, c, l), i.contactInfo && (n || r || a) && Nt(h, n, r, a, i.contactInfo), i.description && o && Et(h, o, i.description), n && je(h, n, i.namePlate);
1324
+ const p = await Oe(t, u, c, l);
1325
+ $e(h, p, c, l), i.contactInfo && (n || r || a) && Nt(h, n, r, a, i.contactInfo), i.description && o && Et(h, o, i.description), n && je(h, n, i.namePlate);
1326
1326
  }
1327
1327
  function Lt(e, t) {
1328
1328
  const [n, r] = X(e);
@@ -1332,10 +1332,10 @@ function Lt(e, t) {
1332
1332
  }, [e, t]), n;
1333
1333
  }
1334
1334
  function en() {
1335
- const e = b((f) => f.voucherConfig.language), t = b((f) => f.voucherConfig.hours), n = b((f) => f.voucherConfig.description), r = b((f) => f.voucherConfig.templateHue), a = b((f) => f.personalInfo), o = b((f) => f.portrait), i = b((f) => f.currentSide), c = b((f) => f.flipSide), l = b((f) => f.setPortraitPan), u = Lt(r, 150), h = V(e), m = W(null), y = W(null), g = W(null), [x, w] = X(!1), [k, P] = X(!1), S = W(null), I = Tt(e, t), C = Ct(e), N = o.useEnhanced && o.enhanced ? o.enhanced : o.original, M = Ye(e, t, n);
1335
+ const e = b((f) => f.voucherConfig.language), t = b((f) => f.voucherConfig.hours), n = b((f) => f.voucherConfig.description), r = b((f) => f.voucherConfig.templateHue), a = b((f) => f.personalInfo), o = b((f) => f.portrait), i = b((f) => f.currentSide), c = b((f) => f.flipSide), l = b((f) => f.setPortraitPan), u = Lt(r, 150), h = V(e), p = W(null), y = W(null), g = W(null), [x, w] = X(!1), [k, P] = X(!1), S = W(null), I = Tt(e, t), C = Ct(e), N = o.useEnhanced && o.enhanced ? o.enhanced : o.original, M = Ue(e, t, n);
1336
1336
  re(() => {
1337
- m.current && Rt(
1338
- m.current,
1337
+ p.current && Rt(
1338
+ p.current,
1339
1339
  I.front,
1340
1340
  N,
1341
1341
  a.name,
@@ -1382,11 +1382,11 @@ function en() {
1382
1382
  l(G, se);
1383
1383
  }, [k, l]), A = B(() => {
1384
1384
  P(!1), S.current = null;
1385
- }, []), U = (f) => {
1385
+ }, []), z = (f) => {
1386
1386
  o.zoom > 1 && H(f.clientX, f.clientY) && (f.preventDefault(), $(f.clientX, f.clientY));
1387
1387
  }, E = (f) => {
1388
1388
  R(f.clientX, f.clientY);
1389
- }, O = () => A(), Y = () => A(), F = (f) => {
1389
+ }, O = () => A(), U = () => A(), F = (f) => {
1390
1390
  if (f.touches.length === 1) {
1391
1391
  const D = f.touches[0];
1392
1392
  o.zoom > 1 && H(D.clientX, D.clientY) && $(D.clientX, D.clientY);
@@ -1394,9 +1394,9 @@ function en() {
1394
1394
  }, Z = (f) => {
1395
1395
  f.touches.length === 1 && R(f.touches[0].clientX, f.touches[0].clientY);
1396
1396
  }, de = () => A(), ie = i === "front" && o.original && o.zoom > 1, be = I.width / I.height;
1397
- return /* @__PURE__ */ p("div", { className: "space-y-4", children: [
1398
- /* @__PURE__ */ p("div", { className: "flex justify-between items-center", children: [
1399
- /* @__PURE__ */ p("div", { className: "tabs tabs-boxed bg-base-200", children: [
1397
+ return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
1398
+ /* @__PURE__ */ m("div", { className: "flex justify-between items-center", children: [
1399
+ /* @__PURE__ */ m("div", { className: "tabs tabs-boxed bg-base-200", children: [
1400
1400
  /* @__PURE__ */ d(
1401
1401
  "button",
1402
1402
  {
@@ -1414,7 +1414,7 @@ function en() {
1414
1414
  }
1415
1415
  )
1416
1416
  ] }),
1417
- /* @__PURE__ */ p("button", { className: "btn btn-ghost btn-sm", onClick: L, children: [
1417
+ /* @__PURE__ */ m("button", { className: "btn btn-ghost btn-sm", onClick: L, children: [
1418
1418
  /* @__PURE__ */ d(
1419
1419
  "svg",
1420
1420
  {
@@ -1437,16 +1437,16 @@ function en() {
1437
1437
  h.preview.flip
1438
1438
  ] })
1439
1439
  ] }),
1440
- /* @__PURE__ */ p(
1440
+ /* @__PURE__ */ m(
1441
1441
  "div",
1442
1442
  {
1443
1443
  ref: g,
1444
1444
  className: `relative w-full overflow-hidden shadow-lg ${ie ? k ? "cursor-grabbing" : "cursor-grab" : ""}`,
1445
1445
  style: { aspectRatio: be },
1446
- onMouseDown: U,
1446
+ onMouseDown: z,
1447
1447
  onMouseMove: E,
1448
1448
  onMouseUp: O,
1449
- onMouseLeave: Y,
1449
+ onMouseLeave: U,
1450
1450
  onTouchStart: F,
1451
1451
  onTouchMove: Z,
1452
1452
  onTouchEnd: de,
@@ -1454,7 +1454,7 @@ function en() {
1454
1454
  /* @__PURE__ */ d(
1455
1455
  "canvas",
1456
1456
  {
1457
- ref: m,
1457
+ ref: p,
1458
1458
  className: `absolute inset-0 w-full h-full transition-all duration-300 ${i === "front" ? x ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
1459
1459
  }
1460
1460
  ),
@@ -1859,7 +1859,7 @@ async function Mt(e) {
1859
1859
  portraitPanX: l = 0,
1860
1860
  portraitPanY: u = 0,
1861
1861
  templateHue: h = 160,
1862
- name: m,
1862
+ name: p,
1863
1863
  email: y,
1864
1864
  phone: g,
1865
1865
  description: x
@@ -1877,12 +1877,12 @@ async function Mt(e) {
1877
1877
  I(new Error("Invalid response from worker"));
1878
1878
  return;
1879
1879
  }
1880
- const U = Ae(H, "image/jpeg"), E = Ae($, "image/jpeg"), O = R / 96 * 25.4, Y = A / 96 * 25.4, F = new rt({
1881
- orientation: O > Y ? "landscape" : "portrait",
1880
+ const z = Ae(H, "image/jpeg"), E = Ae($, "image/jpeg"), O = R / 96 * 25.4, U = A / 96 * 25.4, F = new rt({
1881
+ orientation: O > U ? "landscape" : "portrait",
1882
1882
  unit: "mm",
1883
- format: [O, Y]
1883
+ format: [O, U]
1884
1884
  });
1885
- F.addImage(U, "JPEG", 0, 0, O, Y), F.addPage([O, Y]), F.addImage(E, "JPEG", 0, 0, O, Y);
1885
+ F.addImage(z, "JPEG", 0, 0, O, U), F.addPage([O, U]), F.addImage(E, "JPEG", 0, 0, O, U);
1886
1886
  const Z = F.output("blob");
1887
1887
  S(Z);
1888
1888
  } catch (H) {
@@ -1915,7 +1915,7 @@ async function Mt(e) {
1915
1915
  description: o.back.description
1916
1916
  }
1917
1917
  },
1918
- name: m,
1918
+ name: p,
1919
1919
  email: y,
1920
1920
  phone: g,
1921
1921
  description: x
@@ -1926,13 +1926,13 @@ function At(e, t) {
1926
1926
  const n = URL.createObjectURL(e), r = document.createElement("a");
1927
1927
  r.href = n, r.download = t, document.body.appendChild(r), r.click(), document.body.removeChild(r), URL.revokeObjectURL(n);
1928
1928
  }
1929
- async function Ut(e) {
1929
+ async function zt(e) {
1930
1930
  const t = await Mt(e);
1931
1931
  At(t, e.filename);
1932
1932
  }
1933
1933
  function nn() {
1934
- const e = b((w) => w.voucherConfig.language), t = b((w) => w.voucherConfig.hours), n = b((w) => w.voucherConfig.description), r = b((w) => w.voucherConfig.templateHue), a = b((w) => w.personalInfo), o = b((w) => w.portrait), i = b((w) => w.isExporting), c = b((w) => w.setIsExporting), l = V(e), u = Pt(e, t), h = Xe(e), m = o.useEnhanced && o.enhanced ? o.enhanced : o.original, y = Ye(e, t, n), g = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && o.original !== null;
1935
- return /* @__PURE__ */ p(
1934
+ const e = b((w) => w.voucherConfig.language), t = b((w) => w.voucherConfig.hours), n = b((w) => w.voucherConfig.description), r = b((w) => w.voucherConfig.templateHue), a = b((w) => w.personalInfo), o = b((w) => w.portrait), i = b((w) => w.isExporting), c = b((w) => w.setIsExporting), l = V(e), u = Pt(e, t), h = Xe(e), p = o.useEnhanced && o.enhanced ? o.enhanced : o.original, y = Ue(e, t, n), g = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && o.original !== null;
1935
+ return /* @__PURE__ */ m(
1936
1936
  "button",
1937
1937
  {
1938
1938
  className: `btn btn-primary flex-1 ${g ? "" : "btn-disabled"}`,
@@ -1941,13 +1941,13 @@ function nn() {
1941
1941
  c(!0);
1942
1942
  try {
1943
1943
  const w = `zeitgutschein-${t}h-${a.name.replace(/\s+/g, "-").toLowerCase()}.pdf`;
1944
- await Ut({
1944
+ await zt({
1945
1945
  frontTemplateSrc: u.front,
1946
1946
  backTemplateSrc: u.back,
1947
1947
  templateWidth: u.width,
1948
1948
  templateHeight: u.height,
1949
1949
  layout: h,
1950
- portrait: m,
1950
+ portrait: p,
1951
1951
  portraitZoom: o.zoom,
1952
1952
  portraitPanX: o.panX,
1953
1953
  portraitPanY: o.panY,
@@ -1992,11 +1992,11 @@ function nn() {
1992
1992
  }
1993
1993
  );
1994
1994
  }
1995
- function Yt() {
1995
+ function Ut() {
1996
1996
  const e = b((r) => r.voucherConfig.language), t = b((r) => r.setLanguage), n = (r) => {
1997
1997
  t(r);
1998
1998
  };
1999
- return /* @__PURE__ */ p("div", { className: "join", children: [
1999
+ return /* @__PURE__ */ m("div", { className: "join", children: [
2000
2000
  /* @__PURE__ */ d(
2001
2001
  "button",
2002
2002
  {
@@ -2017,13 +2017,13 @@ function Yt() {
2017
2017
  }
2018
2018
  function an() {
2019
2019
  const e = b((n) => n.voucherConfig.language), t = V(e);
2020
- return /* @__PURE__ */ p("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
2020
+ return /* @__PURE__ */ m("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
2021
2021
  /* @__PURE__ */ d("div", { className: "navbar-start", children: /* @__PURE__ */ d("a", { className: "btn btn-ghost text-xl font-currency font-bold", children: t.header.title }) }),
2022
2022
  /* @__PURE__ */ d("div", { className: "navbar-center hidden sm:flex", children: /* @__PURE__ */ d("span", { className: "text-sm opacity-80", children: t.header.subtitle }) }),
2023
- /* @__PURE__ */ d("div", { className: "navbar-end", children: /* @__PURE__ */ d(Yt, {}) })
2023
+ /* @__PURE__ */ d("div", { className: "navbar-end", children: /* @__PURE__ */ d(Ut, {}) })
2024
2024
  ] });
2025
2025
  }
2026
- const ge = "/", zt = {
2026
+ const ge = "/", Yt = {
2027
2027
  id: "time-voucher-classic-de",
2028
2028
  name: "Zeitgutschein Classic",
2029
2029
  type: "time-voucher",
@@ -2151,16 +2151,16 @@ const ge = "/", zt = {
2151
2151
  }
2152
2152
  },
2153
2153
  languages: ["en"]
2154
- }, Ue = [
2155
- zt,
2154
+ }, ze = [
2155
+ Yt,
2156
2156
  _t
2157
2157
  ], Wt = {
2158
2158
  async listTemplates(e) {
2159
- let t = [...Ue];
2159
+ let t = [...ze];
2160
2160
  return e != null && e.type && (t = t.filter((n) => n.type === e.type)), e != null && e.category && (t = t.filter((n) => n.category === e.category)), e != null && e.language && (t = t.filter((n) => n.languages.includes(e.language))), t;
2161
2161
  },
2162
2162
  async getTemplate(e) {
2163
- const t = Ue.find((n) => n.id === e);
2163
+ const t = ze.find((n) => n.id === e);
2164
2164
  if (!t)
2165
2165
  throw new Error(`Template not found: ${e}`);
2166
2166
  return t;
@@ -2189,13 +2189,13 @@ export {
2189
2189
  an as Header,
2190
2190
  ae as LAYOUT_HDPI,
2191
2191
  ne as LAYOUT_LDPI,
2192
- Yt as LanguageToggle,
2192
+ Ut as LanguageToggle,
2193
2193
  Kt as PersonalInfoForm,
2194
2194
  Jt as PortraitUpload,
2195
2195
  We as TEMPLATES,
2196
2196
  Qt as VoucherConfig,
2197
2197
  ut as applyEngravingEffect,
2198
- mt as applyHueShift,
2198
+ pt as applyHueShift,
2199
2199
  At as downloadBlob,
2200
2200
  Nt as drawContactInfo,
2201
2201
  Et as drawMultilineText,
@@ -2203,8 +2203,8 @@ export {
2203
2203
  $e as drawTemplate,
2204
2204
  je as drawText,
2205
2205
  Zt as enhancePortrait,
2206
- Ut as exportBillAsPDF,
2207
- Ye as formatDescription,
2206
+ zt as exportBillAsPDF,
2207
+ Ue as formatDescription,
2208
2208
  Mt as generateBillPDF,
2209
2209
  Ee as getApiKey,
2210
2210
  rn as getDefaultTemplateId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antontranelis/money-printer",
3
- "version": "1.0.23",
3
+ "version": "1.0.24",
4
4
  "description": "Create personalized time vouchers that look like real currency. React components for voucher generation with PDF export.",
5
5
  "type": "module",
6
6
  "license": "MIT",