@antontranelis/money-printer 1.0.28 → 1.0.30

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"),bt=require("zustand"),xt=require("zustand/middleware"),p=require("react"),wt=require("jspdf");var ie=typeof document<"u"?document.currentScript:null;const Ne={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=bt.create()(xt.persist(e=>({...Ne,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(Ne)}),{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}})})),yt={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"}},vt={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"}},kt={de:yt,en:vt};function K(e){return kt[e]}function Se(e,t,n){if(n&&n.trim())return n;const r=K(e),a=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",a)}function It(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.personalInfo),n=b(a=>a.setPersonalInfo),r=K(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 Pt=1024,re=new Map;let $=null,De=null;function Te(e,t){return $||($=document.createElement("canvas"),De=$.getContext("2d",{willReadFrequently:!0})),($.width!==e||$.height!==t)&&($.width=e,$.height=t),De}function de(e){const t=re.get(e);return t?Promise.resolve(t):new Promise((n,r)=>{const a=new Image;a.onload=()=>{if(re.size>10){const i=re.keys().next().value;i&&re.delete(i)}re.set(e,a),n(a)},a.onerror=()=>r(new Error("Failed to load image")),a.src=e})}function Ct(){re.clear()}async function St(e,t=Pt){const n=await de(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),c=document.createElement("canvas"),d=c.getContext("2d");if(!d)throw new Error("Failed to get canvas context");return c.width=i,c.height=s,d.drawImage(n,0,0,i,s),c.toDataURL("image/jpeg",.9)}async function ye(e,t,n,r=0){const[a,i]=await Promise.all([de(e),de(t)]),s=Te(a.width,a.height);if(s.clearRect(0,0,a.width,a.height),n>0){const c=r*20;s.save(),s.globalAlpha=n,c>0&&(s.filter=`blur(${c}px)`),s.drawImage(i,0,0,a.width,a.height),s.restore()}return s.drawImage(a,0,0),$.toDataURL("image/png")}async function Ye(e,t=.5,n=40){const r=await de(e),a=Te(r.width,r.height);a.clearRect(0,0,r.width,r.height),a.drawImage(r,0,0);const i=a.getImageData(0,0,r.width,r.height),s=i.data,c=new Uint32Array(s.buffer),d=1+t*.8,u=1-t,y=n%360/360;for(let x=0;x<c.length;x++){const g=c[x],h=g&255,v=g>>8&255,m=g>>16&255,T=g>>24&255;if(T===0)continue;let k=(((77*h+150*v+29*m>>8)/255-.5)*d+.5)*255;k<0?k=0:k>255&&(k=255);const I=k/255,R=.12,[S,U,N]=_e(y,R,I),j=h*u+S*t|0,D=v*u+U*t|0,E=m*u+N*t|0;c[x]=T<<24|E<<16|D<<8|j}return a.putImageData(i,0,0),$.toDataURL("image/png")}function Tt(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,c=0;if(r!==a){const d=r-a;switch(c=i>.5?d/(2-r-a):d/(r+a),r){case e:s=((t-n)/d+(t<n?6:0))/6;break;case t:s=((n-e)/d+2)/6;break;case n:s=((e-t)/d+4)/6;break}}return[s,c,i]}function _e(e,t,n){if(t===0){const s=Math.round(n*255);return[s,s,s]}const r=(s,c,d)=>(d<0&&(d+=1),d>1&&(d-=1),d<1/6?s+(c-s)*6*d:d<1/2?c:d<2/3?s+(c-s)*(2/3-d)*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 We(e,t){if(t>=155&&t<=165)return e;const n=await de(e),r=Te(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),c=t%360/360,d=60/360,u=260/360,y=1e5,x=s.length;for(let g=0;g<x;g+=y){const h=Math.min(g+y,x);for(let v=g;v<h;v++){const m=s[v],T=m&255,H=m>>8&255,k=m>>16&255,I=m>>24&255;if(I===0)continue;const[R,S,U]=Tt(T,H,k);if(S<.06||R<d||R>u)continue;const N=c,[j,D,E]=_e(N,S,U);s[v]=I<<24|E<<16|D<<8|j}h<x&&await new Promise(v=>setTimeout(v,0))}return r.putImageData(a,0,0),$.toDataURL("image/png")}const Rt="https://api.stability.ai/v1/generation",jt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",Xe="stability_api_key";let se=null;function Et(e){se=e}function Bt(){return se}function Ht(){return se!==null}const Lt={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,c=Math.abs(n-s);c<a&&(a=c,r=i)}return r}function Dt(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 c=r.width/r.height,d=a.width/a.height;let u=0,y=0,x=r.width,g=r.height;c>d?(x=r.height*d,u=(r.width-x)/2):(g=r.width/d,y=(r.height-g)/2),s.drawImage(r,u,y,x,g,0,0,a.width,a.height),t(i.toDataURL("image/png"))},r.onerror=()=>n(new Error("Failed to load image")),r.src=e})}function $e(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 c=0;c<a;c++)i[c]=r.charCodeAt(c);return new Blob([i],{type:n})}function pe(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ie&&ie.tagName.toUpperCase()==="SCRIPT"&&ie.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(Xe):null}function Oe(e){localStorage.setItem(Xe,e)}function Pe(){return se?!0:pe()!==null}async function Mt(e){const t=pe();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,i=await Dt(n),s=$e(i),c=new FormData;c.append("init_image",s,"portrait.png"),c.append("init_image_mode","IMAGE_STRENGTH"),c.append("image_strength",String(1-a)),c.append("text_prompts[0][text]",Lt[r]),c.append("text_prompts[0][weight]","1"),c.append("cfg_scale","7"),c.append("samples","1"),c.append("steps","30");const u=await fetch(`${Rt}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:c});if(!u.ok){const x=await u.text();throw console.error("Stability AI error:",x),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 y=await u.json();if(!y.artifacts||y.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${y.artifacts[0].base64}`}async function Fe(e){if(se){const s=await fetch(se,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!s.ok){const d=await s.json().catch(()=>({}));throw new Error(d.error||`API error: ${s.status}`)}return(await s.json()).imageDataUrl}const t=pe();if(!t)throw new Error("No Stability AI API key configured");const n=$e(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,c)=>{const d=new FileReader;d.onload=()=>s(d.result),d.onerror=()=>c(new Error("Failed to read result")),d.readAsDataURL(i)})}function At(){const[e,t]=p.useState(!1),[n,r]=p.useState(!1),[a,i]=p.useState(null),[s,c]=p.useState(()=>Pe());p.useEffect(()=>{c(Pe())},[]);const d=p.useCallback(()=>i(null),[]),u=p.useCallback(g=>{Oe(g),c(!0),i(null)},[]),y=p.useCallback(async(g,h=.5,v=40)=>{t(!0),i(null);try{return await Ye(g,h,v)}catch(m){const T=m instanceof Error?m.message:"Enhancement failed";throw i(T),m}finally{t(!1)}},[]),x=p.useCallback(async g=>{r(!0),i(null);try{return await Fe(g)}catch(h){const v=h instanceof Error?h.message:"Background removal failed";throw i(v),h}finally{r(!1)}},[]);return{enhance:y,removeBg:x,isEnhancing:e,isRemovingBg:n,error:a,hasKey:s,setApiKey:u,clearError:d}}function qe({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())},d={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:d.title}),o.jsx("p",{className:"py-4 text-sm opacity-80",children:d.description}),o.jsxs("form",{onSubmit:s,children:[o.jsxs("div",{className:"form-control",children:[o.jsx("input",{type:"password",placeholder:d.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:d.hint})})]}),o.jsxs("div",{className:"modal-action",children:[o.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:d.cancel}),o.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:d.submit})]})]})]}),o.jsx("form",{method:"dialog",className:"modal-backdrop",children:o.jsx("button",{onClick:t,children:"close"})})]})}function Ut(){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),c=b(l=>l.setPortraitBgOpacity),d=b(l=>l.setPortraitBgBlur),u=b(l=>l.setPortraitEngravingIntensity),{enhance:y,removeBg:x,isEnhancing:g,isRemovingBg:h,error:v,hasKey:m,setApiKey:T}=At(),H=K(e),k=p.useRef(null),I=p.useRef(null),[R,S]=p.useState(!1),[U,N]=p.useState(!1),[j,D]=p.useState(!1),E=p.useRef(null),L=p.useRef(null),M=p.useRef(null),B=t.rawImage,J=t.bgRemovedImage,z=t.bgRemoved,W=t.bgOpacity,O=t.bgBlur,Q=t.engravingIntensity;p.useEffect(()=>{t.original&&!t.rawImage&&i(t.original)},[t.original,t.rawImage,i]),p.useEffect(()=>()=>{L.current&&clearTimeout(L.current),M.current&&clearTimeout(M.current)},[]);const ee=b(l=>l.voucherConfig.templateHue),ue=p.useRef(ee),f=p.useCallback(async l=>{if(!l.type.startsWith("image/"))return;const w=new FileReader;w.onload=async C=>{var Y;const P=(Y=C.target)==null?void 0:Y.result,X=await St(P);i(X),n(X),s(!1,null),u(0)},w.readAsDataURL(l)},[n,i,s,u]),A=p.useCallback(l=>{l.preventDefault(),S(!1);const w=l.dataTransfer.files[0];w&&f(w)},[f]),F=p.useCallback(l=>{l.preventDefault(),S(!0)},[]),te=p.useCallback(l=>{l.preventDefault(),S(!1)},[]),le=()=>{var l;(l=k.current)==null||l.click()},ce=l=>{var C;const w=(C=l.target.files)==null?void 0:C[0];w&&f(w)},q=p.useCallback(async(l,w,C)=>{try{return await y(l,w,C)}catch(P){return console.error("Enhancement failed:",P),l}},[y]),ne=p.useCallback(async l=>{try{const w=await x(l);return s(!0,w),w}catch(w){return console.error("Background removal failed:",w),l}},[x,s]),G=p.useCallback(async()=>{const l=b.getState(),w=l.portrait,C=l.voucherConfig.templateHue;if(!w.rawImage)return;let P;w.bgRemoved&&w.bgRemovedImage?P=await ye(w.bgRemovedImage,w.rawImage,w.bgOpacity,w.bgBlur):P=w.rawImage,w.engravingIntensity>0&&(P=await q(P,w.engravingIntensity,C)),n(P)},[q,n]);p.useEffect(()=>{if(ue.current===ee)return;ue.current=ee;const l=b.getState().portrait;l.engravingIntensity>0&&l.rawImage&&(L.current&&clearTimeout(L.current),L.current=setTimeout(G,150))},[ee,G]);const be=async()=>{if(!B)return;if(!z&&!m){N(!0);return}if(!z){const w=await ne(B),C=b.getState(),P=C.portrait,X=C.voucherConfig.templateHue;let Y=await ye(w,B,P.bgOpacity,P.bgBlur);P.engravingIntensity>0&&(Y=await q(Y,P.engravingIntensity,X)),n(Y)}else{s(!1,null);const w=b.getState(),C=w.portrait.engravingIntensity,P=w.voucherConfig.templateHue;if(C>0){const X=await q(B,C,P);n(X)}else n(B)}},xe=l=>{u(l),L.current&&clearTimeout(L.current),B&&(L.current=setTimeout(G,150))},he=async l=>{if(T(l),!B)return;const w=await ne(B),C=b.getState(),P=C.portrait,X=C.voucherConfig.templateHue;let Y=await ye(w,B,P.bgOpacity,P.bgBlur);P.engravingIntensity>0&&(Y=await q(Y,P.engravingIntensity,X)),n(Y)},me=l=>{c(l),M.current&&clearTimeout(M.current),!(!B||!J)&&(M.current=setTimeout(G,150))},it=l=>{d(l),M.current&&clearTimeout(M.current),!(!B||!J)&&(M.current=setTimeout(G,150))},st=()=>{n(null),i(null),s(!1,null),c(0),d(0),u(0),Ct()},He=(l,w)=>{t.zoom<=1||(D(!0),E.current={x:l,y:w,panX:t.panX,panY:t.panY})},Le=(l,w)=>{if(!j||!E.current||!I.current)return;const C=I.current.getBoundingClientRect(),P=2/Math.max(C.width,C.height),X=(l-E.current.x)*P,Y=(w-E.current.y)*P,pt=Math.max(-1,Math.min(1,E.current.panX+X)),ft=Math.max(-1,Math.min(1,E.current.panY+Y));a(pt,ft)},we=()=>{D(!1),E.current=null},lt=l=>{l.preventDefault(),He(l.clientX,l.clientY)},ct=l=>{Le(l.clientX,l.clientY)},dt=()=>{we()},ut=()=>{we()},ht=l=>{l.touches.length===1&&He(l.touches[0].clientX,l.touches[0].clientY)},mt=l=>{l.touches.length===1&&Le(l.touches[0].clientX,l.touches[0].clientY)},gt=()=>{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":""} ${j?"cursor-grabbing":""}`,onMouseDown:lt,onMouseMove:ct,onMouseUp:dt,onMouseLeave:ut,onTouchStart:ht,onTouchMove:mt,onTouchEnd:gt,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:st,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:H.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 w=parseFloat(l.target.value);r(w),w<=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"?"Farbanpassung":"Color adjustment",g&&o.jsx("span",{className:"loading loading-spinner loading-xs"})]}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(Q*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:Q,onChange:l=>xe(parseFloat(l.target.value)),className:"range range-secondary range-sm",disabled:g||!B})]})]}),z?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(W*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:W,onChange:l=>me(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(O*100),"%"]})]}),o.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:O,onChange:l=>it(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 ${h?"opacity-50":""}`,checked:z,onChange:be,disabled:h||!B}),o.jsxs("span",{className:"label-text flex items-center gap-2",children:[h?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",!m&&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 ${h?"border-primary bg-primary/10 pointer-events-none":R?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:A,onDragOver:F,onDragLeave:te,onClick:le,children:[o.jsx("input",{ref:k,type:"file",accept:"image/*",className:"hidden",onChange:ce}),h?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:H.form.portrait.upload}),o.jsx("p",{className:"text-sm text-base-content/60",children:H.form.portrait.dragDrop})]})]}),o.jsx(qe,{isOpen:U,onClose:()=>N(!1),onSubmit:he})]})}function zt(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.voucherConfig.templateHue),n=b(a=>a.setTemplateHue),r=K(e);return o.jsx("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.billColor.label})}),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,
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),bt=require("zustand"),xt=require("zustand/middleware"),p=require("react"),wt=require("jspdf");var ie=typeof document<"u"?document.currentScript:null;const De={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,appLanguage:"de"},g=bt.create()(xt.persist(e=>({...De,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}),setAppLanguage:t=>e({appLanguage:t}),setBillLanguage: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(De)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig,appLanguage:e.appLanguage,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}})})),yt={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?",billLanguage:"Schein-Sprache",billLanguageGerman:"Deutsch",billLanguageEnglish:"Englisch"},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"}},vt={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?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},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"}},kt={de:yt,en:vt};function G(e){return kt[e]}function Te(e,t,n){if(n&&n.trim())return n;const r=G(e),a=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",a)}function It(){const e=g(a=>a.appLanguage),t=g(a=>a.personalInfo),n=g(a=>a.setPersonalInfo),r=G(e);return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),i.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})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),i.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})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),i.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 Pt=1024,re=new Map;let $=null,Me=null;function Le(e,t){return $||($=document.createElement("canvas"),Me=$.getContext("2d",{willReadFrequently:!0})),($.width!==e||$.height!==t)&&($.width=e,$.height=t),Me}function ue(e){const t=re.get(e);return t?Promise.resolve(t):new Promise((n,r)=>{const a=new Image;a.onload=()=>{if(re.size>10){const s=re.keys().next().value;s&&re.delete(s)}re.set(e,a),n(a)},a.onerror=()=>r(new Error("Failed to load image")),a.src=e})}function Ct(){re.clear()}async function St(e,t=Pt){const n=await ue(e),r=Math.max(n.width,n.height);if(r<=t)return e;const a=t/r,s=Math.round(n.width*a),o=Math.round(n.height*a),l=document.createElement("canvas"),u=l.getContext("2d");if(!u)throw new Error("Failed to get canvas context");return l.width=s,l.height=o,u.drawImage(n,0,0,s,o),l.toDataURL("image/jpeg",.9)}async function ve(e,t,n,r=0){const[a,s]=await Promise.all([ue(e),ue(t)]),o=Le(a.width,a.height);if(o.clearRect(0,0,a.width,a.height),n>0){const l=r*20;o.save(),o.globalAlpha=n,l>0&&(o.filter=`blur(${l}px)`),o.drawImage(s,0,0,a.width,a.height),o.restore()}return o.drawImage(a,0,0),$.toDataURL("image/png")}async function _e(e,t=.5,n=40){const r=await ue(e),a=Le(r.width,r.height);a.clearRect(0,0,r.width,r.height),a.drawImage(r,0,0);const s=a.getImageData(0,0,r.width,r.height),o=s.data,l=new Uint32Array(o.buffer),u=1+t*.8,d=1-t,b=n%360/360;for(let x=0;x<l.length;x++){const h=l[x],m=h&255,y=h>>8&255,k=h>>16&255,v=h>>24&255;if(v===0)continue;let S=(((77*m+150*y+29*k>>8)/255-.5)*u+.5)*255;S<0?S=0:S>255&&(S=255);const L=S/255,I=.12,[C,z,M]=We(b,I,L),B=m*d+C*t|0,N=y*d+z*t|0,j=k*d+M*t|0;l[x]=v<<24|j<<16|N<<8|B}return a.putImageData(s,0,0),$.toDataURL("image/png")}function Tt(e,t,n){e/=255,t/=255,n/=255;const r=Math.max(e,t,n),a=Math.min(e,t,n),s=(r+a)/2;let o=0,l=0;if(r!==a){const u=r-a;switch(l=s>.5?u/(2-r-a):u/(r+a),r){case e:o=((t-n)/u+(t<n?6:0))/6;break;case t:o=((n-e)/u+2)/6;break;case n:o=((e-t)/u+4)/6;break}}return[o,l,s]}function We(e,t,n){if(t===0){const o=Math.round(n*255);return[o,o,o]}const r=(o,l,u)=>(u<0&&(u+=1),u>1&&(u-=1),u<1/6?o+(l-o)*6*u:u<1/2?l:u<2/3?o+(l-o)*(2/3-u)*6:o),a=n<.5?n*(1+t):n+t-n*t,s=2*n-a;return[Math.round(r(s,a,e+1/3)*255),Math.round(r(s,a,e)*255),Math.round(r(s,a,e-1/3)*255)]}async function Xe(e,t){if(t>=155&&t<=165)return e;const n=await ue(e),r=Le(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),s=a.data,o=new Uint32Array(s.buffer),l=t%360/360,u=60/360,d=260/360,b=1e5,x=o.length;for(let h=0;h<x;h+=b){const m=Math.min(h+b,x);for(let y=h;y<m;y++){const k=o[y],v=k&255,R=k>>8&255,S=k>>16&255,L=k>>24&255;if(L===0)continue;const[I,C,z]=Tt(v,R,S);if(C<.06||I<u||I>d)continue;const M=l,[B,N,j]=We(M,C,z);o[y]=L<<24|j<<16|N<<8|B}m<x&&await new Promise(y=>setTimeout(y,0))}return r.putImageData(a,0,0),$.toDataURL("image/png")}const Lt="https://api.stability.ai/v1/generation",jt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",$e="stability_api_key";let se=null;function Et(e){se=e}function Rt(){return se}function Bt(){return se!==null}const Nt={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"},Ae=[{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 Ht(e,t){const n=e/t;let r=Ae[0],a=1/0;for(const s of Ae){const o=s.width/s.height,l=Math.abs(n-o);l<a&&(a=l,r=s)}return r}function Dt(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{const a=Ht(r.width,r.height),s=document.createElement("canvas");s.width=a.width,s.height=a.height;const o=s.getContext("2d");if(!o){n(new Error("Failed to get canvas context"));return}const l=r.width/r.height,u=a.width/a.height;let d=0,b=0,x=r.width,h=r.height;l>u?(x=r.height*u,d=(r.width-x)/2):(h=r.width/u,b=(r.height-h)/2),o.drawImage(r,d,b,x,h,0,0,a.width,a.height),t(s.toDataURL("image/png"))},r.onerror=()=>n(new Error("Failed to load image")),r.src=e})}function Fe(e){var o;const t=e.split(","),n=((o=t[0].match(/:(.*?);/))==null?void 0:o[1])||"image/png",r=atob(t[1]),a=r.length,s=new Uint8Array(a);for(let l=0;l<a;l++)s[l]=r.charCodeAt(l);return new Blob([s],{type:n})}function pe(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ie&&ie.tagName.toUpperCase()==="SCRIPT"&&ie.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($e):null}function Oe(e){localStorage.setItem($e,e)}function Ce(){return se?!0:pe()!==null}async function Mt(e){const t=pe();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,s=await Dt(n),o=Fe(s),l=new FormData;l.append("init_image",o,"portrait.png"),l.append("init_image_mode","IMAGE_STRENGTH"),l.append("image_strength",String(1-a)),l.append("text_prompts[0][text]",Nt[r]),l.append("text_prompts[0][weight]","1"),l.append("cfg_scale","7"),l.append("samples","1"),l.append("steps","30");const d=await fetch(`${Lt}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:l});if(!d.ok){const x=await d.text();throw console.error("Stability AI error:",x),d.status===401?new Error("Invalid API key"):d.status===402?new Error("Insufficient credits"):d.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${d.status}`)}const b=await d.json();if(!b.artifacts||b.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${b.artifacts[0].base64}`}async function qe(e){if(se){const o=await fetch(se,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!o.ok){const u=await o.json().catch(()=>({}));throw new Error(u.error||`API error: ${o.status}`)}return(await o.json()).imageDataUrl}const t=pe();if(!t)throw new Error("No Stability AI API key configured");const n=Fe(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 o=await a.text();throw console.error("Stability AI remove background error:",o),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 s=await a.blob();return new Promise((o,l)=>{const u=new FileReader;u.onload=()=>o(u.result),u.onerror=()=>l(new Error("Failed to read result")),u.readAsDataURL(s)})}function At(){const[e,t]=p.useState(!1),[n,r]=p.useState(!1),[a,s]=p.useState(null),[o,l]=p.useState(()=>Ce());p.useEffect(()=>{l(Ce())},[]);const u=p.useCallback(()=>s(null),[]),d=p.useCallback(h=>{Oe(h),l(!0),s(null)},[]),b=p.useCallback(async(h,m=.5,y=40)=>{t(!0),s(null);try{return await _e(h,m,y)}catch(k){const v=k instanceof Error?k.message:"Enhancement failed";throw s(v),k}finally{t(!1)}},[]),x=p.useCallback(async h=>{r(!0),s(null);try{return await qe(h)}catch(m){const y=m instanceof Error?m.message:"Background removal failed";throw s(y),m}finally{r(!1)}},[]);return{enhance:b,removeBg:x,isEnhancing:e,isRemovingBg:n,error:a,hasKey:o,setApiKey:d,clearError:u}}function Ke({isOpen:e,onClose:t,onSubmit:n}){const r=g(d=>d.appLanguage),[a,s]=p.useState("");if(!e)return null;const o=d=>{d.preventDefault(),a.trim()&&(n(a.trim()),s(""),t())},u={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 i.jsxs("dialog",{className:"modal modal-open",children:[i.jsxs("div",{className:"modal-box",children:[i.jsx("h3",{className:"font-bold text-lg",children:u.title}),i.jsx("p",{className:"py-4 text-sm opacity-80",children:u.description}),i.jsxs("form",{onSubmit:o,children:[i.jsxs("div",{className:"form-control",children:[i.jsx("input",{type:"password",placeholder:u.placeholder,className:"input input-bordered w-full",value:a,onChange:d=>s(d.target.value),autoFocus:!0}),i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text-alt",children:u.hint})})]}),i.jsxs("div",{className:"modal-action",children:[i.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:u.cancel}),i.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:u.submit})]})]})]}),i.jsx("form",{method:"dialog",className:"modal-backdrop",children:i.jsx("button",{onClick:t,children:"close"})})]})}function zt(){const e=g(c=>c.appLanguage),t=g(c=>c.portrait),n=g(c=>c.setPortrait),r=g(c=>c.setPortraitZoom),a=g(c=>c.setPortraitPan),s=g(c=>c.setPortraitRawImage),o=g(c=>c.setPortraitBgRemoved),l=g(c=>c.setPortraitBgOpacity),u=g(c=>c.setPortraitBgBlur),d=g(c=>c.setPortraitEngravingIntensity),{enhance:b,removeBg:x,isEnhancing:h,isRemovingBg:m,error:y,hasKey:k,setApiKey:v}=At(),R=G(e),S=p.useRef(null),L=p.useRef(null),[I,C]=p.useState(!1),[z,M]=p.useState(!1),[B,N]=p.useState(!1),j=p.useRef(null),D=p.useRef(null),H=p.useRef(null),E=t.rawImage,J=t.bgRemovedImage,U=t.bgRemoved,W=t.bgOpacity,F=t.bgBlur,Q=t.engravingIntensity;p.useEffect(()=>{t.original&&!t.rawImage&&s(t.original)},[t.original,t.rawImage,s]),p.useEffect(()=>()=>{D.current&&clearTimeout(D.current),H.current&&clearTimeout(H.current)},[]);const ee=g(c=>c.voucherConfig.templateHue),de=p.useRef(ee),le=p.useCallback(async c=>{if(!c.type.startsWith("image/"))return;const w=new FileReader;w.onload=async T=>{var Y;const P=(Y=T.target)==null?void 0:Y.result,X=await St(P);s(X),n(X),o(!1,null),d(0)},w.readAsDataURL(c)},[n,s,o,d]),f=p.useCallback(c=>{c.preventDefault(),C(!1);const w=c.dataTransfer.files[0];w&&le(w)},[le]),A=p.useCallback(c=>{c.preventDefault(),C(!0)},[]),O=p.useCallback(c=>{c.preventDefault(),C(!1)},[]),te=()=>{var c;(c=S.current)==null||c.click()},ce=c=>{var T;const w=(T=c.target.files)==null?void 0:T[0];w&&le(w)},q=p.useCallback(async(c,w,T)=>{try{return await b(c,w,T)}catch(P){return console.error("Enhancement failed:",P),c}},[b]),ne=p.useCallback(async c=>{try{const w=await x(c);return o(!0,w),w}catch(w){return console.error("Background removal failed:",w),c}},[x,o]),K=p.useCallback(async()=>{const c=g.getState(),w=c.portrait,T=c.voucherConfig.templateHue;if(!w.rawImage)return;let P;w.bgRemoved&&w.bgRemovedImage?P=await ve(w.bgRemovedImage,w.rawImage,w.bgOpacity,w.bgBlur):P=w.rawImage,w.engravingIntensity>0&&(P=await q(P,w.engravingIntensity,T)),n(P)},[q,n]);p.useEffect(()=>{if(de.current===ee)return;de.current=ee;const c=g.getState().portrait;c.engravingIntensity>0&&c.rawImage&&(D.current&&clearTimeout(D.current),D.current=setTimeout(K,150))},[ee,K]);const be=async()=>{if(!E)return;if(!U&&!k){M(!0);return}if(!U){const w=await ne(E),T=g.getState(),P=T.portrait,X=T.voucherConfig.templateHue;let Y=await ve(w,E,P.bgOpacity,P.bgBlur);P.engravingIntensity>0&&(Y=await q(Y,P.engravingIntensity,X)),n(Y)}else{o(!1,null);const w=g.getState(),T=w.portrait.engravingIntensity,P=w.voucherConfig.templateHue;if(T>0){const X=await q(E,T,P);n(X)}else n(E)}},xe=c=>{d(c),D.current&&clearTimeout(D.current),E&&(D.current=setTimeout(K,150))},we=async c=>{if(v(c),!E)return;const w=await ne(E),T=g.getState(),P=T.portrait,X=T.voucherConfig.templateHue;let Y=await ve(w,E,P.bgOpacity,P.bgBlur);P.engravingIntensity>0&&(Y=await q(Y,P.engravingIntensity,X)),n(Y)},ge=c=>{l(c),H.current&&clearTimeout(H.current),!(!E||!J)&&(H.current=setTimeout(K,150))},me=c=>{u(c),H.current&&clearTimeout(H.current),!(!E||!J)&&(H.current=setTimeout(K,150))},st=()=>{n(null),s(null),o(!1,null),l(0),u(0),d(0),Ct()},Ne=(c,w)=>{t.zoom<=1||(N(!0),j.current={x:c,y:w,panX:t.panX,panY:t.panY})},He=(c,w)=>{if(!B||!j.current||!L.current)return;const T=L.current.getBoundingClientRect(),P=2/Math.max(T.width,T.height),X=(c-j.current.x)*P,Y=(w-j.current.y)*P,pt=Math.max(-1,Math.min(1,j.current.panX+X)),ft=Math.max(-1,Math.min(1,j.current.panY+Y));a(pt,ft)},ye=()=>{N(!1),j.current=null},lt=c=>{c.preventDefault(),Ne(c.clientX,c.clientY)},ct=c=>{He(c.clientX,c.clientY)},ut=()=>{ye()},dt=()=>{ye()},gt=c=>{c.touches.length===1&&Ne(c.touches[0].clientX,c.touches[0].clientY)},mt=c=>{c.touches.length===1&&He(c.touches[0].clientX,c.touches[0].clientY)},ht=()=>{ye()};return i.jsxs("div",{className:"space-y-4",children:[t.original?i.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[i.jsxs("div",{className:"relative",children:[i.jsx("div",{ref:L,className:`w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg ${t.zoom>1?"cursor-grab":""} ${B?"cursor-grabbing":""}`,onMouseDown:lt,onMouseMove:ct,onMouseUp:ut,onMouseLeave:dt,onTouchStart:gt,onTouchMove:mt,onTouchEnd:ht,children:i.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})}),i.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:st,children:i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:R.form.portrait.zoom}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),i.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:c=>{const w=parseFloat(c.target.value);r(w),w<=1&&(t.panX!==0||t.panY!==0)&&a(0,0)},className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",h&&i.jsx("span",{className:"loading loading-spinner loading-xs"})]}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(Q*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:Q,onChange:c=>xe(parseFloat(c.target.value)),className:"range range-secondary range-sm",disabled:h||!E})]})]}),U?i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(W*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:W,onChange:c=>ge(parseFloat(c.target.value)),className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(F*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:F,onChange:c=>me(parseFloat(c.target.value)),className:"range range-primary range-sm"})]})]}):i.jsx("div",{className:"form-control",children:i.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[i.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${m?"opacity-50":""}`,checked:U,onChange:be,disabled:m||!E}),i.jsxs("span",{className:"label-text flex items-center gap-2",children:[m?i.jsxs(i.Fragment,{children:[i.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!k&&i.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),y&&i.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[i.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:i.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"})}),i.jsx("span",{children:y})]})]}):i.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${m?"border-primary bg-primary/10 pointer-events-none":I?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:f,onDragOver:A,onDragLeave:O,onClick:te,children:[i.jsx("input",{ref:S,type:"file",accept:"image/*",className:"hidden",onChange:ce}),m?i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),i.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.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:i.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"})}),i.jsx("p",{className:"font-medium",children:R.form.portrait.upload}),i.jsx("p",{className:"text-sm text-base-content/60",children:R.form.portrait.dragDrop})]})]}),i.jsx(Ke,{isOpen:z,onClose:()=>M(!1),onSubmit:we})]})}function Ut(){const e=g(d=>d.appLanguage),t=g(d=>d.voucherConfig.language),n=g(d=>d.voucherConfig.hours),r=g(d=>d.voucherConfig.templateHue),a=g(d=>d.setBillLanguage),s=g(d=>d.setHours),o=g(d=>d.setTemplateHue),l=G(e),u=[1,5,10];return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:l.form.voucher.billLanguage})}),i.jsxs("div",{className:"join",children:[i.jsx("button",{className:`join-item btn btn-sm ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:l.form.voucher.billLanguageGerman}),i.jsx("button",{className:`join-item btn btn-sm ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:l.form.voucher.billLanguageEnglish})]})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:l.form.voucher.hours})}),i.jsx("div",{className:"join",children:u.map(d=>i.jsxs("button",{className:`join-item btn btn-sm ${n===d?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>s(d),children:[d," ",d===1?l.form.voucher.hourLabel:l.form.voucher.hoursLabel]},d))})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:l.form.billColor.label})}),i.jsx("input",{type:"range",min:"0",max:"360",value:r,onChange:d=>o(Number(d.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%))`}})]})})}const _=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ie&&ie.tagName.toUpperCase()==="SCRIPT"&&ie.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",Re={en:{1:{front:`${_}templates/front_ldpi_en.png`,back:`${_}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${_}templates/front_ldpi_en.png`,back:`${_}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${_}templates/front_ldpi_en.png`,back:`${_}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${_}templates/front_hdpi_de.webp`,back:`${_}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${_}templates/front_hdpi_de.webp`,back:`${_}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${_}templates/front_hdpi_de.webp`,back:`${_}templates/back_hdpi_de.webp`,width:6144,height:3200}}},V={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"},signature:{x:768,y:920,width:300,height:60,lineY:950,labelFontSize:16}}},Z={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"},signature:{x:4600,y:2850,width:1200,height:240,lineY:2700,labelFontSize:64}}};function je(e){return e==="de"?Z:V}function Ke(e,t){return Re[e][t]}const Ce=.25;function Yt(e){const t=je(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 _t(e,t){const n=Re[e][t];return{...n,width:Math.round(n.width*Ce),height:Math.round(n.height*Ce)}}const ve=new Map,ae=new Map;async function oe(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 Ge(e,t,n,r){if(t>=155&&t<=165)return oe(e);const a=`${e}:${t}:${n}x${r}`;if(ae.has(a))return oe(ae.get(a));const i=await oe(e),s=document.createElement("canvas");s.width=n,s.height=r;const c=s.getContext("2d");if(!c)throw new Error("Failed to get canvas context");c.drawImage(i,0,0,n,r);const d=s.toDataURL("image/png"),u=await We(d,t);if(ae.size>20){const y=ae.keys().next().value;y&&ae.delete(y)}return ae.set(a,u),oe(u)}function Ve(e,t,n,r,a,i,s=1,c=0,d=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,y=a/i,x=a*2,g=i*2;let h,v;u>y?(v=g,h=g*u):(h=x,v=x/u),h*=s,v*=s;const m=Math.max(0,(h-x)/2),T=Math.max(0,(v-g)/2),H=n-h/2+c*m,k=r-v/2+d*T;e.drawImage(t,H,k,h,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 Ze(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(" "),c=[];let d="";for(const x of s){const g=d?`${d} ${x}`:x;e.measureText(g).width>a&&d?(c.push(d),d=x):d=g}d&&c.push(d);const u=c.length*i;let y=n.y-u/2;for(const x of c)e.fillText(x,n.x,y),y+=i;e.restore()}function Je(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,c=[t,n,r].filter(Boolean),d=(c.length-1)*s;let u=a.y-d/2;for(const y of c)y&&(e.fillText(y,a.x,u),u+=s);e.restore()}function Wt(e,t,n,r="#2a3a2a"){e.save(),e.strokeStyle=r,e.lineWidth=Math.max(2,t.labelFontSize/16),e.beginPath(),e.moveTo(t.x-t.width/2,t.lineY),e.lineTo(t.x+t.width/2,t.lineY),e.stroke(),e.font=`${t.labelFontSize}px "Times New Roman", serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=r,e.fillText(n,t.x,t.lineY+t.labelFontSize*.3),e.restore()}async function Qe(e,t,n,r,a,i,s,c=1,d=0,u=0,y=0){const x=e.getContext("2d");if(!x)return;const g=document.createElement("canvas");g.width=i,g.height=s;const h=g.getContext("2d");if(!h)return;h.clearRect(0,0,i,s);const v=await Ge(t,y,i,s);if(Ee(h,v,i,s),n)try{const m=await oe(n);Ve(h,m,a.portrait.x,a.portrait.y,a.portrait.radiusX,a.portrait.radiusY,c,d,u)}catch(m){console.error("Failed to load portrait:",m)}r&&Be(h,r,a.namePlate),e.width=i,e.height=s,x.drawImage(g,0,0)}async function et(e,t,n,r,a,i,s,c,d,u=0,y="de"){const x=e.getContext("2d");if(!x)return;const g=document.createElement("canvas");g.width=c,g.height=d;const h=g.getContext("2d");if(!h)return;h.clearRect(0,0,c,d);const v=await Ge(t,u,c,d);if(Ee(h,v,c,d),s.contactInfo&&(n||r||a)&&Je(h,n,r,a,s.contactInfo),s.description&&i&&Ze(h,i,s.description),n&&Be(h,n,s.namePlate),s.signature){const m=y==="de"?"Unterschrift":"Signature";Wt(h,s.signature,m)}e.width=c,e.height=d,x.drawImage(g,0,0)}function Xt(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),c=b(f=>f.flipSide),d=b(f=>f.setPortraitPan),u=Xt(r,150),y=K(e),x=p.useRef(null),g=p.useRef(null),h=p.useRef(null),[v,m]=p.useState(!1),[T,H]=p.useState(!1),k=p.useRef(null),I=_t(e,t),R=Yt(e),S=i.useEnhanced&&i.enhanced?i.enhanced:i.original,U=Se(e,t,n);p.useEffect(()=>{x.current&&Qe(x.current,I.front,S,a.name,R.front,I.width,I.height,i.zoom,i.panX,i.panY,u)},[I,S,a.name,R,i.zoom,i.panX,i.panY,u]),p.useEffect(()=>{g.current&&et(g.current,I.back,a.name,a.email,a.phone,U,R.back,I.width,I.height,u,e)},[I,a,U,R,u,e]);const N=()=>{m(!0),setTimeout(()=>{c(),m(!1)},150)},j=p.useCallback((f,A)=>{if(!h.current||s!=="front"||!i.original)return!1;const F=h.current.getBoundingClientRect(),te=F.width/I.width,le=F.height/I.height,ce=(f-F.left)/te,q=(A-F.top)/le,{x:ne,y:G,radiusX:be,radiusY:xe}=R.front.portrait,he=(ce-ne)/be,me=(q-G)/xe;return he*he+me*me<=1},[s,i.original,I.width,I.height,R.front.portrait]),D=p.useCallback((f,A)=>{i.zoom<=1||!j(f,A)||(H(!0),k.current={x:f,y:A,panX:i.panX,panY:i.panY})},[i.zoom,i.panX,i.panY,j]),E=p.useCallback((f,A)=>{if(!T||!k.current||!h.current)return;const F=h.current.getBoundingClientRect(),te=3/Math.max(F.width,F.height),le=(f-k.current.x)*te,ce=(A-k.current.y)*te,q=Math.max(-1,Math.min(1,k.current.panX+le)),ne=Math.max(-1,Math.min(1,k.current.panY+ce));d(q,ne)},[T,d]),L=p.useCallback(()=>{H(!1),k.current=null},[]),M=f=>{i.zoom>1&&j(f.clientX,f.clientY)&&(f.preventDefault(),D(f.clientX,f.clientY))},B=f=>{E(f.clientX,f.clientY)},J=()=>L(),z=()=>L(),W=f=>{if(f.touches.length===1){const A=f.touches[0];i.zoom>1&&j(A.clientX,A.clientY)&&D(A.clientX,A.clientY)}},O=f=>{f.touches.length===1&&E(f.touches[0].clientX,f.touches[0].clientY)},Q=()=>L(),ee=s==="front"&&i.original&&i.zoom>1,ue=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"&&N(),children:y.preview.front}),o.jsx("button",{className:`tab ${s==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="back"&&N(),children:y.preview.back})]}),o.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:N,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"})}),y.preview.flip]})]}),o.jsxs("div",{ref:h,className:`relative w-full overflow-hidden shadow-lg ${ee?T?"cursor-grabbing":"cursor-grab":""}`,style:{aspectRatio:ue},onMouseDown:M,onMouseMove:B,onMouseUp:J,onMouseLeave:z,onTouchStart:W,onTouchMove:O,onTouchEnd:Q,children:[o.jsx("canvas",{ref:x,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:g,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 Ot(){const e=p.useRef(null),t=p.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Ft=`
8
+ hsl(360, 70%, 50%))`}})]})]})}const _=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ie&&ie.tagName.toUpperCase()==="SCRIPT"&&ie.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",je={en:{1:{front:`${_}templates/front_ldpi_en.png`,back:`${_}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${_}templates/front_ldpi_en.png`,back:`${_}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${_}templates/front_ldpi_en.png`,back:`${_}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${_}templates/front_hdpi_de.webp`,back:`${_}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${_}templates/front_hdpi_de.webp`,back:`${_}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${_}templates/front_hdpi_de.webp`,back:`${_}templates/back_hdpi_de.webp`,width:6144,height:3200}}},V={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"},signature:{x:768,y:920,width:300,height:60,labelFontSize:16}}},Z={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:145,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1580,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1580,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"},signature:{x:3080,y:2450,width:1600,height:240,labelFontSize:145}}};function Ee(e){return e==="de"?Z:V}function Ge(e,t){return je[e][t]}const Se=.25;function Yt(e){const t=Ee(e),n=Se,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,signature:a.signature?{x:a.signature.x*n,y:a.signature.y*n,width:a.signature.width*n,height:a.signature.height*n,labelFontSize:a.signature.labelFontSize*n}:void 0});return{front:r(t.front),back:r(t.back)}}function _t(e,t){const n=je[e][t];return{...n,width:Math.round(n.width*Se),height:Math.round(n.height*Se)}}const ke=new Map,ae=new Map;async function oe(e){return ke.has(e)?ke.get(e):new Promise((t,n)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{ke.set(e,r),t(r)},r.onerror=n,r.src=e})}function Re(e,t,n,r){e.drawImage(t,0,0,n,r)}async function Ve(e,t,n,r){if(t>=155&&t<=165)return oe(e);const a=`${e}:${t}:${n}x${r}`;if(ae.has(a))return oe(ae.get(a));const s=await oe(e),o=document.createElement("canvas");o.width=n,o.height=r;const l=o.getContext("2d");if(!l)throw new Error("Failed to get canvas context");l.drawImage(s,0,0,n,r);const u=o.toDataURL("image/png"),d=await Xe(u,t);if(ae.size>20){const b=ae.keys().next().value;b&&ae.delete(b)}return ae.set(a,d),oe(d)}function Ze(e,t,n,r,a,s,o=1,l=0,u=0){e.save(),e.beginPath(),e.ellipse(n,r,a,s,0,0,Math.PI*2),e.closePath(),e.clip();const d=t.width/t.height,b=a/s,x=a*2,h=s*2;let m,y;d>b?(y=h,m=h*d):(m=x,y=x/d),m*=o,y*=o;const k=Math.max(0,(m-x)/2),v=Math.max(0,(y-h)/2),R=n-m/2+l*k,S=r-y/2+u*v;e.drawImage(t,R,S,m,y),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 Je(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,s=n.lineHeight||n.fontSize*1.4,o=t.split(" "),l=[];let u="";for(const x of o){const h=u?`${u} ${x}`:x;e.measureText(h).width>a&&u?(l.push(u),u=x):u=h}u&&l.push(u);const d=l.length*s;let b=n.y-d/2;for(const x of l)e.fillText(x,n.x,b),b+=s;e.restore()}function Qe(e,t,n,r,a,s="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=s;const o=a.lineHeight||a.fontSize*1.8,l=[t,n,r].filter(Boolean),u=(l.length-1)*o;let d=a.y-u/2;for(const b of l)b&&(e.fillText(b,a.x,d),d+=o);e.restore()}function Wt(e,t,n,r="#2a3a2a"){e.save(),e.strokeStyle=r,e.lineWidth=Math.max(2,t.labelFontSize/16),e.beginPath(),e.moveTo(t.x-t.width/2,t.y),e.lineTo(t.x+t.width/2,t.y),e.stroke(),e.font=`${t.labelFontSize}px "Times New Roman", serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=r,e.fillText(n,t.x,t.y+t.labelFontSize*.3),e.restore()}async function et(e,t,n,r,a,s,o,l=1,u=0,d=0,b=0){const x=e.getContext("2d");if(!x)return;const h=document.createElement("canvas");h.width=s,h.height=o;const m=h.getContext("2d");if(!m)return;m.clearRect(0,0,s,o);const y=await Ve(t,b,s,o);if(Re(m,y,s,o),n)try{const k=await oe(n);Ze(m,k,a.portrait.x,a.portrait.y,a.portrait.radiusX,a.portrait.radiusY,l,u,d)}catch(k){console.error("Failed to load portrait:",k)}r&&Be(m,r,a.namePlate),e.width=s,e.height=o,x.drawImage(h,0,0)}async function tt(e,t,n,r,a,s,o,l,u,d=0,b="de"){const x=e.getContext("2d");if(!x)return;const h=document.createElement("canvas");h.width=l,h.height=u;const m=h.getContext("2d");if(!m)return;m.clearRect(0,0,l,u);const y=await Ve(t,d,l,u);if(Re(m,y,l,u),o.contactInfo&&(n||r||a)&&Qe(m,n,r,a,o.contactInfo),o.description&&s&&Je(m,s,o.description),n&&Be(m,n,o.namePlate),o.signature){const k=b==="de"?"Unterschrift":"Signature";Wt(m,o.signature,k)}e.width=l,e.height=u,x.drawImage(h,0,0)}function Xt(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=g(f=>f.appLanguage),t=g(f=>f.voucherConfig.language),n=g(f=>f.voucherConfig.hours),r=g(f=>f.voucherConfig.description),a=g(f=>f.voucherConfig.templateHue),s=g(f=>f.personalInfo),o=g(f=>f.portrait),l=g(f=>f.currentSide),u=g(f=>f.flipSide),d=g(f=>f.setPortraitPan),b=Xt(a,150),x=G(e),h=p.useRef(null),m=p.useRef(null),y=p.useRef(null),[k,v]=p.useState(!1),[R,S]=p.useState(!1),L=p.useRef(null),I=_t(t,n),C=Yt(t),z=o.useEnhanced&&o.enhanced?o.enhanced:o.original,M=Te(t,n,r);p.useEffect(()=>{h.current&&et(h.current,I.front,z,s.name,C.front,I.width,I.height,o.zoom,o.panX,o.panY,b)},[I,z,s.name,C,o.zoom,o.panX,o.panY,b]),p.useEffect(()=>{m.current&&tt(m.current,I.back,s.name,s.email,s.phone,M,C.back,I.width,I.height,b,t)},[I,s,M,C,b,t]);const B=()=>{v(!0),setTimeout(()=>{u(),v(!1)},150)},N=p.useCallback((f,A)=>{if(!y.current||l!=="front"||!o.original)return!1;const O=y.current.getBoundingClientRect(),te=O.width/I.width,ce=O.height/I.height,q=(f-O.left)/te,ne=(A-O.top)/ce,{x:K,y:be,radiusX:xe,radiusY:we}=C.front.portrait,ge=(q-K)/xe,me=(ne-be)/we;return ge*ge+me*me<=1},[l,o.original,I.width,I.height,C.front.portrait]),j=p.useCallback((f,A)=>{o.zoom<=1||!N(f,A)||(S(!0),L.current={x:f,y:A,panX:o.panX,panY:o.panY})},[o.zoom,o.panX,o.panY,N]),D=p.useCallback((f,A)=>{if(!R||!L.current||!y.current)return;const O=y.current.getBoundingClientRect(),te=3/Math.max(O.width,O.height),ce=(f-L.current.x)*te,q=(A-L.current.y)*te,ne=Math.max(-1,Math.min(1,L.current.panX+ce)),K=Math.max(-1,Math.min(1,L.current.panY+q));d(ne,K)},[R,d]),H=p.useCallback(()=>{S(!1),L.current=null},[]),E=f=>{o.zoom>1&&N(f.clientX,f.clientY)&&(f.preventDefault(),j(f.clientX,f.clientY))},J=f=>{D(f.clientX,f.clientY)},U=()=>H(),W=()=>H(),F=f=>{if(f.touches.length===1){const A=f.touches[0];o.zoom>1&&N(A.clientX,A.clientY)&&j(A.clientX,A.clientY)}},Q=f=>{f.touches.length===1&&D(f.touches[0].clientX,f.touches[0].clientY)},ee=()=>H(),de=l==="front"&&o.original&&o.zoom>1,le=I.width/I.height;return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"flex justify-between items-center",children:[i.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[i.jsx("button",{className:`tab ${l==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="front"&&B(),children:x.preview.front}),i.jsx("button",{className:`tab ${l==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="back"&&B(),children:x.preview.back})]}),i.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:B,children:[i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.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"})}),x.preview.flip]})]}),i.jsxs("div",{ref:y,className:`relative w-full overflow-hidden shadow-lg ${de?R?"cursor-grabbing":"cursor-grab":""}`,style:{aspectRatio:le},onMouseDown:E,onMouseMove:J,onMouseUp:U,onMouseLeave:W,onTouchStart:F,onTouchMove:Q,onTouchEnd:ee,children:[i.jsx("canvas",{ref:h,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="front"?k?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),i.jsx("canvas",{ref:m,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="back"?k?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Ft(){const e=p.useRef(null),t=p.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Ot=`
9
9
  // RGB to HSL conversion
10
10
  function rgbToHsl(r, g, b) {
11
11
  r /= 255;
@@ -222,6 +222,7 @@ self.onmessage = async (e) => {
222
222
  email,
223
223
  phone,
224
224
  description,
225
+ language,
225
226
  } = e.data;
226
227
 
227
228
  try {
@@ -337,12 +338,12 @@ self.onmessage = async (e) => {
337
338
  const sig = layout.back.signature;
338
339
  const signatureLabel = language === 'de' ? 'Unterschrift' : 'Signature';
339
340
 
340
- // Draw signature line
341
+ // Draw signature line at (x, y)
341
342
  backCtx.strokeStyle = '#2a3a2a';
342
343
  backCtx.lineWidth = Math.max(2, sig.labelFontSize / 16);
343
344
  backCtx.beginPath();
344
- backCtx.moveTo(sig.x - sig.width / 2, sig.lineY);
345
- backCtx.lineTo(sig.x + sig.width / 2, sig.lineY);
345
+ backCtx.moveTo(sig.x - sig.width / 2, sig.y);
346
+ backCtx.lineTo(sig.x + sig.width / 2, sig.y);
346
347
  backCtx.stroke();
347
348
 
348
349
  // Draw label below line
@@ -350,7 +351,7 @@ self.onmessage = async (e) => {
350
351
  backCtx.textAlign = 'center';
351
352
  backCtx.textBaseline = 'top';
352
353
  backCtx.fillStyle = '#2a3a2a';
353
- backCtx.fillText(signatureLabel, sig.x, sig.lineY + sig.labelFontSize * 0.3);
354
+ backCtx.fillText(signatureLabel, sig.x, sig.y + sig.labelFontSize * 0.3);
354
355
  }
355
356
 
356
357
  // Convert canvases to blobs and then to ArrayBuffer for transfer
@@ -379,4 +380,4 @@ self.onmessage = async (e) => {
379
380
  });
380
381
  }
381
382
  };
382
- `;let ke=null,Ae=null;function qt(){if(!ke){const e=new Blob([Ft],{type:"application/javascript"});Ae=URL.createObjectURL(e),ke=new Worker(Ae,{type:"module"})}return ke}async function Ie(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 tt(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:r,templateHeight:a,layout:i,portrait:s,portraitZoom:c=1,portraitPanX:d=0,portraitPanY:u=0,templateHue:y=160,name:x,email:g,phone:h,description:v,language:m="de"}=e,[T,H]=await Promise.all([Ie(t),Ie(n)]);let k=null;return s&&(k=await Ie(s)),new Promise((I,R)=>{const S=qt(),U=j=>{if(S.removeEventListener("message",U),S.removeEventListener("error",N),URL.revokeObjectURL(T),URL.revokeObjectURL(H),k&&URL.revokeObjectURL(k),j.data.type==="success")try{const{frontImageData:D,backImageData:E,width:L,height:M}=j.data;if(!D||!E||!L||!M){R(new Error("Invalid response from worker"));return}const B=Ue(D,"image/jpeg"),J=Ue(E,"image/jpeg"),z=L/96*25.4,W=M/96*25.4,O=new wt.jsPDF({orientation:z>W?"landscape":"portrait",unit:"mm",format:[z,W]});O.addImage(B,"JPEG",0,0,z,W),O.addPage([z,W]),O.addImage(J,"JPEG",0,0,z,W);const Q=O.output("blob");I(Q)}catch(D){R(D)}else R(new Error(j.data.error))},N=j=>{S.removeEventListener("message",U),S.removeEventListener("error",N),URL.revokeObjectURL(T),URL.revokeObjectURL(H),k&&URL.revokeObjectURL(k),R(new Error(j.message))};S.addEventListener("message",U),S.addEventListener("error",N),S.postMessage({type:"generate",frontTemplateUrl:T,backTemplateUrl:H,portraitUrl:k,templateWidth:r,templateHeight:a,templateHue:y,portraitZoom:c,portraitPanX:d,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,signature:i.back.signature}},name:x,email:g,phone:h,description:v,language:m})})}function nt(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 at(e){const t=await tt(e);nt(t,e.filename)}function Kt(){const e=b(m=>m.voucherConfig.language),t=b(m=>m.voucherConfig.hours),n=b(m=>m.voucherConfig.description),r=b(m=>m.voucherConfig.templateHue),a=b(m=>m.personalInfo),i=b(m=>m.portrait),s=b(m=>m.isExporting),c=b(m=>m.setIsExporting),d=K(e),u=Ke(e,t),y=je(e),x=i.useEnhanced&&i.enhanced?i.enhanced:i.original,g=Se(e,t,n),h=a.name.trim().length>0&&a.email.trim().length>0&&a.phone.trim().length>0&&i.original!==null,v=async()=>{if(!(!h||s)){c(!0);try{const m=`zeitgutschein-${t}h-${a.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await at({frontTemplateSrc:u.front,backTemplateSrc:u.back,templateWidth:u.width,templateHeight:u.height,layout:y,portrait:x,portraitZoom:i.zoom,portraitPanX:i.panX,portraitPanY:i.panY,templateHue:r,name:a.name,email:a.email,phone:a.phone,description:g,filename:m,language:e})}catch(m){console.error("PDF export failed:",m)}finally{c(!1)}}};return o.jsxs("button",{className:`btn btn-primary flex-1 ${h?"":"btn-disabled"}`,onClick:v,disabled:!h,"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"})}),d.export.button]})}function rt(){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 Gt(){const e=b(n=>n.voucherConfig.language),t=K(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(rt,{})})]})}const ge="/",Vt={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${ge}templates/front_hdpi_de.jpg`,back:`${ge}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:Z.front.portrait,name:Z.front.namePlate},back:{name:Z.back.namePlate,contactInfo:Z.back.contactInfo,description:Z.back.description}},languages:["de"]},Zt={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${ge}templates/front_ldpi_en.png`,back:`${ge}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:V.front.portrait,name:V.front.namePlate},back:{name:V.back.namePlate,contactInfo:V.back.contactInfo,description:V.back.description}},languages:["en"]},ze=[Vt,Zt],ot={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 Jt(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let fe=ot;function Qt(e){fe=e}function en(){return fe}async function tn(e){return fe.listTemplates(e)}async function nn(e){return fe.getTemplate(e)}exports.ApiKeyModal=qe;exports.BillPreview=$t;exports.ExportButton=Kt;exports.Header=Gt;exports.LAYOUT_HDPI=Z;exports.LAYOUT_LDPI=V;exports.LanguageToggle=rt;exports.PersonalInfoForm=It;exports.PortraitUpload=Ut;exports.TEMPLATES=Re;exports.VoucherConfig=zt;exports.applyEngravingEffect=Ye;exports.applyHueShift=We;exports.downloadBlob=nt;exports.drawContactInfo=Je;exports.drawMultilineText=Ze;exports.drawOvalPortrait=Ve;exports.drawTemplate=Ee;exports.drawText=Be;exports.enhancePortrait=Mt;exports.exportBillAsPDF=at;exports.formatDescription=Se;exports.generateBillPDF=tt;exports.getApiKey=pe;exports.getDefaultTemplateId=Jt;exports.getLayout=je;exports.getRemoveBackgroundEndpoint=Bt;exports.getTemplate=Ke;exports.getTemplateById=nn;exports.getTemplateProvider=en;exports.hasApiKey=Pe;exports.hasCustomEndpoint=Ht;exports.listTemplates=tn;exports.loadImage=oe;exports.removeBackground=Fe;exports.renderBackSide=et;exports.renderFrontSide=Qe;exports.setApiKey=Oe;exports.setRemoveBackgroundEndpoint=Et;exports.setTemplateProvider=Qt;exports.staticTemplateProvider=ot;exports.t=K;exports.useBillCanvasRefs=Ot;exports.useBillStore=b;
383
+ `;let Ie=null,ze=null;function qt(){if(!Ie){const e=new Blob([Ot],{type:"application/javascript"});ze=URL.createObjectURL(e),Ie=new Worker(ze,{type:"module"})}return Ie}async function Pe(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 nt(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:r,templateHeight:a,layout:s,portrait:o,portraitZoom:l=1,portraitPanX:u=0,portraitPanY:d=0,templateHue:b=160,name:x,email:h,phone:m,description:y,language:k="de"}=e,[v,R]=await Promise.all([Pe(t),Pe(n)]);let S=null;return o&&(S=await Pe(o)),new Promise((L,I)=>{const C=qt(),z=B=>{if(C.removeEventListener("message",z),C.removeEventListener("error",M),URL.revokeObjectURL(v),URL.revokeObjectURL(R),S&&URL.revokeObjectURL(S),B.data.type==="success")try{const{frontImageData:N,backImageData:j,width:D,height:H}=B.data;if(!N||!j||!D||!H){I(new Error("Invalid response from worker"));return}const E=Ue(N,"image/jpeg"),J=Ue(j,"image/jpeg"),U=D/96*25.4,W=H/96*25.4,F=new wt.jsPDF({orientation:U>W?"landscape":"portrait",unit:"mm",format:[U,W]});F.addImage(E,"JPEG",0,0,U,W),F.addPage([U,W]),F.addImage(J,"JPEG",0,0,U,W);const Q=F.output("blob");L(Q)}catch(N){I(N)}else I(new Error(B.data.error))},M=B=>{C.removeEventListener("message",z),C.removeEventListener("error",M),URL.revokeObjectURL(v),URL.revokeObjectURL(R),S&&URL.revokeObjectURL(S),I(new Error(B.message))};C.addEventListener("message",z),C.addEventListener("error",M),C.postMessage({type:"generate",frontTemplateUrl:v,backTemplateUrl:R,portraitUrl:S,templateWidth:r,templateHeight:a,templateHue:b,portraitZoom:l,portraitPanX:u,portraitPanY:d,layout:{front:{portrait:s.front.portrait,namePlate:s.front.namePlate},back:{namePlate:s.back.namePlate,contactInfo:s.back.contactInfo,description:s.back.description,signature:s.back.signature}},name:x,email:h,phone:m,description:y,language:k})})}function at(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 rt(e){const t=await nt(e);at(t,e.filename)}function Kt(){const e=g(v=>v.appLanguage),t=g(v=>v.voucherConfig.language),n=g(v=>v.voucherConfig.hours),r=g(v=>v.voucherConfig.description),a=g(v=>v.voucherConfig.templateHue),s=g(v=>v.personalInfo),o=g(v=>v.portrait),l=g(v=>v.isExporting),u=g(v=>v.setIsExporting),d=G(e),b=Ge(t,n),x=Ee(t),h=o.useEnhanced&&o.enhanced?o.enhanced:o.original,m=Te(t,n,r),y=s.name.trim().length>0&&s.email.trim().length>0&&s.phone.trim().length>0&&o.original!==null,k=async()=>{if(!(!y||l)){u(!0);try{const v=`zeitgutschein-${n}h-${s.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await rt({frontTemplateSrc:b.front,backTemplateSrc:b.back,templateWidth:b.width,templateHeight:b.height,layout:x,portrait:h,portraitZoom:o.zoom,portraitPanX:o.panX,portraitPanY:o.panY,templateHue:a,name:s.name,email:s.email,phone:s.phone,description:m,filename:v,language:t})}catch(v){console.error("PDF export failed:",v)}finally{u(!1)}}};return i.jsxs("button",{className:`btn btn-primary flex-1 ${y?"":"btn-disabled"}`,onClick:k,disabled:!y,"aria-busy":l,children:[l?i.jsx("span",{className:"loading loading-spinner loading-sm"}):i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.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"})}),d.export.button]})}function ot(){const e=g(r=>r.appLanguage),t=g(r=>r.setAppLanguage),n=r=>{t(r)};return i.jsxs("div",{className:"join",children:[i.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),i.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Gt(){const e=g(n=>n.appLanguage),t=G(e);return i.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[i.jsx("div",{className:"navbar-start",children:i.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),i.jsx("div",{className:"navbar-center hidden sm:flex",children:i.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),i.jsx("div",{className:"navbar-end",children:i.jsx(ot,{})})]})}const he="/",Vt={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:Z.front.portrait,name:Z.front.namePlate},back:{name:Z.back.namePlate,contactInfo:Z.back.contactInfo,description:Z.back.description}},languages:["de"]},Zt={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:V.front.portrait,name:V.front.namePlate},back:{name:V.back.namePlate,contactInfo:V.back.contactInfo,description:V.back.description}},languages:["en"]},Ye=[Vt,Zt],it={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 Jt(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let fe=it;function Qt(e){fe=e}function en(){return fe}async function tn(e){return fe.listTemplates(e)}async function nn(e){return fe.getTemplate(e)}exports.ApiKeyModal=Ke;exports.BillPreview=$t;exports.ExportButton=Kt;exports.Header=Gt;exports.LAYOUT_HDPI=Z;exports.LAYOUT_LDPI=V;exports.LanguageToggle=ot;exports.PersonalInfoForm=It;exports.PortraitUpload=zt;exports.TEMPLATES=je;exports.VoucherConfig=Ut;exports.applyEngravingEffect=_e;exports.applyHueShift=Xe;exports.downloadBlob=at;exports.drawContactInfo=Qe;exports.drawMultilineText=Je;exports.drawOvalPortrait=Ze;exports.drawTemplate=Re;exports.drawText=Be;exports.enhancePortrait=Mt;exports.exportBillAsPDF=rt;exports.formatDescription=Te;exports.generateBillPDF=nt;exports.getApiKey=pe;exports.getDefaultTemplateId=Jt;exports.getLayout=Ee;exports.getRemoveBackgroundEndpoint=Rt;exports.getTemplate=Ge;exports.getTemplateById=nn;exports.getTemplateProvider=en;exports.hasApiKey=Ce;exports.hasCustomEndpoint=Bt;exports.listTemplates=tn;exports.loadImage=oe;exports.removeBackground=qe;exports.renderBackSide=tt;exports.renderFrontSide=et;exports.setApiKey=Oe;exports.setRemoveBackgroundEndpoint=Et;exports.setTemplateProvider=Qt;exports.staticTemplateProvider=it;exports.t=G;exports.useBillCanvasRefs=Ft;exports.useBillStore=g;
package/dist/index.d.ts CHANGED
@@ -48,7 +48,8 @@ declare interface BillActions {
48
48
  flipSide: () => void;
49
49
  setIsEnhancing: (value: boolean) => void;
50
50
  setIsExporting: (value: boolean) => void;
51
- setLanguage: (language: Language) => void;
51
+ setAppLanguage: (language: Language) => void;
52
+ setBillLanguage: (language: Language) => void;
52
53
  setHours: (hours: HourValue) => void;
53
54
  setTemplateHue: (hue: number) => void;
54
55
  reset: () => void;
@@ -65,6 +66,7 @@ export declare interface BillState {
65
66
  currentSide: BillSide;
66
67
  isEnhancing: boolean;
67
68
  isExporting: boolean;
69
+ appLanguage: Language;
68
70
  }
69
71
 
70
72
  export declare interface CanvasPosition {
@@ -262,7 +264,6 @@ export declare function setTemplateProvider(provider: TemplateProvider): void;
262
264
  export declare interface SignatureConfig extends CanvasPosition {
263
265
  width: number;
264
266
  height: number;
265
- lineY: number;
266
267
  labelFontSize: number;
267
268
  }
268
269
 
@@ -395,6 +396,9 @@ declare interface Translations {
395
396
  hoursLabel: string;
396
397
  description: string;
397
398
  descriptionPlaceholder: string;
399
+ billLanguage: string;
400
+ billLanguageGerman: string;
401
+ billLanguageEnglish: string;
398
402
  };
399
403
  billColor: {
400
404
  title: string;
@@ -428,6 +432,7 @@ persist: {
428
432
  setOptions: (options: Partial<PersistOptions<BillState & BillActions, {
429
433
  personalInfo: PersonalInfo;
430
434
  voucherConfig: VoucherConfigType;
435
+ appLanguage: Language;
431
436
  portrait: {
432
437
  original: null;
433
438
  enhanced: null;
@@ -451,6 +456,7 @@ onFinishHydration: (fn: (state: BillState & BillActions) => void) => () => void;
451
456
  getOptions: () => Partial<PersistOptions<BillState & BillActions, {
452
457
  personalInfo: PersonalInfo;
453
458
  voucherConfig: VoucherConfigType;
459
+ appLanguage: Language;
454
460
  portrait: {
455
461
  original: null;
456
462
  enhanced: null;