@antontranelis/money-printer 1.0.86 → 1.0.87
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 +4 -4
- package/dist/index.js +715 -706
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),g=require("react"),nn=require("zustand"),an=require("zustand/middleware"),rn=require("jspdf");var ge=typeof document<"u"?document.currentScript:null;const on=1024,ct=1200,le=new Map;let F=null,lt=null;function Qe(e,t){return F||(F=document.createElement("canvas"),lt=F.getContext("2d",{willReadFrequently:!0})),(F.width!==e||F.height!==t)&&(F.width=e,F.height=t),lt}function pe(e){const t=le.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(le.size>10){const l=le.keys().next().value;l&&le.delete(l)}le.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function pt(){le.clear()}async function ft(e,t=on){const n=await pe(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,l=Math.round(n.width*r),i=Math.round(n.height*r),s=document.createElement("canvas"),o=s.getContext("2d");if(!o)throw new Error("Failed to get canvas context");return s.width=l,s.height=i,o.drawImage(n,0,0,l,i),s.toDataURL("image/jpeg",.9)}async function bt(e){const t=await pe(e),n=Math.max(t.width,t.height);if(n<=ct){const o=document.createElement("canvas"),u=o.getContext("2d");if(!u)throw new Error("Failed to get canvas context");return o.width=t.width,o.height=t.height,u.drawImage(t,0,0),o.toDataURL("image/png")}const a=ct/n,r=Math.round(t.width*a),l=Math.round(t.height*a),i=document.createElement("canvas"),s=i.getContext("2d");if(!s)throw new Error("Failed to get canvas context");return i.width=r,i.height=l,s.drawImage(t,0,0,r,l),i.toDataURL("image/png")}async function ze(e,t,n,a=0){const[r,l]=await Promise.all([pe(e),pe(t)]),i=Qe(r.width,r.height);if(i.clearRect(0,0,r.width,r.height),n>0){const s=a*20;i.save(),i.globalAlpha=n,s>0&&(i.filter=`blur(${s}px)`),i.drawImage(l,0,0,r.width,r.height),i.restore()}return i.drawImage(r,0,0),F.toDataURL("image/png")}async function xt(e,t=.5,n=40){const a=await pe(e),r=Qe(a.width,a.height);r.clearRect(0,0,a.width,a.height),r.drawImage(a,0,0);const l=r.getImageData(0,0,a.width,a.height),i=l.data,s=new Uint32Array(i.buffer),o=1+t*.8,u=1-t,h=n%360/360;for(let f=0;f<s.length;f++){const p=s[f],m=p&255,y=p>>8&255,k=p>>16&255,d=p>>24&255;if(d===0)continue;let E=(((77*m+150*y+29*k>>8)/255-.5)*o+.5)*255;E<0?E=0:E>255&&(E=255);const v=E/255,S=.12,[L,P,D]=wt(h,S,v),j=m*u+L*t|0,R=y*u+P*t|0,C=k*u+D*t|0;s[f]=d<<24|C<<16|R<<8|j}return r.putImageData(l,0,0),F.toDataURL("image/png")}function sn(e,t,n){e/=255,t/=255,n/=255;const a=Math.max(e,t,n),r=Math.min(e,t,n),l=(a+r)/2;let i=0,s=0;if(a!==r){const o=a-r;switch(s=l>.5?o/(2-a-r):o/(a+r),a){case e:i=((t-n)/o+(t<n?6:0))/6;break;case t:i=((n-e)/o+2)/6;break;case n:i=((e-t)/o+4)/6;break}}return[i,s,l]}function wt(e,t,n){if(t===0){const i=Math.round(n*255);return[i,i,i]}const a=(i,s,o)=>(o<0&&(o+=1),o>1&&(o-=1),o<1/6?i+(s-i)*6*o:o<1/2?s:o<2/3?i+(s-i)*(2/3-o)*6:i),r=n<.5?n*(1+t):n+t-n*t,l=2*n-r;return[Math.round(a(l,r,e+1/3)*255),Math.round(a(l,r,e)*255),Math.round(a(l,r,e-1/3)*255)]}const cn=29,ln=5;async function yt(e,t){if(Math.abs(t-cn)<=ln)return e;const n=await pe(e),a=Qe(n.width,n.height);a.clearRect(0,0,n.width,n.height),a.drawImage(n,0,0);const r=a.getImageData(0,0,n.width,n.height),l=r.data,i=new Uint32Array(l.buffer),s=t%360/360,o=20/360,u=45/360,h=i.length;for(let f=0;f<h;f++){const p=i[f],m=p&255,y=p>>8&255,k=p>>16&255,d=p>>24&255;if(d===0)continue;const[I,E,v]=sn(m,y,k);if(E<.08||I<o||I>u)continue;const S=s,L=Math.min(E,.05),[P,D,j]=wt(S,L,v);i[f]=d<<24|j<<16|D<<8|P}return a.putImageData(r,0,0),F.toDataURL("image/png")}const me=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",X={background:`${me}templates/background.webp`,frontFrame:`${me}templates/front_frame.webp`,backFrame:`${me}templates/back_frame.webp`},he={1:`${me}templates/1.png`,5:`${me}templates/5.png`,10:`${me}templates/10.png`},vt={de:{banner:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"}},en:{banner:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}}},ne=3633,ae=1920,Ne=.5,un=Math.round(ne*Ne),dn=Math.round(ae*Ne),kt=320,It=335,$={badges:{topLeft:{x:286,y:235},topRight:{x:3340,y:230},bottomLeft:{x:282,y:1665},bottomRight:{x:3345,y:1665}},banner:{centerX:1816,centerY:3820,radius:3610,fontSize:103,color:"#2a3a2a"}},Ee=new Map,ie=new Map,Ve=new Map,Ke=new Map,Fe=new Map;function Tt(e,t,n,a,r,l,i){e.save(),e.font=`900 ${l}px "Times New Roman", Georgia, serif`,e.fillStyle=i,e.textAlign="center",e.textBaseline="middle";const o=e.measureText(t).width/r,u=-Math.PI/2-o/2,h=t.split(""),f=[];for(const m of h)f.push(e.measureText(m).width);let p=u;for(let m=0;m<h.length;m++){const y=h[m],k=f[m],d=p+k/2/r,I=n+r*Math.cos(d),E=a+r*Math.sin(d);e.save(),e.translate(I,E),e.rotate(d+Math.PI/2),e.fillText(y,0,0),e.restore(),p+=k/r}e.restore()}let W={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function gn(){const[e,t,n,a,r,l]=await Promise.all([B(X.background),B(X.frontFrame),B(X.backFrame),B(he[1]),B(he[5]),B(he[10])]);W={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:l}}}function mn(e,t){const n=Math.round(ne*e),a=Math.round(ae*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");l.drawImage(t,0,0,n,a);const i=e<1?.8:.95;return r.toDataURL("image/jpeg",i)}function hn(e,t){const n=Math.round(ne*e),a=Math.round(ae*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");const i=kt*e,s=It*e,o=$.badges,u=(h,f)=>{const p=f/2,m=h.x*e-p,y=h.y*e-p;l.drawImage(t,m,y,f,f)};return u(o.topLeft,i),u(o.topRight,i),u(o.bottomLeft,s),u(o.bottomRight,s),r.toDataURL("image/png")}function Et(e,t,n,a=1){const r=vt[n].banner[t];Tt(e,r,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}function St(e,t,n,a,r,l,i){const s=Math.round(ne*a),o=Math.round(ae*a),u=document.createElement("canvas");u.width=s,u.height=o;const h=u.getContext("2d");if(!h)throw new Error("Failed to get canvas context");h.drawImage(r,0,0,s,o);{const p=kt*a,m=It*a,y=$.badges,k=(d,I)=>{const E=I/2,v=d.x*a-E,S=d.y*a-E;h.drawImage(i,v,S,I,I)};k(y.topLeft,p),k(y.topRight,p),k(y.bottomLeft,m),k(y.bottomRight,m)}if(h.drawImage(l,0,0,s,o),n==="front"){const p=vt[t].banner[e];Tt(h,p,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}const f=a<1?.8:.95;return u.toDataURL("image/jpeg",f)}async function Pt(e,t,n){const a=`${e}-${t}-${n}`;if(Ee.has(a))return Ee.get(a);const r=W.background||await B(X.background),l=n==="front"?W.frontFrame||await B(X.frontFrame):W.backFrame||await B(X.backFrame),i=W.badges[e]||await B(he[e]),s=St(e,t,n,Ne,r,l,i);return Ee.set(a,s),s}async function qe(e,t,n){const a=`${e}-${t}-${n}`;if(ie.has(a))return ie.get(a);const r=W.background||await B(X.background),l=n==="front"?W.frontFrame||await B(X.frontFrame):W.backFrame||await B(X.backFrame),i=W.badges[e]||await B(he[e]),s=St(e,t,n,1,r,l,i);if(ie.size>4){const o=ie.keys().next().value;o&&ie.delete(o)}return ie.set(a,s),s}function pn(){return{width:ne,height:ae}}function Lt(){Ee.clear(),ie.clear(),Ve.clear(),Ke.clear(),Fe.clear()}async function Ze(e,t,n="front",a=Ne){const r=`bg-${a}`;let l=Ve.get(r);if(!l){const h=W.background||await B(X.background);l=mn(a,h),Ve.set(r,l)}const i=`badges-${e}-${a}`;let s=Ke.get(i);if(!s){const h=W.badges[e]||await B(he[e]);s=hn(a,h),Ke.set(i,s)}const o=`${n}-${a}`;let u=Fe.get(o);if(!u){const h=n==="front"?W.frontFrame||await B(X.frontFrame):W.backFrame||await B(X.backFrame),f=Math.round(ne*a),p=Math.round(ae*a),m=document.createElement("canvas");m.width=f,m.height=p;const y=m.getContext("2d");if(!y)throw new Error("Failed to get canvas context");y.drawImage(h,0,0,f,p),u=m.toDataURL("image/png"),Fe.set(o,u)}return{background:l,badges:s,frame:u}}async function fn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const l of t)for(const i of n)a.push(Pt(r,l,i));await Promise.all(a)}const Se=new Map,se=new Map;function Rt(){se.clear(),Se.clear(),pt()}async function B(e){return Se.has(e)?Se.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{Se.set(e,a),t(a)},a.onerror=n,a.src=e})}function ce(e,t,n,a){e.drawImage(t,0,0,n,a)}const bn=29,xn=5;async function Ct(e,t,n,a){if(Math.abs(t-bn)<=xn)return B(e);const r=`${e}:${t}:${n}x${a}`;if(se.has(r))return B(se.get(r));const l=await B(e),i=document.createElement("canvas");i.width=n,i.height=a;const s=i.getContext("2d");if(!s)throw new Error("Failed to get canvas context");s.drawImage(l,0,0,n,a);const o=i.toDataURL("image/png"),u=await yt(o,t);if(se.size>20){const h=se.keys().next().value;h&&se.delete(h)}return se.set(r,u),B(u)}function wn(e,t,n,a,r,l="de"){e.save(),e.beginPath(),e.ellipse(t,n,a,r,0,0,Math.PI*2),e.closePath(),e.setLineDash([20,10]),e.strokeStyle="rgba(100, 100, 100, 0.4)",e.lineWidth=3,e.stroke(),e.restore()}function Bt(e,t,n,a,r,l,i=1,s=0,o=0){e.save(),e.beginPath(),e.ellipse(n,a,r,l,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,h=r/l,f=r*2,p=l*2;let m,y;u>h?(y=p,m=p*u):(m=f,y=f/u),m*=i,y*=i;const k=Math.max(0,(m-f)/2),d=Math.max(0,(y-p)/2),I=n-m/2+s*k,E=a-y/2+o*d;e.drawImage(t,I,E,m,y),e.restore()}function et(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=a,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function Nt(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=a;const r=n.maxWidth||400,l=n.lineHeight||n.fontSize*1.4,i=t.split(" "),s=[];let o="";for(const f of i){const p=o?`${o} ${f}`:f;e.measureText(p).width>r&&o?(s.push(o),o=f):o=p}o&&s.push(o);const u=s.length*l;let h=n.y-u/2;for(const f of s)e.fillText(f,n.x,h),h+=l;e.restore()}function jt(e,t,n,a,r,l="#2a3a2a"){e.save(),e.font=`${r.fontSize}px "Times New Roman", serif`,e.textAlign=r.align||"center",e.textBaseline="middle",e.fillStyle=l;const i=r.lineHeight||r.fontSize*1.8,s=[t,n,a].filter(Boolean),o=(s.length-1)*i;let u=r.y-o/2;for(const h of s)h&&(e.fillText(h,r.x,u),u+=i);e.restore()}function yn(e,t,n,a="#2a3a2a"){e.save(),e.strokeStyle=a,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=a,e.fillText(n,t.x,t.y+t.labelFontSize*.3),e.restore()}async function At(e,t,n,a,r,l,i,s,o,u=1,h=0,f=0,p=0,m=1,y="de"){const k=e.getContext("2d");if(!k)return;const d=document.createElement("canvas");d.width=s,d.height=o;const I=d.getContext("2d");if(!I)return;I.clearRect(0,0,s,o);const E=await Ct(t,p,s,o);ce(I,E,s,o);const v=await B(n);if(ce(I,v,s,o),r)try{const P=await B(r);Bt(I,P,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,u,h,f)}catch(P){console.error("Failed to load portrait:",P)}else wn(I,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,y);const S=await B(a);ce(I,S,s,o);const L=s/3633;Et(I,m,y,L),l&&et(I,l,i.namePlate),e.width=s,e.height=o,k.drawImage(d,0,0)}async function Dt(e,t,n,a,r,l,i,s,o,u,h,f=0,p=1,m="de"){const y=e.getContext("2d");if(!y)return;const k=document.createElement("canvas");k.width=u,k.height=h;const d=k.getContext("2d");if(!d)return;d.clearRect(0,0,u,h);const I=await Ct(t,f,u,h);ce(d,I,u,h);const E=await B(n);ce(d,E,u,h);const v=await B(a);ce(d,v,u,h);const S=u/3633;if(Et(d,p,m,S),o.contactInfo&&(r||l||i)&&jt(d,r,l,i,o.contactInfo),o.description&&s&&Nt(d,s,o.description),r&&et(d,r,o.namePlate),o.signature){const L=m==="de"?"Unterschrift":"Signature";yn(d,o.signature,L)}e.width=u,e.height=h,y.drawImage(k,0,0)}const Le="money-generator-portrait",Re="money-generator-bg-removed";async function vn(e){try{if(localStorage.removeItem(Le),!e)return;const t=await bt(e);try{localStorage.setItem(Le,t)}catch(n){console.warn("Could not persist portrait to localStorage:",n)}}catch(t){console.warn("Error processing portrait for storage:",t)}}async function kn(e){try{if(localStorage.removeItem(Re),!e)return;const t=await bt(e);try{localStorage.setItem(Re,t)}catch(n){console.warn("Could not persist bg-removed image to localStorage:",n)}}catch(t){console.warn("Error processing bg-removed image for storage:",t)}}function In(){try{return localStorage.getItem(Le)}catch{return null}}function Tn(){try{return localStorage.getItem(Re)}catch{return null}}function En(){try{localStorage.removeItem(Le),localStorage.removeItem(Re)}catch{}}function Sn(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Ce=Sn(),ut={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Ce,templateHue:29},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:Ce},w=nn.create()(an.persist(e=>({...ut,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>(vn(t),e(a=>({portrait:{...a.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:a.portrait.original&&t?a.portrait.zoom:1,panX:a.portrait.original&&t?a.portrait.panX:0,panY:a.portrait.original&&t?a.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(a=>({portrait:{...a.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>(n!==void 0&&kn(n),e(a=>({portrait:{...a.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:a.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=>(Rt(),Lt(),e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}}))),reset:()=>(En(),e(ut))}),{name:"money-generator-storage",migrate:e=>{const t=e;return t!=null&&t.voucherConfig&&(t.voucherConfig.templateHue===void 0&&(t.voucherConfig.templateHue=29),t.voucherConfig.hours=1,t.voucherConfig.language=Ce),t&&(t.appLanguage=Ce),t},version:2,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:e.portrait.bgRemoved,bgOpacity:e.portrait.bgOpacity,bgBlur:e.portrait.bgBlur,engravingIntensity:e.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));if(typeof window<"u"){const e=In(),t=Tn();e&&setTimeout(()=>{const n=w.getState();if(!n.portrait.original){const a=n.portrait.bgRemoved,r=t!==null;w.setState({portrait:{...n.portrait,original:e,rawImage:e,bgRemovedImage:t,bgRemoved:a&&r,bgOpacity:a&&r?n.portrait.bgOpacity:0,bgBlur:a&&r?n.portrait.bgBlur:0}})}},0)}const Pn={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 {bannerText} meiner Zeit oder ein gleichwertiges Dankeschön.",bannerText:{1:"eine Stunde",5:"fünf Stunden",10:"zehn Stunden"}}},Ln={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:"For this voucher, you will receive {bannerText} of my time or an equivalent appreciation in return.",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},Rn={de:Pn,en:Ln};function re(e){return Rn[e]}function tt(e,t,n){if(n&&n.trim())return n;const a=re(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function Cn(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function Bn(e){return e.replace(/\D/g,"").length>=6}function Nn({focusField:e,onFocused:t,onFormFocusChange:n}={}){const a=w(d=>d.appLanguage),r=w(d=>d.personalInfo),l=w(d=>d.setPersonalInfo),i=re(a),[s,o]=g.useState(!1),[u,h]=g.useState(!1),f=s&&r.email.trim()&&!Cn(r.email),p=u&&r.phone.trim()&&!Bn(r.phone),m=g.useRef(null),y=g.useRef(null),k=g.useRef(null);return g.useEffect(()=>{if(e){const d=e==="name"?m:e==="email"?y:k;setTimeout(()=>{var I,E;(I=d.current)==null||I.click(),(E=d.current)==null||E.focus(),setTimeout(()=>{var v;(v=d.current)==null||v.scrollIntoView({behavior:"smooth",block:"center"})},300),t==null||t()},100)}},[e,t]),c.jsxs("div",{className:"space-y-4",children:[c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.name})}),c.jsx("input",{ref:m,type:"text",name:"name",autoComplete:"name",placeholder:i.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:r.name,onChange:d=>l({name:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>n==null?void 0:n(!1)})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.email})}),c.jsx("input",{ref:y,type:"email",name:"email",autoComplete:"email",placeholder:i.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${f?"input-error":""}`,value:r.email,onChange:d=>l({email:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{o(!0),n==null||n(!1)}}),f&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige E-Mail-Adresse ein":"Please enter a valid email address"})})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.phone})}),c.jsx("input",{ref:k,type:"tel",name:"phone",autoComplete:"tel",placeholder:i.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${p?"input-error":""}`,value:r.phone,onChange:d=>l({phone:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{h(!0),n==null||n(!1)}}),p&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige Telefonnummer ein":"Please enter a valid phone number"})})]})]})}const $e={},jn="https://api.stability.ai/v1/generation",An="https://api.stability.ai/v2beta/stable-image/edit/remove-background",Ht="stability_api_key";let fe=null;function Dn(e){fe=e}function Hn(){return fe}function Mn(){return fe!==null}const Un={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"},dt=[{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 On(e,t){const n=e/t;let a=dt[0],r=1/0;for(const l of dt){const i=l.width/l.height,s=Math.abs(n-i);s<r&&(r=s,a=l)}return a}function Yn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=On(a.width,a.height),l=document.createElement("canvas");l.width=r.width,l.height=r.height;const i=l.getContext("2d");if(!i){n(new Error("Failed to get canvas context"));return}const s=a.width/a.height,o=r.width/r.height;let u=0,h=0,f=a.width,p=a.height;s>o?(f=a.height*o,u=(a.width-f)/2):(p=a.width/o,h=(a.height-p)/2),i.drawImage(a,u,h,f,p,0,0,r.width,r.height),t(l.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function Mt(e){var i;const t=e.split(","),n=((i=t[0].match(/:(.*?);/))==null?void 0:i[1])||"image/png",a=atob(t[1]),r=a.length,l=new Uint8Array(r);for(let s=0;s<r;s++)l[s]=a.charCodeAt(s);return new Blob([l],{type:n})}function je(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&($e==null?void 0:$e.VITE_STABILITY_API_KEY)||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(Ht):null}function Ut(e){localStorage.setItem(Ht,e)}function Pe(){return fe?!0:je()!==null}async function _n(e){const t=je();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,l=await Yn(n),i=Mt(l),s=new FormData;s.append("init_image",i,"portrait.png"),s.append("init_image_mode","IMAGE_STRENGTH"),s.append("image_strength",String(1-r)),s.append("text_prompts[0][text]",Un[a]),s.append("text_prompts[0][weight]","1"),s.append("cfg_scale","7"),s.append("samples","1"),s.append("steps","30");const u=await fetch(`${jn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:s});if(!u.ok){const f=await u.text();throw console.error("Stability AI error:",f),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const h=await u.json();if(!h.artifacts||h.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${h.artifacts[0].base64}`}async function Ot(e){if(fe){const i=await fetch(fe,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!i.ok){const o=await i.json().catch(()=>({}));throw new Error(o.error||`API error: ${i.status}`)}return(await i.json()).imageDataUrl}const t=je();if(!t)throw new Error("No Stability AI API key configured");const n=Mt(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(An,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const i=await r.text();throw console.error("Stability AI remove background error:",i),r.status===401?new Error("Invalid API key"):r.status===402?new Error("Insufficient credits"):r.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${r.status}`)}const l=await r.blob();return new Promise((i,s)=>{const o=new FileReader;o.onload=()=>i(o.result),o.onerror=()=>s(new Error("Failed to read result")),o.readAsDataURL(l)})}function Wn(){const[e,t]=g.useState(!1),[n,a]=g.useState(!1),[r,l]=g.useState(null),[i,s]=g.useState(()=>Pe());g.useEffect(()=>{s(Pe());const p=setTimeout(()=>{s(Pe())},150);return()=>clearTimeout(p)},[]);const o=g.useCallback(()=>l(null),[]),u=g.useCallback(p=>{Ut(p),s(!0),l(null)},[]),h=g.useCallback(async(p,m=.5,y=40)=>{t(!0),l(null);try{return await xt(p,m,y)}catch(k){const d=k instanceof Error?k.message:"Enhancement failed";throw l(d),k}finally{t(!1)}},[]),f=g.useCallback(async p=>{a(!0),l(null);try{return await Ot(p)}catch(m){const y=m instanceof Error?m.message:"Background removal failed";throw l(y),m}finally{a(!1)}},[]);return{enhance:h,removeBg:f,isEnhancing:e,isRemovingBg:n,error:r,hasKey:i,setApiKey:u,clearError:o}}function Yt({isOpen:e,onClose:t,onSubmit:n}){const a=w(u=>u.appLanguage),[r,l]=g.useState("");if(!e)return null;const i=u=>{u.preventDefault(),r.trim()&&(n(r.trim()),l(""),t())},o={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."}}[a];return c.jsxs("dialog",{className:"modal modal-open",children:[c.jsxs("div",{className:"modal-box",children:[c.jsx("h3",{className:"font-bold text-lg",children:o.title}),c.jsx("p",{className:"py-4 text-sm opacity-80",children:o.description}),c.jsxs("form",{onSubmit:i,children:[c.jsxs("div",{className:"form-control",children:[c.jsx("input",{type:"password",placeholder:o.placeholder,className:"input input-bordered w-full",value:r,onChange:u=>l(u.target.value),autoFocus:!0}),c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt",children:o.hint})})]}),c.jsxs("div",{className:"modal-action",children:[c.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:o.cancel}),c.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:o.submit})]})]})]}),c.jsx("form",{method:"dialog",className:"modal-backdrop",children:c.jsx("button",{onClick:t,children:"close"})})]})}function ye({min:e,max:t,step:n,value:a,onChange:r,className:l="",disabled:i=!1}){const s=g.useRef(null),o=g.useRef(null),u=g.useRef(!1),[h,f]=g.useState(!1),p=(a-e)/(t-e)*100,m=g.useCallback(v=>{if(!s.current)return a;const S=s.current.getBoundingClientRect(),L=Math.max(0,Math.min(1,(v-S.left)/S.width)),P=t-e,D=e+L*P,j=Math.round(D/n)*n;return Math.max(e,Math.min(t,j))},[e,t,n,a]),y=g.useCallback(v=>{if(i)return;const S=v.touches[0];o.current={x:S.clientX,y:S.clientY,value:a,decided:!1},u.current=!1},[a,i]),k=g.useCallback(v=>{if(i||!o.current)return;const S=v.touches[0],L=Math.abs(S.clientX-o.current.x),P=Math.abs(S.clientY-o.current.y);if(!o.current.decided){if(L<8&&P<8)return;if(o.current.decided=!0,P>L){o.current=null;return}u.current=!0,f(!0)}if(u.current){const D=m(S.clientX);D!==a&&r(D)}},[i,m,r,a]),d=g.useCallback(v=>{if(o.current&&!o.current.decided){const S=v.changedTouches[0];if(S){const L=m(S.clientX);L!==a&&r(L)}}o.current=null,u.current=!1,f(!1)},[m,r,a]);g.useEffect(()=>{const v=s.current;if(!v)return;const S=L=>{u.current&&L.preventDefault()};return v.addEventListener("touchmove",S,{passive:!1}),()=>{v.removeEventListener("touchmove",S)}},[]);const I=g.useCallback(v=>{if(i)return;const S=m(v.clientX);r(S),f(!0);const L=D=>{const j=m(D.clientX);r(j)},P=()=>{f(!1),document.removeEventListener("mousemove",L),document.removeEventListener("mouseup",P)};document.addEventListener("mousemove",L),document.addEventListener("mouseup",P)},[i,m,r]),E=`calc(10px + (100% - 20px) * ${p/100})`;return c.jsxs("div",{ref:s,className:`relative h-10 flex items-center cursor-pointer overflow-visible ${i?"opacity-50 cursor-not-allowed":""}`,onTouchStart:y,onTouchMove:k,onTouchEnd:d,onMouseDown:I,children:[c.jsx("div",{className:"absolute h-2 bg-base-300 rounded-full inset-x-0"}),c.jsx("div",{className:`absolute h-2 rounded-full transition-colors ${l.includes("range-primary")?"bg-primary":l.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{left:0,width:E}}),c.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transition-transform ${h?"scale-110":""} ${l.includes("range-primary")?"border-primary":l.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:E,transform:"translateX(-50%)"}})]})}function zn(){const e=w(b=>b.appLanguage),t=w(b=>b.portrait),n=w(b=>b.setPortrait),a=w(b=>b.setPortraitZoom),r=w(b=>b.setPortraitPan),l=w(b=>b.setPortraitRawImage),i=w(b=>b.setPortraitBgRemoved),s=w(b=>b.setPortraitBgOpacity),o=w(b=>b.setPortraitBgBlur),u=w(b=>b.setPortraitEngravingIntensity),{enhance:h,removeBg:f,isEnhancing:p,isRemovingBg:m,error:y,hasKey:k,setApiKey:d}=Wn(),I=re(e),E=g.useRef(null),[v,S]=g.useState(!1),[L,P]=g.useState(!1),D=g.useRef(null),j=g.useRef(null),R=t.rawImage,C=t.bgRemovedImage,Y=t.bgRemoved,q=t.bgOpacity,H=t.bgBlur,O=t.engravingIntensity;g.useEffect(()=>{t.original&&!t.rawImage&&l(t.original)},[t.original,t.rawImage,l]),g.useEffect(()=>()=>{D.current&&clearTimeout(D.current),j.current&&clearTimeout(j.current)},[]);const Z=w(b=>b.voucherConfig.templateHue),oe=g.useRef(Z),J=g.useCallback(async b=>{if(!b.type.startsWith("image/"))return;const T=new FileReader;T.onload=async M=>{var _;const A=(_=M.target)==null?void 0:_.result,V=await ft(A);pt(),l(V),n(V),a(1),r(0,0),i(!1,null),s(0),o(0),u(0)},T.readAsDataURL(b)},[n,l,a,r,i,s,o,u]),be=g.useCallback(b=>{b.preventDefault(),S(!1);const T=b.dataTransfer.files[0];T&&J(T)},[J]),G=g.useCallback(b=>{b.preventDefault(),S(!0)},[]),Q=g.useCallback(b=>{b.preventDefault(),S(!1)},[]),K=()=>{var b;(b=E.current)==null||b.click()},xe=b=>{var M;const T=(M=b.target.files)==null?void 0:M[0];T&&J(T)},ee=g.useCallback(async(b,T,M)=>{try{return await h(b,T,M)}catch(A){return console.error("Enhancement failed:",A),b}},[h]),ve=g.useCallback(async b=>{try{const T=await f(b);return i(!0,T),T}catch(T){return console.error("Background removal failed:",T),b}},[f,i]),te=g.useCallback(async()=>{const b=w.getState(),T=b.portrait,M=b.voucherConfig.templateHue;if(!T.rawImage)return;let A;T.bgRemoved&&T.bgRemovedImage?A=await ze(T.bgRemovedImage,T.rawImage,T.bgOpacity,T.bgBlur):A=T.rawImage,T.engravingIntensity>0&&(A=await ee(A,T.engravingIntensity,M)),n(A)},[ee,n]);g.useEffect(()=>{if(oe.current===Z)return;oe.current=Z;const b=w.getState().portrait;b.engravingIntensity>0&&b.rawImage&&(D.current&&clearTimeout(D.current),D.current=setTimeout(te,150))},[Z,te]);const He=async()=>{if(!R)return;if(!Y&&!k){P(!0);return}if(!Y){const T=await ve(R),M=w.getState(),A=M.portrait,V=M.voucherConfig.templateHue;let _=await ze(T,R,A.bgOpacity,A.bgBlur);A.engravingIntensity>0&&(_=await ee(_,A.engravingIntensity,V)),n(_)}else{i(!1,null);const T=w.getState(),M=T.portrait.engravingIntensity,A=T.voucherConfig.templateHue;if(M>0){const V=await ee(R,M,A);n(V)}else n(R)}},we=b=>{u(b),D.current&&clearTimeout(D.current),R&&(D.current=setTimeout(te,150))},Me=async b=>{if(d(b),!R)return;const T=await ve(R),M=w.getState(),A=M.portrait,V=M.voucherConfig.templateHue;let _=await ze(T,R,A.bgOpacity,A.bgBlur);A.engravingIntensity>0&&(_=await ee(_,A.engravingIntensity,V)),n(_)},ke=b=>{s(b),j.current&&clearTimeout(j.current),!(!R||!C)&&(j.current=setTimeout(te,150))},Ie=b=>{o(b),j.current&&clearTimeout(j.current),!(!R||!C)&&(j.current=setTimeout(te,150))};return c.jsxs("div",{className:"space-y-4",children:[c.jsx("style",{children:`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),d=require("react"),nn=require("zustand"),an=require("zustand/middleware"),rn=require("jspdf");var ge=typeof document<"u"?document.currentScript:null;const on=1024,ct=1200,le=new Map;let q=null,lt=null;function et(e,t){return q||(q=document.createElement("canvas"),lt=q.getContext("2d",{willReadFrequently:!0})),(q.width!==e||q.height!==t)&&(q.width=e,q.height=t),lt}function fe(e){const t=le.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(le.size>10){const l=le.keys().next().value;l&&le.delete(l)}le.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function ft(){le.clear()}async function pt(e,t=on){const n=await fe(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,l=Math.round(n.width*r),o=Math.round(n.height*r),s=document.createElement("canvas"),i=s.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return s.width=l,s.height=o,i.drawImage(n,0,0,l,o),s.toDataURL("image/jpeg",.9)}async function bt(e){const t=await fe(e),n=Math.max(t.width,t.height);if(n<=ct){const i=document.createElement("canvas"),u=i.getContext("2d");if(!u)throw new Error("Failed to get canvas context");return i.width=t.width,i.height=t.height,u.drawImage(t,0,0),i.toDataURL("image/png")}const a=ct/n,r=Math.round(t.width*a),l=Math.round(t.height*a),o=document.createElement("canvas"),s=o.getContext("2d");if(!s)throw new Error("Failed to get canvas context");return o.width=r,o.height=l,s.drawImage(t,0,0,r,l),o.toDataURL("image/png")}async function $e(e,t,n,a=0){const[r,l]=await Promise.all([fe(e),fe(t)]),o=et(r.width,r.height);if(o.clearRect(0,0,r.width,r.height),n>0){const s=a*20;o.save(),o.globalAlpha=n,s>0&&(o.filter=`blur(${s}px)`),o.drawImage(l,0,0,r.width,r.height),o.restore()}return o.drawImage(r,0,0),q.toDataURL("image/png")}async function xt(e,t=.5,n=40){const a=await fe(e),r=et(a.width,a.height);r.clearRect(0,0,a.width,a.height),r.drawImage(a,0,0);const l=r.getImageData(0,0,a.width,a.height),o=l.data,s=new Uint32Array(o.buffer),i=1+t*.8,u=1-t,h=n%360/360;for(let x=0;x<s.length;x++){const f=s[x],g=f&255,v=f>>8&255,k=f>>16&255,m=f>>24&255;if(m===0)continue;let T=(((77*g+150*v+29*k>>8)/255-.5)*i+.5)*255;T<0?T=0:T>255&&(T=255);const I=T/255,E=.12,[R,P,D]=wt(h,E,I),j=g*u+R*t|0,L=v*u+P*t|0,C=k*u+D*t|0;s[x]=m<<24|C<<16|L<<8|j}return r.putImageData(l,0,0),q.toDataURL("image/png")}function sn(e,t,n){e/=255,t/=255,n/=255;const a=Math.max(e,t,n),r=Math.min(e,t,n),l=(a+r)/2;let o=0,s=0;if(a!==r){const i=a-r;switch(s=l>.5?i/(2-a-r):i/(a+r),a){case e:o=((t-n)/i+(t<n?6:0))/6;break;case t:o=((n-e)/i+2)/6;break;case n:o=((e-t)/i+4)/6;break}}return[o,s,l]}function wt(e,t,n){if(t===0){const o=Math.round(n*255);return[o,o,o]}const a=(o,s,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?o+(s-o)*6*i:i<1/2?s:i<2/3?o+(s-o)*(2/3-i)*6:o),r=n<.5?n*(1+t):n+t-n*t,l=2*n-r;return[Math.round(a(l,r,e+1/3)*255),Math.round(a(l,r,e)*255),Math.round(a(l,r,e-1/3)*255)]}const cn=29,ln=5;async function yt(e,t){if(Math.abs(t-cn)<=ln)return e;const n=await fe(e),a=et(n.width,n.height);a.clearRect(0,0,n.width,n.height),a.drawImage(n,0,0);const r=a.getImageData(0,0,n.width,n.height),l=r.data,o=new Uint32Array(l.buffer),s=t%360/360,i=20/360,u=45/360,h=o.length;for(let x=0;x<h;x++){const f=o[x],g=f&255,v=f>>8&255,k=f>>16&255,m=f>>24&255;if(m===0)continue;const[b,T,I]=sn(g,v,k);if(T<.08||b<i||b>u)continue;const E=s,R=Math.min(T,.05),[P,D,j]=wt(E,R,I);o[x]=m<<24|j<<16|D<<8|P}return a.putImageData(r,0,0),q.toDataURL("image/png")}const me=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",G={background:`${me}templates/background.webp`,frontFrame:`${me}templates/front_frame.webp`,backFrame:`${me}templates/back_frame.webp`},he={1:`${me}templates/1.png`,5:`${me}templates/5.png`,10:`${me}templates/10.png`},vt={de:{banner:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"}},en:{banner:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}}},ne=3633,ae=1920,Ae=.5,un=Math.round(ne*Ae),dn=Math.round(ae*Ae),It=320,kt=335,X={badges:{topLeft:{x:286,y:235},topRight:{x:3340,y:230},bottomLeft:{x:282,y:1665},bottomRight:{x:3345,y:1665}},banner:{centerX:1816,centerY:3820,radius:3610,fontSize:103,color:"#2a3a2a"}},Pe=new Map,ie=new Map,Ke=new Map,Fe=new Map,qe=new Map;function Tt(e,t,n,a,r,l,o){e.save(),e.font=`900 ${l}px "Times New Roman", Georgia, serif`,e.fillStyle=o,e.textAlign="center",e.textBaseline="middle";const i=e.measureText(t).width/r,u=-Math.PI/2-i/2,h=t.split(""),x=[];for(const g of h)x.push(e.measureText(g).width);let f=u;for(let g=0;g<h.length;g++){const v=h[g],k=x[g],m=f+k/2/r,b=n+r*Math.cos(m),T=a+r*Math.sin(m);e.save(),e.translate(b,T),e.rotate(m+Math.PI/2),e.fillText(v,0,0),e.restore(),f+=k/r}e.restore()}let W={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function gn(){const[e,t,n,a,r,l]=await Promise.all([B(G.background),B(G.frontFrame),B(G.backFrame),B(he[1]),B(he[5]),B(he[10])]);W={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:l}}}function mn(e,t){const n=Math.round(ne*e),a=Math.round(ae*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");l.drawImage(t,0,0,n,a);const o=e<1?.8:.95;return r.toDataURL("image/jpeg",o)}function hn(e,t){const n=Math.round(ne*e),a=Math.round(ae*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");const o=It*e,s=kt*e,i=X.badges,u=(h,x)=>{const f=x/2,g=h.x*e-f,v=h.y*e-f;l.drawImage(t,g,v,x,x)};return u(i.topLeft,o),u(i.topRight,o),u(i.bottomLeft,s),u(i.bottomRight,s),r.toDataURL("image/png")}function Et(e,t,n,a=1){const r=vt[n].banner[t];Tt(e,r,X.banner.centerX*a,X.banner.centerY*a,X.banner.radius*a,X.banner.fontSize*a,X.banner.color)}function St(e,t,n,a,r,l,o){const s=Math.round(ne*a),i=Math.round(ae*a),u=document.createElement("canvas");u.width=s,u.height=i;const h=u.getContext("2d");if(!h)throw new Error("Failed to get canvas context");h.drawImage(r,0,0,s,i);{const f=It*a,g=kt*a,v=X.badges,k=(m,b)=>{const T=b/2,I=m.x*a-T,E=m.y*a-T;h.drawImage(o,I,E,b,b)};k(v.topLeft,f),k(v.topRight,f),k(v.bottomLeft,g),k(v.bottomRight,g)}if(h.drawImage(l,0,0,s,i),n==="front"){const f=vt[t].banner[e];Tt(h,f,X.banner.centerX*a,X.banner.centerY*a,X.banner.radius*a,X.banner.fontSize*a,X.banner.color)}const x=a<1?.8:.95;return u.toDataURL("image/jpeg",x)}async function Pt(e,t,n){const a=`${e}-${t}-${n}`;if(Pe.has(a))return Pe.get(a);const r=W.background||await B(G.background),l=n==="front"?W.frontFrame||await B(G.frontFrame):W.backFrame||await B(G.backFrame),o=W.badges[e]||await B(he[e]),s=St(e,t,n,Ae,r,l,o);return Pe.set(a,s),s}async function Ze(e,t,n){const a=`${e}-${t}-${n}`;if(ie.has(a))return ie.get(a);const r=W.background||await B(G.background),l=n==="front"?W.frontFrame||await B(G.frontFrame):W.backFrame||await B(G.backFrame),o=W.badges[e]||await B(he[e]),s=St(e,t,n,1,r,l,o);if(ie.size>4){const i=ie.keys().next().value;i&&ie.delete(i)}return ie.set(a,s),s}function fn(){return{width:ne,height:ae}}function Rt(){Pe.clear(),ie.clear(),Ke.clear(),Fe.clear(),qe.clear()}async function Je(e,t,n="front",a=Ae){const r=`bg-${a}`;let l=Ke.get(r);if(!l){const h=W.background||await B(G.background);l=mn(a,h),Ke.set(r,l)}const o=`badges-${e}-${a}`;let s=Fe.get(o);if(!s){const h=W.badges[e]||await B(he[e]);s=hn(a,h),Fe.set(o,s)}const i=`${n}-${a}`;let u=qe.get(i);if(!u){const h=n==="front"?W.frontFrame||await B(G.frontFrame):W.backFrame||await B(G.backFrame),x=Math.round(ne*a),f=Math.round(ae*a),g=document.createElement("canvas");g.width=x,g.height=f;const v=g.getContext("2d");if(!v)throw new Error("Failed to get canvas context");v.drawImage(h,0,0,x,f),u=g.toDataURL("image/png"),qe.set(i,u)}return{background:l,badges:s,frame:u}}async function pn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const l of t)for(const o of n)a.push(Pt(r,l,o));await Promise.all(a)}const Re=new Map,se=new Map;function Lt(){se.clear(),Re.clear(),ft()}async function B(e){return Re.has(e)?Re.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{Re.set(e,a),t(a)},a.onerror=n,a.src=e})}function ce(e,t,n,a){e.drawImage(t,0,0,n,a)}const bn=29,xn=5;async function Ct(e,t,n,a){if(Math.abs(t-bn)<=xn)return B(e);const r=`${e}:${t}:${n}x${a}`;if(se.has(r))return B(se.get(r));const l=await B(e),o=document.createElement("canvas");o.width=n,o.height=a;const s=o.getContext("2d");if(!s)throw new Error("Failed to get canvas context");s.drawImage(l,0,0,n,a);const i=o.toDataURL("image/png"),u=await yt(i,t);if(se.size>20){const h=se.keys().next().value;h&&se.delete(h)}return se.set(r,u),B(u)}function wn(e,t,n,a,r,l="de"){e.save(),e.beginPath(),e.ellipse(t,n,a,r,0,0,Math.PI*2),e.closePath(),e.setLineDash([20,10]),e.strokeStyle="rgba(100, 100, 100, 0.4)",e.lineWidth=3,e.stroke(),e.restore()}function Bt(e,t,n,a,r,l,o=1,s=0,i=0){e.save(),e.beginPath(),e.ellipse(n,a,r,l,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,h=r/l,x=r*2,f=l*2;let g,v;u>h?(v=f,g=f*u):(g=x,v=x/u),g*=o,v*=o;const k=Math.max(0,(g-x)/2),m=Math.max(0,(v-f)/2),b=n-g/2+s*k,T=a-v/2+i*m;e.drawImage(t,b,T,g,v),e.restore()}function tt(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=a,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function Nt(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=a;const r=n.maxWidth||400,l=n.lineHeight||n.fontSize*1.4,o=t.split(" "),s=[];let i="";for(const x of o){const f=i?`${i} ${x}`:x;e.measureText(f).width>r&&i?(s.push(i),i=x):i=f}i&&s.push(i);const u=s.length*l;let h=n.y-u/2;for(const x of s)e.fillText(x,n.x,h),h+=l;e.restore()}function jt(e,t,n,a,r,l="#2a3a2a"){e.save(),e.font=`${r.fontSize}px "Times New Roman", serif`,e.textAlign=r.align||"center",e.textBaseline="middle",e.fillStyle=l;const o=r.lineHeight||r.fontSize*1.8,s=[t,n,a].filter(Boolean),i=(s.length-1)*o;let u=r.y-i/2;for(const h of s)h&&(e.fillText(h,r.x,u),u+=o);e.restore()}function yn(e,t,n,a="#2a3a2a"){e.save(),e.strokeStyle=a,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=a,e.fillText(n,t.x,t.y+t.labelFontSize*.3),e.restore()}async function At(e,t,n,a,r,l,o,s,i,u=1,h=0,x=0,f=0,g=1,v="de"){const k=e.getContext("2d");if(!k)return;const m=document.createElement("canvas");m.width=s,m.height=i;const b=m.getContext("2d");if(!b)return;b.clearRect(0,0,s,i);const T=await Ct(t,f,s,i);ce(b,T,s,i);const I=await B(n);if(ce(b,I,s,i),r)try{const P=await B(r);Bt(b,P,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,u,h,x)}catch(P){console.error("Failed to load portrait:",P)}else wn(b,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,v);const E=await B(a);ce(b,E,s,i);const R=s/3633;Et(b,g,v,R),l&&tt(b,l,o.namePlate),e.width=s,e.height=i,k.drawImage(m,0,0)}async function Dt(e,t,n,a,r,l,o,s,i,u,h,x=0,f=1,g="de"){const v=e.getContext("2d");if(!v)return;const k=document.createElement("canvas");k.width=u,k.height=h;const m=k.getContext("2d");if(!m)return;m.clearRect(0,0,u,h);const b=await Ct(t,x,u,h);ce(m,b,u,h);const T=await B(n);ce(m,T,u,h);const I=await B(a);ce(m,I,u,h);const E=u/3633;if(Et(m,f,g,E),i.contactInfo&&(r||l||o)&&jt(m,r,l,o,i.contactInfo),i.description&&s&&Nt(m,s,i.description),r&&tt(m,r,i.namePlate),i.signature){const R=g==="de"?"Unterschrift":"Signature";yn(m,i.signature,R)}e.width=u,e.height=h,v.drawImage(k,0,0)}const Ce="money-generator-portrait",Be="money-generator-bg-removed";async function vn(e){try{if(localStorage.removeItem(Ce),!e)return;const t=await bt(e);try{localStorage.setItem(Ce,t)}catch(n){console.warn("Could not persist portrait to localStorage:",n)}}catch(t){console.warn("Error processing portrait for storage:",t)}}async function In(e){try{if(localStorage.removeItem(Be),!e)return;const t=await bt(e);try{localStorage.setItem(Be,t)}catch(n){console.warn("Could not persist bg-removed image to localStorage:",n)}}catch(t){console.warn("Error processing bg-removed image for storage:",t)}}function kn(){try{return localStorage.getItem(Ce)}catch{return null}}function Tn(){try{return localStorage.getItem(Be)}catch{return null}}function En(){try{localStorage.removeItem(Ce),localStorage.removeItem(Be)}catch{}}function Sn(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Ne=Sn(),ut={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Ne,templateHue:29},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:Ne},y=nn.create()(an.persist(e=>({...ut,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>e(a=>{const r=a.portrait.original||a.portrait.rawImage;return{portrait:{...a.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:r&&t?a.portrait.zoom:1,panX:r&&t?a.portrait.panX:0,panY:r&&t?a.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(a=>({portrait:{...a.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>(vn(t),e(n=>({portrait:{...n.portrait,rawImage:t}}))),setPortraitBgRemoved:(t,n)=>(n!==void 0&&In(n),e(a=>({portrait:{...a.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:a.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=>(Lt(),Rt(),e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}}))),reset:()=>(En(),e(ut))}),{name:"money-generator-storage",migrate:e=>{const t=e;return t!=null&&t.voucherConfig&&(t.voucherConfig.templateHue===void 0&&(t.voucherConfig.templateHue=29),t.voucherConfig.hours=1,t.voucherConfig.language=Ne),t&&(t.appLanguage=Ne),t},version:2,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:e.portrait.bgRemoved,bgOpacity:e.portrait.bgOpacity,bgBlur:e.portrait.bgBlur,engravingIntensity:e.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));if(typeof window<"u"){const e=kn(),t=Tn();e&&setTimeout(()=>{const n=y.getState();if(!n.portrait.rawImage){const a=n.portrait.bgRemoved,r=t!==null;y.setState({portrait:{...n.portrait,rawImage:e,original:null,bgRemovedImage:t,bgRemoved:a&&r,bgOpacity:a&&r?n.portrait.bgOpacity:0,bgBlur:a&&r?n.portrait.bgBlur:0}})}},0)}const Pn={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 {bannerText} meiner Zeit oder ein gleichwertiges Dankeschön.",bannerText:{1:"eine Stunde",5:"fünf Stunden",10:"zehn Stunden"}}},Rn={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:"For this voucher, you will receive {bannerText} of my time or an equivalent appreciation in return.",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},Ln={de:Pn,en:Rn};function re(e){return Ln[e]}function nt(e,t,n){if(n&&n.trim())return n;const a=re(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function Cn(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function Bn(e){return e.replace(/\D/g,"").length>=6}function Nn({focusField:e,onFocused:t,onFormFocusChange:n}={}){const a=y(m=>m.appLanguage),r=y(m=>m.personalInfo),l=y(m=>m.setPersonalInfo),o=re(a),[s,i]=d.useState(!1),[u,h]=d.useState(!1),x=s&&r.email.trim()&&!Cn(r.email),f=u&&r.phone.trim()&&!Bn(r.phone),g=d.useRef(null),v=d.useRef(null),k=d.useRef(null);return d.useEffect(()=>{if(e){const m=e==="name"?g:e==="email"?v:k;setTimeout(()=>{var b,T;(b=m.current)==null||b.click(),(T=m.current)==null||T.focus(),setTimeout(()=>{var I;(I=m.current)==null||I.scrollIntoView({behavior:"smooth",block:"center"})},300),t==null||t()},100)}},[e,t]),c.jsxs("div",{className:"space-y-4",children:[c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:o.form.personalInfo.name})}),c.jsx("input",{ref:g,type:"text",name:"name",autoComplete:"name",placeholder:o.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:r.name,onChange:m=>l({name:m.target.value}),onFocus:m=>{n==null||n(!0),setTimeout(()=>m.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>n==null?void 0:n(!1)})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:o.form.personalInfo.email})}),c.jsx("input",{ref:v,type:"email",name:"email",autoComplete:"email",placeholder:o.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${x?"input-error":""}`,value:r.email,onChange:m=>l({email:m.target.value}),onFocus:m=>{n==null||n(!0),setTimeout(()=>m.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{i(!0),n==null||n(!1)}}),x&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige E-Mail-Adresse ein":"Please enter a valid email address"})})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:o.form.personalInfo.phone})}),c.jsx("input",{ref:k,type:"tel",name:"phone",autoComplete:"tel",placeholder:o.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${f?"input-error":""}`,value:r.phone,onChange:m=>l({phone:m.target.value}),onFocus:m=>{n==null||n(!0),setTimeout(()=>m.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{h(!0),n==null||n(!1)}}),f&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige Telefonnummer ein":"Please enter a valid phone number"})})]})]})}const Xe={},jn="https://api.stability.ai/v1/generation",An="https://api.stability.ai/v2beta/stable-image/edit/remove-background",Ht="stability_api_key";let pe=null;function Dn(e){pe=e}function Hn(){return pe}function Mn(){return pe!==null}const Un={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"},dt=[{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 On(e,t){const n=e/t;let a=dt[0],r=1/0;for(const l of dt){const o=l.width/l.height,s=Math.abs(n-o);s<r&&(r=s,a=l)}return a}function Yn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=On(a.width,a.height),l=document.createElement("canvas");l.width=r.width,l.height=r.height;const o=l.getContext("2d");if(!o){n(new Error("Failed to get canvas context"));return}const s=a.width/a.height,i=r.width/r.height;let u=0,h=0,x=a.width,f=a.height;s>i?(x=a.height*i,u=(a.width-x)/2):(f=a.width/i,h=(a.height-f)/2),o.drawImage(a,u,h,x,f,0,0,r.width,r.height),t(l.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function Mt(e){var o;const t=e.split(","),n=((o=t[0].match(/:(.*?);/))==null?void 0:o[1])||"image/png",a=atob(t[1]),r=a.length,l=new Uint8Array(r);for(let s=0;s<r;s++)l[s]=a.charCodeAt(s);return new Blob([l],{type:n})}function De(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&(Xe==null?void 0:Xe.VITE_STABILITY_API_KEY)||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(Ht):null}function Ut(e){localStorage.setItem(Ht,e)}function Le(){return pe?!0:De()!==null}async function _n(e){const t=De();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,l=await Yn(n),o=Mt(l),s=new FormData;s.append("init_image",o,"portrait.png"),s.append("init_image_mode","IMAGE_STRENGTH"),s.append("image_strength",String(1-r)),s.append("text_prompts[0][text]",Un[a]),s.append("text_prompts[0][weight]","1"),s.append("cfg_scale","7"),s.append("samples","1"),s.append("steps","30");const u=await fetch(`${jn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:s});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 h=await u.json();if(!h.artifacts||h.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${h.artifacts[0].base64}`}async function Ot(e){if(pe){const o=await fetch(pe,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!o.ok){const i=await o.json().catch(()=>({}));throw new Error(i.error||`API error: ${o.status}`)}return(await o.json()).imageDataUrl}const t=De();if(!t)throw new Error("No Stability AI API key configured");const n=Mt(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(An,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const o=await r.text();throw console.error("Stability AI remove background error:",o),r.status===401?new Error("Invalid API key"):r.status===402?new Error("Insufficient credits"):r.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${r.status}`)}const l=await r.blob();return new Promise((o,s)=>{const i=new FileReader;i.onload=()=>o(i.result),i.onerror=()=>s(new Error("Failed to read result")),i.readAsDataURL(l)})}function Wn(){const[e,t]=d.useState(!1),[n,a]=d.useState(!1),[r,l]=d.useState(null),[o,s]=d.useState(()=>Le());d.useEffect(()=>{s(Le());const f=setTimeout(()=>{s(Le())},150);return()=>clearTimeout(f)},[]);const i=d.useCallback(()=>l(null),[]),u=d.useCallback(f=>{Ut(f),s(!0),l(null)},[]),h=d.useCallback(async(f,g=.5,v=40)=>{t(!0),l(null);try{return await xt(f,g,v)}catch(k){const m=k instanceof Error?k.message:"Enhancement failed";throw l(m),k}finally{t(!1)}},[]),x=d.useCallback(async f=>{a(!0),l(null);try{return await Ot(f)}catch(g){const v=g instanceof Error?g.message:"Background removal failed";throw l(v),g}finally{a(!1)}},[]);return{enhance:h,removeBg:x,isEnhancing:e,isRemovingBg:n,error:r,hasKey:o,setApiKey:u,clearError:i}}function Yt({isOpen:e,onClose:t,onSubmit:n}){const a=y(u=>u.appLanguage),[r,l]=d.useState("");if(!e)return null;const o=u=>{u.preventDefault(),r.trim()&&(n(r.trim()),l(""),t())},i={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."}}[a];return c.jsxs("dialog",{className:"modal modal-open",children:[c.jsxs("div",{className:"modal-box",children:[c.jsx("h3",{className:"font-bold text-lg",children:i.title}),c.jsx("p",{className:"py-4 text-sm opacity-80",children:i.description}),c.jsxs("form",{onSubmit:o,children:[c.jsxs("div",{className:"form-control",children:[c.jsx("input",{type:"password",placeholder:i.placeholder,className:"input input-bordered w-full",value:r,onChange:u=>l(u.target.value),autoFocus:!0}),c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt",children:i.hint})})]}),c.jsxs("div",{className:"modal-action",children:[c.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:i.cancel}),c.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:i.submit})]})]})]}),c.jsx("form",{method:"dialog",className:"modal-backdrop",children:c.jsx("button",{onClick:t,children:"close"})})]})}function Ie({min:e,max:t,step:n,value:a,onChange:r,className:l="",disabled:o=!1}){const s=d.useRef(null),i=d.useRef(null),u=d.useRef(!1),[h,x]=d.useState(!1),f=(a-e)/(t-e)*100,g=d.useCallback(I=>{if(!s.current)return a;const E=s.current.getBoundingClientRect(),R=Math.max(0,Math.min(1,(I-E.left)/E.width)),P=t-e,D=e+R*P,j=Math.round(D/n)*n;return Math.max(e,Math.min(t,j))},[e,t,n,a]),v=d.useCallback(I=>{if(o)return;const E=I.touches[0];i.current={x:E.clientX,y:E.clientY,value:a,decided:!1},u.current=!1},[a,o]),k=d.useCallback(I=>{if(o||!i.current)return;const E=I.touches[0],R=Math.abs(E.clientX-i.current.x),P=Math.abs(E.clientY-i.current.y);if(!i.current.decided){if(R<8&&P<8)return;if(i.current.decided=!0,P>R){i.current=null;return}u.current=!0,x(!0)}if(u.current){const D=g(E.clientX);D!==a&&r(D)}},[o,g,r,a]),m=d.useCallback(I=>{if(i.current&&!i.current.decided){const E=I.changedTouches[0];if(E){const R=g(E.clientX);R!==a&&r(R)}}i.current=null,u.current=!1,x(!1)},[g,r,a]);d.useEffect(()=>{const I=s.current;if(!I)return;const E=R=>{u.current&&R.preventDefault()};return I.addEventListener("touchmove",E,{passive:!1}),()=>{I.removeEventListener("touchmove",E)}},[]);const b=d.useCallback(I=>{if(o)return;const E=g(I.clientX);r(E),x(!0);const R=D=>{const j=g(D.clientX);r(j)},P=()=>{x(!1),document.removeEventListener("mousemove",R),document.removeEventListener("mouseup",P)};document.addEventListener("mousemove",R),document.addEventListener("mouseup",P)},[o,g,r]),T=`calc(10px + (100% - 20px) * ${f/100})`;return c.jsxs("div",{ref:s,className:`relative h-10 flex items-center cursor-pointer overflow-visible ${o?"opacity-50 cursor-not-allowed":""}`,onTouchStart:v,onTouchMove:k,onTouchEnd:m,onMouseDown:b,children:[c.jsx("div",{className:"absolute h-2 bg-base-300 rounded-full inset-x-0"}),c.jsx("div",{className:`absolute h-2 rounded-full transition-colors ${l.includes("range-primary")?"bg-primary":l.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{left:0,width:T}}),c.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transition-transform ${h?"scale-110":""} ${l.includes("range-primary")?"border-primary":l.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:T,transform:"translateX(-50%)"}})]})}function zn(){const e=y(p=>p.appLanguage),t=y(p=>p.portrait),n=y(p=>p.setPortrait),a=y(p=>p.setPortraitZoom),r=y(p=>p.setPortraitPan),l=y(p=>p.setPortraitRawImage),o=y(p=>p.setPortraitBgRemoved),s=y(p=>p.setPortraitBgOpacity),i=y(p=>p.setPortraitBgBlur),u=y(p=>p.setPortraitEngravingIntensity),{enhance:h,removeBg:x,isEnhancing:f,isRemovingBg:g,error:v,hasKey:k,setApiKey:m}=Wn(),b=re(e),T=d.useRef(null),[I,E]=d.useState(!1),[R,P]=d.useState(!1),D=d.useRef(null),j=d.useRef(null),L=t.rawImage,C=t.bgRemovedImage,Y=t.bgRemoved,Z=t.bgOpacity,H=t.bgBlur,O=t.engravingIntensity;d.useEffect(()=>{t.original&&!t.rawImage&&l(t.original)},[t.original,t.rawImage,l]),d.useEffect(()=>()=>{D.current&&clearTimeout(D.current),j.current&&clearTimeout(j.current)},[]);const J=y(p=>p.voucherConfig.templateHue),oe=d.useRef(J),Q=d.useCallback(async p=>{if(!p.type.startsWith("image/"))return;const S=new FileReader;S.onload=async M=>{var _;const A=(_=M.target)==null?void 0:_.result,z=await pt(A);ft(),l(z),n(z),a(1),r(0,0),o(!1,null),s(0),i(0),u(0)},S.readAsDataURL(p)},[n,l,a,r,o,s,i,u]),be=d.useCallback(p=>{p.preventDefault(),E(!1);const S=p.dataTransfer.files[0];S&&Q(S)},[Q]),V=d.useCallback(p=>{p.preventDefault(),E(!0)},[]),ee=d.useCallback(p=>{p.preventDefault(),E(!1)},[]),F=()=>{var p;(p=T.current)==null||p.click()},xe=p=>{var M;const S=(M=p.target.files)==null?void 0:M[0];S&&Q(S)},te=d.useCallback(async(p,S,M)=>{try{return await h(p,S,M)}catch(A){return console.error("Enhancement failed:",A),p}},[h]),ke=d.useCallback(async p=>{try{const S=await x(p);return o(!0,S),S}catch(S){return console.error("Background removal failed:",S),p}},[x,o]),K=d.useCallback(async()=>{const p=y.getState(),S=p.portrait,M=p.voucherConfig.templateHue;if(!S.rawImage)return;let A;S.bgRemoved&&S.bgRemovedImage?A=await $e(S.bgRemovedImage,S.rawImage,S.bgOpacity,S.bgBlur):A=S.rawImage,S.engravingIntensity>0&&(A=await te(A,S.engravingIntensity,M)),n(A)},[te,n]),we=d.useRef(!1);d.useEffect(()=>{t.rawImage&&!t.original&&!we.current&&(we.current=!0,setTimeout(()=>{K()},0)),t.rawImage||(we.current=!1)},[t.rawImage,t.original,K]),d.useEffect(()=>{if(oe.current===J)return;oe.current=J;const p=y.getState().portrait;p.engravingIntensity>0&&p.rawImage&&(D.current&&clearTimeout(D.current),D.current=setTimeout(K,150))},[J,K]);const ye=async()=>{if(!L)return;if(!Y&&!k){P(!0);return}if(!Y){const S=await ke(L),M=y.getState(),A=M.portrait,z=M.voucherConfig.templateHue;let _=await $e(S,L,A.bgOpacity,A.bgBlur);A.engravingIntensity>0&&(_=await te(_,A.engravingIntensity,z)),n(_)}else{o(!1,null);const S=y.getState(),M=S.portrait.engravingIntensity,A=S.voucherConfig.templateHue;if(M>0){const z=await te(L,M,A);n(z)}else n(L)}},Ue=p=>{u(p),D.current&&clearTimeout(D.current),L&&(D.current=setTimeout(K,150))},Te=async p=>{if(m(p),!L)return;const S=await ke(L),M=y.getState(),A=M.portrait,z=M.voucherConfig.templateHue;let _=await $e(S,L,A.bgOpacity,A.bgBlur);A.engravingIntensity>0&&(_=await te(_,A.engravingIntensity,z)),n(_)},Ee=p=>{s(p),j.current&&clearTimeout(j.current),!(!L||!C)&&(j.current=setTimeout(K,150))},ve=p=>{i(p),j.current&&clearTimeout(j.current),!(!L||!C)&&(j.current=setTimeout(K,150))};return c.jsxs("div",{className:"space-y-4",children:[c.jsx("style",{children:`
|
|
2
2
|
@keyframes sparkle1 {
|
|
3
3
|
0%, 33%, 100% { opacity: 0.3; }
|
|
4
4
|
16% { opacity: 1; }
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
0%, 66%, 100% { opacity: 0.3; }
|
|
12
12
|
83% { opacity: 1; }
|
|
13
13
|
}
|
|
14
|
-
`}),t.original?c.jsxs("div",{className:"flex flex-col space-y-4",children:[c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:I.form.portrait.zoom}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),c.jsx(ye,{min:.5,max:2,step:.05,value:t.zoom,onChange:a,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",p&&c.jsx("span",{className:"loading loading-spinner loading-xs"})]}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(O*100),"%"]})]}),c.jsx(ye,{min:0,max:1,step:.05,value:O,onChange:we,className:"range range-secondary range-sm",disabled:p||!R})]})]}),Y?c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(q*100),"%"]})]}),c.jsx(ye,{min:0,max:1,step:.05,value:q,onChange:ke,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(H*100),"%"]})]}),c.jsx(ye,{min:0,max:1,step:.05,value:H,onChange:Ie,className:"range range-primary range-sm",disabled:q===0})]})]}):c.jsx("div",{className:"flex justify-center",children:c.jsxs("button",{className:"btn btn-ghost btn gap-2 text-base-content/70",onClick:He,disabled:m||!R,children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:[c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z",style:m?{animation:"sparkle1 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456z",style:m?{animation:"sparkle2 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z",style:m?{animation:"sparkle3 2.4s ease-in-out infinite"}:void 0})]}),m?e==="de"?"Hintergrund wird entfernt ...":"Removing background ...":e==="de"?"Hintergrund entfernen":"Remove background",!m&&!k&&c.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})}),y&&c.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[c.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:c.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"})}),c.jsx("span",{children:y})]})]}):c.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":v?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:be,onDragOver:G,onDragLeave:Q,onClick:K,children:[c.jsx("input",{ref:E,type:"file",accept:"image/*",className:"hidden",onChange:xe}),m?c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),c.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt ...":"Removing background ..."})]}):c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.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:c.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"})}),c.jsx("p",{className:"font-medium",children:I.form.portrait.upload}),c.jsx("p",{className:"text-sm text-base-content/60",children:I.form.portrait.dragDrop})]})]}),c.jsx(Yt,{isOpen:L,onClose:()=>P(!1),onSubmit:Me})]})}function $n(){const e=w(s=>s.appLanguage),t=w(s=>s.voucherConfig.language),n=w(s=>s.voucherConfig.hours);w(s=>s.voucherConfig.templateHue);const a=w(s=>s.setBillLanguage),r=w(s=>s.setHours);w(s=>s.setTemplateHue);const l=re(e),i=[1,5,10];return c.jsxs("div",{className:"space-y-4",children:[c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.billLanguage}),c.jsxs("div",{className:"join border border-base-300 rounded-lg shadow",children:[c.jsx("button",{className:`join-item btn btn-md ${t==="de"?"btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:l.form.voucher.billLanguageGerman}),c.jsx("button",{className:`join-item btn btn-md ${t==="en"?"btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:l.form.voucher.billLanguageEnglish})]})]})}),c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.hours}),c.jsx("div",{className:"join border border-base-300 rounded-lg shadow",children:i.map(s=>c.jsxs("button",{className:`join-item btn btn-md ${n===s?"btn-primary":"btn-ghost"}`,onClick:()=>r(s),children:[s,c.jsxs("span",{className:"hidden sm:inline",children:[" ",s===1?l.form.voucher.hourLabel:l.form.voucher.hoursLabel]})]},s))})]})}),!1]})}function nt(e,t){return{front:"",back:"",width:ne,height:ae}}const Ae={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},ue=Ae,de=Ae;function at(e){return Ae}const Je=.75;function Xn(e){const t=at(),n=Je,a=r=>({portrait:{x:r.portrait.x*n,y:r.portrait.y*n,radiusX:r.portrait.radiusX*n,radiusY:r.portrait.radiusY*n},namePlate:{x:r.namePlate.x*n,y:r.namePlate.y*n,fontSize:r.namePlate.fontSize*n,maxWidth:r.namePlate.maxWidth?r.namePlate.maxWidth*n:void 0,lineHeight:r.namePlate.lineHeight?r.namePlate.lineHeight*n:void 0,align:r.namePlate.align},contactInfo:r.contactInfo?{x:r.contactInfo.x*n,y:r.contactInfo.y*n,fontSize:r.contactInfo.fontSize*n,maxWidth:r.contactInfo.maxWidth?r.contactInfo.maxWidth*n:void 0,lineHeight:r.contactInfo.lineHeight?r.contactInfo.lineHeight*n:void 0,align:r.contactInfo.align}:void 0,description:r.description?{x:r.description.x*n,y:r.description.y*n,fontSize:r.description.fontSize*n,maxWidth:r.description.maxWidth?r.description.maxWidth*n:void 0,lineHeight:r.description.lineHeight?r.description.lineHeight*n:void 0,align:r.description.align}:void 0,signature:r.signature?{x:r.signature.x*n,y:r.signature.y*n,width:r.signature.width*n,height:r.signature.height*n,labelFontSize:r.signature.labelFontSize*n}:void 0});return{front:a(t.front),back:a(t.back)}}function Gn(e,t){const n=nt();return{...n,width:Math.round(n.width*Je),height:Math.round(n.height*Je)}}function Vn(e,t){const[n,a]=g.useState(e);return g.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Kn({onPortraitClick:e,onFileDrop:t}={}){const n=w(x=>x.appLanguage),a=w(x=>x.voucherConfig.language),r=w(x=>x.voucherConfig.hours),l=w(x=>x.voucherConfig.description),i=w(x=>x.voucherConfig.templateHue),s=w(x=>x.personalInfo),o=w(x=>x.portrait),u=w(x=>x.currentSide),h=w(x=>x.flipSide),f=w(x=>x.setPortraitPan),p=Vn(i,150),m=re(n),y=g.useRef(null),k=g.useRef(null),d=g.useRef(null),[I,E]=g.useState(!1),[v,S]=g.useState(!1),[L,P]=g.useState(!1),[D,j]=g.useState(!1),R=g.useRef(null),C=g.useRef(null),Y=g.useRef(!1),q=g.useRef(0),H=Gn(),O=Xn(),Z=o.useEnhanced&&o.enhanced?o.enhanced:o.original,oe=tt(a,r,l),[J,be]=g.useState(""),[G,Q]=g.useState(""),[K,xe]=g.useState(""),[ee,ve]=g.useState(""),[te,He]=g.useState(""),[we,Me]=g.useState(""),[ke,Ie]=g.useState(!0);g.useEffect(()=>{let x=!0;Ie(!0);async function N(){const[U,z]=await Promise.all([Ze(r,a,"front"),Ze(r,a,"back")]);x&&(be(U.background),Q(U.badges),xe(U.frame),ve(z.background),He(z.badges),Me(z.frame),Ie(!1))}return N(),()=>{x=!1}},[r,a]),g.useEffect(()=>{!y.current||!J||!G||!K||At(y.current,J,G,K,Z,s.name,O.front,H.width,H.height,o.zoom,o.panX,o.panY,p,r,a)},[H,J,G,K,Z,s.name,O,o.zoom,o.panX,o.panY,p,r,a]),g.useEffect(()=>{!k.current||!ee||!te||!we||Dt(k.current,ee,te,we,s.name,s.email,s.phone,oe,O.back,H.width,H.height,p,r,a)},[H,ee,te,we,s,oe,O,p,r,a]);const b=()=>{E(!I),h()};g.useEffect(()=>{E(u==="back")},[u]);const T=g.useCallback((x,N)=>{if(!d.current||u!=="front")return!1;const U=d.current.getBoundingClientRect(),z=U.width/H.width,Ue=U.height/H.height,Te=(x-U.left)/z,Oe=(N-U.top)/Ue,{x:Ye,y:_e,radiusX:We,radiusY:tn}=O.front.portrait,it=(Te-Ye)/We,st=(Oe-_e)/tn;return it*it+st*st<=1},[u,H.width,H.height,O.front.portrait]),M=5,A=g.useCallback((x,N)=>{o.original&&(S(!0),R.current={x,y:N,panX:o.panX,panY:o.panY})},[o.original,o.panX,o.panY]),V=g.useCallback((x,N)=>{if(!v||!R.current||!d.current)return;const U=performance.now();if(U-q.current<33)return;q.current=U;const z=d.current.getBoundingClientRect(),Te=4/Math.max(z.width,z.height)*o.zoom,Oe=(x-R.current.x)*Te,Ye=(N-R.current.y)*Te,_e=Math.max(-1,Math.min(1,R.current.panX+Oe)),We=Math.max(-1,Math.min(1,R.current.panY+Ye));f(_e,We)},[v,f,o.zoom]),_=g.useCallback(()=>{S(!1),R.current=null,C.current=null},[]),rt=g.useCallback(()=>{e&&e()},[e]),Gt=x=>{T(x.clientX,x.clientY)&&(x.preventDefault(),C.current={x:x.clientX,y:x.clientY},Y.current=!1)},Vt=x=>{if(P(T(x.clientX,x.clientY)),C.current&&o.original){const N=x.clientX-C.current.x,U=x.clientY-C.current.y;Math.sqrt(N*N+U*U)>M&&!v&&(Y.current=!0,A(C.current.x,C.current.y))}v&&V(x.clientX,x.clientY)},Kt=x=>{C.current&&!Y.current&&T(x.clientX,x.clientY)&&rt(),_()},Ft=()=>{_(),P(!1)},qt=x=>{if(x.touches.length===1){const N=x.touches[0];T(N.clientX,N.clientY)&&(C.current={x:N.clientX,y:N.clientY},Y.current=!1)}},Zt=x=>{if(x.touches.length===1&&C.current&&o.original){const N=x.touches[0],U=N.clientX-C.current.x,z=N.clientY-C.current.y;Math.sqrt(U*U+z*z)>M&&!v&&(Y.current=!0,A(C.current.x,C.current.y)),v&&V(N.clientX,N.clientY)}},Jt=()=>{C.current&&!Y.current&&T(C.current.x,C.current.y)&&rt(),_()},ot=g.useRef(!1);g.useEffect(()=>{ot.current=v},[v]),g.useEffect(()=>{const x=d.current;if(!x)return;const N=U=>{ot.current&&U.preventDefault()};return x.addEventListener("touchmove",N,{passive:!1}),()=>{x.removeEventListener("touchmove",N)}},[]);const Qt=u==="front"&&o.original,en=H.width/H.height;return c.jsxs("div",{className:"space-y-2",children:[c.jsxs("div",{className:"flex justify-between items-center mb-6",children:[c.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[c.jsx("button",{className:`join-item btn btn-md ${u==="front"?"btn-primary":"btn-ghost"}`,onClick:()=>u!=="front"&&b(),children:m.preview.front}),c.jsx("button",{className:`join-item btn btn-md ${u==="back"?"btn-primary":"btn-ghost"}`,onClick:()=>u!=="back"&&b(),children:m.preview.back})]}),c.jsxs("button",{className:"btn btn-ghost btn-md",onClick:b,children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.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"})}),c.jsx("span",{className:"hidden sm:inline",children:m.preview.flip})]})]}),c.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:en,perspective:"1500px"},children:[ke&&c.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),c.jsxs("div",{ref:d,className:`relative w-full h-full shadow-lg ${L&&Qt?v?"cursor-grabbing":"cursor-grab":""} ${ke?"opacity-0":"opacity-100"} transition-opacity duration-300`,style:{transformStyle:"preserve-3d",transition:"transform 0.6s ease-in-out, opacity 0.3s ease-in-out",transform:I?"rotateY(180deg)":"rotateY(0deg)"},onMouseDown:Gt,onMouseMove:Vt,onMouseUp:Kt,onMouseLeave:Ft,onTouchStart:qt,onTouchMove:Zt,onTouchEnd:Jt,onDragOver:x=>{x.preventDefault(),u==="front"&&j(!0)},onDragLeave:x=>{x.preventDefault(),j(!1)},onDrop:x=>{if(x.preventDefault(),j(!1),u==="front"&&t){const N=x.dataTransfer.files[0];N&&N.type.startsWith("image/")&&t(N)}},children:[c.jsx("canvas",{ref:y,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),c.jsx("canvas",{ref:k,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),u==="front"&&!o.original&&c.jsx("div",{className:`absolute flex flex-col items-center justify-center transition-colors duration-300 ease-in-out pointer-events-none ${D?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(O.front.portrait.x-O.front.portrait.radiusX)/H.width*100}%`,top:`${(O.front.portrait.y-O.front.portrait.radiusY)/H.height*100}%`,width:`${O.front.portrait.radiusX*2/H.width*100}%`,height:`${O.front.portrait.radiusY*2/H.height*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},children:c.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 flex flex-col items-center gap-0.5 sm:gap-1 h-auto py-1.5 px-2.5 sm:py-3 sm:px-4 bg-base-100/20 hover:bg-base-100/30",children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-7 h-6 sm:w-10 sm:h-9 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"8",r:"4"}),c.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),c.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
|
|
14
|
+
`}),!t.original&&!t.rawImage?c.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${g?"border-primary bg-primary/10 pointer-events-none":I?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:be,onDragOver:V,onDragLeave:ee,onClick:F,children:[c.jsx("input",{ref:T,type:"file",accept:"image/*",className:"hidden",onChange:xe}),g?c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),c.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt ...":"Removing background ..."})]}):c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.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:c.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"})}),c.jsx("p",{className:"font-medium",children:b.form.portrait.upload}),c.jsx("p",{className:"text-sm text-base-content/60",children:b.form.portrait.dragDrop})]})]}):c.jsxs("div",{className:"flex flex-col space-y-4",children:[c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:b.form.portrait.zoom}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),c.jsx(Ie,{min:.5,max:2,step:.05,value:t.zoom,onChange:a,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",f&&c.jsx("span",{className:"loading loading-spinner loading-xs"})]}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(O*100),"%"]})]}),c.jsx(Ie,{min:0,max:1,step:.05,value:O,onChange:Ue,className:"range range-secondary range-sm",disabled:f||!L})]})]}),Y?c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(Z*100),"%"]})]}),c.jsx(Ie,{min:0,max:1,step:.05,value:Z,onChange:Ee,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(H*100),"%"]})]}),c.jsx(Ie,{min:0,max:1,step:.05,value:H,onChange:ve,className:"range range-primary range-sm",disabled:Z===0})]})]}):c.jsx("div",{className:"flex justify-center",children:c.jsxs("button",{className:"btn btn-ghost btn gap-2 text-base-content/70",onClick:ye,disabled:g||!L,children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:[c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z",style:g?{animation:"sparkle1 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456z",style:g?{animation:"sparkle2 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z",style:g?{animation:"sparkle3 2.4s ease-in-out infinite"}:void 0})]}),g?e==="de"?"Hintergrund wird entfernt ...":"Removing background ...":e==="de"?"Hintergrund entfernen":"Remove background",!g&&!k&&c.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})}),v&&c.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[c.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:c.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"})}),c.jsx("span",{children:v})]})]}),c.jsx(Yt,{isOpen:R,onClose:()=>P(!1),onSubmit:Te})]})}function $n(){const e=y(s=>s.appLanguage),t=y(s=>s.voucherConfig.language),n=y(s=>s.voucherConfig.hours);y(s=>s.voucherConfig.templateHue);const a=y(s=>s.setBillLanguage),r=y(s=>s.setHours);y(s=>s.setTemplateHue);const l=re(e),o=[1,5,10];return c.jsxs("div",{className:"space-y-4",children:[c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.billLanguage}),c.jsxs("div",{className:"join border border-base-300 rounded-lg shadow",children:[c.jsx("button",{className:`join-item btn btn-md ${t==="de"?"btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:l.form.voucher.billLanguageGerman}),c.jsx("button",{className:`join-item btn btn-md ${t==="en"?"btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:l.form.voucher.billLanguageEnglish})]})]})}),c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.hours}),c.jsx("div",{className:"join border border-base-300 rounded-lg shadow",children:o.map(s=>c.jsxs("button",{className:`join-item btn btn-md ${n===s?"btn-primary":"btn-ghost"}`,onClick:()=>r(s),children:[s,c.jsxs("span",{className:"hidden sm:inline",children:[" ",s===1?l.form.voucher.hourLabel:l.form.voucher.hoursLabel]})]},s))})]})}),!1]})}function at(e,t){return{front:"",back:"",width:ne,height:ae}}const He={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},ue=He,de=He;function rt(e){return He}const Qe=.75;function Xn(e){const t=rt(),n=Qe,a=r=>({portrait:{x:r.portrait.x*n,y:r.portrait.y*n,radiusX:r.portrait.radiusX*n,radiusY:r.portrait.radiusY*n},namePlate:{x:r.namePlate.x*n,y:r.namePlate.y*n,fontSize:r.namePlate.fontSize*n,maxWidth:r.namePlate.maxWidth?r.namePlate.maxWidth*n:void 0,lineHeight:r.namePlate.lineHeight?r.namePlate.lineHeight*n:void 0,align:r.namePlate.align},contactInfo:r.contactInfo?{x:r.contactInfo.x*n,y:r.contactInfo.y*n,fontSize:r.contactInfo.fontSize*n,maxWidth:r.contactInfo.maxWidth?r.contactInfo.maxWidth*n:void 0,lineHeight:r.contactInfo.lineHeight?r.contactInfo.lineHeight*n:void 0,align:r.contactInfo.align}:void 0,description:r.description?{x:r.description.x*n,y:r.description.y*n,fontSize:r.description.fontSize*n,maxWidth:r.description.maxWidth?r.description.maxWidth*n:void 0,lineHeight:r.description.lineHeight?r.description.lineHeight*n:void 0,align:r.description.align}:void 0,signature:r.signature?{x:r.signature.x*n,y:r.signature.y*n,width:r.signature.width*n,height:r.signature.height*n,labelFontSize:r.signature.labelFontSize*n}:void 0});return{front:a(t.front),back:a(t.back)}}function Gn(e,t){const n=at();return{...n,width:Math.round(n.width*Qe),height:Math.round(n.height*Qe)}}function Vn(e,t){const[n,a]=d.useState(e);return d.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Kn({onPortraitClick:e,onFileDrop:t}={}){const n=y(w=>w.appLanguage),a=y(w=>w.voucherConfig.language),r=y(w=>w.voucherConfig.hours),l=y(w=>w.voucherConfig.description),o=y(w=>w.voucherConfig.templateHue),s=y(w=>w.personalInfo),i=y(w=>w.portrait),u=y(w=>w.currentSide),h=y(w=>w.flipSide),x=y(w=>w.setPortraitPan),f=Vn(o,150),g=re(n),v=d.useRef(null),k=d.useRef(null),m=d.useRef(null),[b,T]=d.useState(!1),[I,E]=d.useState(!1),[R,P]=d.useState(!1),[D,j]=d.useState(!1),L=d.useRef(null),C=d.useRef(null),Y=d.useRef(!1),Z=d.useRef(0),H=Gn(),O=Xn(),J=i.useEnhanced&&i.enhanced?i.enhanced:i.original||i.rawImage,oe=nt(a,r,l),[Q,be]=d.useState(""),[V,ee]=d.useState(""),[F,xe]=d.useState(""),[te,ke]=d.useState(""),[K,we]=d.useState(""),[ye,Ue]=d.useState(""),[Te,Ee]=d.useState(!0);d.useEffect(()=>{let w=!0;Ee(!0);async function N(){const[U,$]=await Promise.all([Je(r,a,"front"),Je(r,a,"back")]);w&&(be(U.background),ee(U.badges),xe(U.frame),ke($.background),we($.badges),Ue($.frame),Ee(!1))}return N(),()=>{w=!1}},[r,a]),d.useEffect(()=>{!v.current||!Q||!V||!F||At(v.current,Q,V,F,J,s.name,O.front,H.width,H.height,i.zoom,i.panX,i.panY,f,r,a)},[H,Q,V,F,J,s.name,O,i.zoom,i.panX,i.panY,f,r,a]),d.useEffect(()=>{!k.current||!te||!K||!ye||Dt(k.current,te,K,ye,s.name,s.email,s.phone,oe,O.back,H.width,H.height,f,r,a)},[H,te,K,ye,s,oe,O,f,r,a]);const ve=()=>{T(!b),h()};d.useEffect(()=>{T(u==="back")},[u]);const p=d.useCallback((w,N)=>{if(!m.current||u!=="front")return!1;const U=m.current.getBoundingClientRect(),$=U.width/H.width,Oe=U.height/H.height,Se=(w-U.left)/$,Ye=(N-U.top)/Oe,{x:_e,y:We,radiusX:ze,radiusY:tn}=O.front.portrait,it=(Se-_e)/ze,st=(Ye-We)/tn;return it*it+st*st<=1},[u,H.width,H.height,O.front.portrait]),S=5,M=d.useCallback((w,N)=>{i.original&&(E(!0),L.current={x:w,y:N,panX:i.panX,panY:i.panY})},[i.original,i.panX,i.panY]),A=d.useCallback((w,N)=>{if(!I||!L.current||!m.current)return;const U=performance.now();if(U-Z.current<33)return;Z.current=U;const $=m.current.getBoundingClientRect(),Se=4/Math.max($.width,$.height)*i.zoom,Ye=(w-L.current.x)*Se,_e=(N-L.current.y)*Se,We=Math.max(-1,Math.min(1,L.current.panX+Ye)),ze=Math.max(-1,Math.min(1,L.current.panY+_e));x(We,ze)},[I,x,i.zoom]),z=d.useCallback(()=>{E(!1),L.current=null,C.current=null},[]),_=d.useCallback(()=>{e&&e()},[e]),Gt=w=>{p(w.clientX,w.clientY)&&(w.preventDefault(),C.current={x:w.clientX,y:w.clientY},Y.current=!1)},Vt=w=>{if(P(p(w.clientX,w.clientY)),C.current&&i.original){const N=w.clientX-C.current.x,U=w.clientY-C.current.y;Math.sqrt(N*N+U*U)>S&&!I&&(Y.current=!0,M(C.current.x,C.current.y))}I&&A(w.clientX,w.clientY)},Kt=w=>{C.current&&!Y.current&&p(w.clientX,w.clientY)&&_(),z()},Ft=()=>{z(),P(!1)},qt=w=>{if(w.touches.length===1){const N=w.touches[0];p(N.clientX,N.clientY)&&(C.current={x:N.clientX,y:N.clientY},Y.current=!1)}},Zt=w=>{if(w.touches.length===1&&C.current&&i.original){const N=w.touches[0],U=N.clientX-C.current.x,$=N.clientY-C.current.y;Math.sqrt(U*U+$*$)>S&&!I&&(Y.current=!0,M(C.current.x,C.current.y)),I&&A(N.clientX,N.clientY)}},Jt=()=>{C.current&&!Y.current&&p(C.current.x,C.current.y)&&_(),z()},ot=d.useRef(!1);d.useEffect(()=>{ot.current=I},[I]),d.useEffect(()=>{const w=m.current;if(!w)return;const N=U=>{ot.current&&U.preventDefault()};return w.addEventListener("touchmove",N,{passive:!1}),()=>{w.removeEventListener("touchmove",N)}},[]);const Qt=u==="front"&&i.original,en=H.width/H.height;return c.jsxs("div",{className:"space-y-2",children:[c.jsxs("div",{className:"flex justify-between items-center mb-6",children:[c.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[c.jsx("button",{className:`join-item btn btn-md ${u==="front"?"btn-primary":"btn-ghost"}`,onClick:()=>u!=="front"&&ve(),children:g.preview.front}),c.jsx("button",{className:`join-item btn btn-md ${u==="back"?"btn-primary":"btn-ghost"}`,onClick:()=>u!=="back"&&ve(),children:g.preview.back})]}),c.jsxs("button",{className:"btn btn-ghost btn-md",onClick:ve,children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.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"})}),c.jsx("span",{className:"hidden sm:inline",children:g.preview.flip})]})]}),c.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:en,perspective:"1500px"},children:[Te&&c.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),c.jsxs("div",{ref:m,className:`relative w-full h-full shadow-lg ${R&&Qt?I?"cursor-grabbing":"cursor-grab":""} ${Te?"opacity-0":"opacity-100"} transition-opacity duration-300`,style:{transformStyle:"preserve-3d",transition:"transform 0.6s ease-in-out, opacity 0.3s ease-in-out",transform:b?"rotateY(180deg)":"rotateY(0deg)"},onMouseDown:Gt,onMouseMove:Vt,onMouseUp:Kt,onMouseLeave:Ft,onTouchStart:qt,onTouchMove:Zt,onTouchEnd:Jt,onDragOver:w=>{w.preventDefault(),u==="front"&&j(!0)},onDragLeave:w=>{w.preventDefault(),j(!1)},onDrop:w=>{if(w.preventDefault(),j(!1),u==="front"&&t){const N=w.dataTransfer.files[0];N&&N.type.startsWith("image/")&&t(N)}},children:[c.jsx("canvas",{ref:v,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),c.jsx("canvas",{ref:k,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),u==="front"&&!i.original&&c.jsx("div",{className:`absolute flex flex-col items-center justify-center transition-colors duration-300 ease-in-out pointer-events-none ${D?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(O.front.portrait.x-O.front.portrait.radiusX)/H.width*100}%`,top:`${(O.front.portrait.y-O.front.portrait.radiusY)/H.height*100}%`,width:`${O.front.portrait.radiusX*2/H.width*100}%`,height:`${O.front.portrait.radiusY*2/H.height*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},children:c.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 flex flex-col items-center gap-0.5 sm:gap-1 h-auto py-1.5 px-2.5 sm:py-3 sm:px-4 bg-base-100/20 hover:bg-base-100/30",children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-7 h-6 sm:w-10 sm:h-9 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"8",r:"4"}),c.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),c.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
|
|
15
15
|
hochladen`:`Upload
|
|
16
|
-
photo`})]})})]})]})]})}function Fn(){const e=
|
|
16
|
+
photo`})]})})]})]})]})}function Fn(){const e=d.useRef(null),t=d.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const qn=`
|
|
17
17
|
// Translations for banner text
|
|
18
18
|
const TRANSLATIONS = {
|
|
19
19
|
de: {
|
|
@@ -488,4 +488,4 @@ self.onmessage = async (e) => {
|
|
|
488
488
|
});
|
|
489
489
|
}
|
|
490
490
|
};
|
|
491
|
-
`;let
|
|
491
|
+
`;let Ge=null,gt=null;function Zn(){if(!Ge){const e=new Blob([qn],{type:"application/javascript"});gt=URL.createObjectURL(e),Ge=new Worker(gt,{type:"module"})}return Ge}async function Ve(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function mt(e,t){const n=new Uint8Array(e);let a="";for(let r=0;r<n.length;r++)a+=String.fromCharCode(n[r]);return`data:${t};base64,${btoa(a)}`}async function _t(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:r,layout:l,portrait:o,portraitZoom:s=1,portraitPanX:i=0,portraitPanY:u=0,templateHue:h=160,name:x,email:f,phone:g,description:v,language:k="de",hours:m=1}=e,[b,T]=await Promise.all([Ve(t),Ve(n)]);let I=null;return o&&(I=await Ve(o)),new Promise((E,R)=>{const P=Zn(),D=setTimeout(()=>{P.removeEventListener("message",j),P.removeEventListener("error",L),URL.revokeObjectURL(b),URL.revokeObjectURL(T),I&&URL.revokeObjectURL(I),R(new Error("PDF generation timed out. Please try again."))},6e4),j=C=>{if(clearTimeout(D),P.removeEventListener("message",j),P.removeEventListener("error",L),URL.revokeObjectURL(b),URL.revokeObjectURL(T),I&&URL.revokeObjectURL(I),C.data.type==="success")try{const{frontImageData:Y,backImageData:Z,width:H,height:O}=C.data;if(!Y||!Z||!H||!O){R(new Error("Invalid response from worker"));return}const J=mt(Y,"image/jpeg"),oe=mt(Z,"image/jpeg"),Q=138.6,be=72.9,V=Q,ee=be,F=new rn.jsPDF({orientation:V>ee?"landscape":"portrait",unit:"mm",format:[V,ee]});F.addImage(J,"JPEG",0,0,V,ee),F.addPage([V,ee]),F.addImage(oe,"JPEG",0,0,V,ee);const xe=F.output("blob");E(xe)}catch(Y){R(Y)}else R(new Error(C.data.error))},L=C=>{P.removeEventListener("message",j),P.removeEventListener("error",L),URL.revokeObjectURL(b),URL.revokeObjectURL(T),I&&URL.revokeObjectURL(I),R(new Error(C.message))};P.addEventListener("message",j),P.addEventListener("error",L),P.postMessage({type:"generate",frontTemplateUrl:b,backTemplateUrl:T,portraitUrl:I,templateWidth:a,templateHeight:r,templateHue:h,portraitZoom:s,portraitPanX:i,portraitPanY:u,layout:{front:{portrait:l.front.portrait,namePlate:l.front.namePlate},back:{namePlate:l.back.namePlate,contactInfo:l.back.contactInfo,description:l.back.description,signature:l.back.signature}},name:x,email:f,phone:g,description:v,language:k,hours:m})})}function Wt(e,t){const n=URL.createObjectURL(e),a=document.createElement("a");a.href=n,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}async function zt(e){const t=await _t(e);Wt(t,e.filename)}function Jn(){const e=y(b=>b.appLanguage),t=y(b=>b.voucherConfig.language),n=y(b=>b.voucherConfig.hours),a=y(b=>b.voucherConfig.description),r=y(b=>b.voucherConfig.templateHue),l=y(b=>b.personalInfo),o=y(b=>b.portrait),s=y(b=>b.isExporting),i=y(b=>b.setIsExporting),u=re(e),h=at(),x=rt(),f=o.useEnhanced&&o.enhanced?o.enhanced:o.original||o.rawImage,g=nt(t,n,a),v=o.original!==null||o.rawImage!==null,k=l.name.trim().length>0&&l.email.trim().length>0&&l.phone.trim().length>0&&v,m=async()=>{if(!(!k||s)){i(!0);try{const[b,T]=await Promise.all([Ze(n,t,"front"),Ze(n,t,"back")]),I=`zeitgutschein-${n}h-${l.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await zt({frontTemplateSrc:b,backTemplateSrc:T,templateWidth:h.width,templateHeight:h.height,layout:x,portrait:f,portraitZoom:o.zoom,portraitPanX:o.panX,portraitPanY:o.panY,templateHue:r,name:l.name,email:l.email,phone:l.phone,description:g,filename:I,language:t,hours:n})}catch(b){console.error("PDF export failed:",b)}finally{i(!1)}}};return c.jsxs("button",{className:`btn btn-primary w-full btn-md ${k?"":"btn-disabled"}`,onClick:m,disabled:!k,"aria-busy":s,children:[s?c.jsx("span",{className:"loading loading-spinner loading-sm"}):c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.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"})}),u.export.button]})}function $t(){const e=y(a=>a.appLanguage),t=y(a=>a.setAppLanguage),n=a=>{t(a)};return c.jsxs("div",{className:"join",children:[c.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),c.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Qn(){const e=y(n=>n.appLanguage),t=re(e);return c.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg shrink-0",children:[c.jsx("div",{className:"navbar-start",children:c.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),c.jsx("div",{className:"navbar-center hidden sm:flex",children:c.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),c.jsx("div",{className:"navbar-end",children:c.jsx($t,{})})]})}const je="/",ea={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${je}templates/front_hdpi_de.jpg`,back:`${je}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:ue.front.portrait,name:ue.front.namePlate},back:{name:ue.back.namePlate,contactInfo:ue.back.contactInfo,description:ue.back.description}},languages:["de"]},ta={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${je}templates/front_ldpi_en.png`,back:`${je}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:de.front.portrait,name:de.front.namePlate},back:{name:de.back.namePlate,contactInfo:de.back.contactInfo,description:de.back.description}},languages:["en"]},ht=[ea,ta],Xt={async listTemplates(e){let t=[...ht];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=ht.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function na(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let Me=Xt;function aa(e){Me=e}function ra(){return Me}async function oa(e){return Me.listTemplates(e)}async function ia(e){return Me.getTemplate(e)}exports.ApiKeyModal=Yt;exports.BillPreview=Kn;exports.ExportButton=Jn;exports.Header=Qn;exports.LAYOUT_HDPI=ue;exports.LAYOUT_LDPI=de;exports.LanguageToggle=$t;exports.PREVIEW_HEIGHT=dn;exports.PREVIEW_WIDTH=un;exports.PersonalInfoForm=Nn;exports.PortraitUpload=zn;exports.TEMPLATE_HEIGHT=ae;exports.TEMPLATE_LAYOUT=He;exports.TEMPLATE_WIDTH=ne;exports.TouchSlider=Ie;exports.VoucherConfig=$n;exports.applyEngravingEffect=xt;exports.applyHueShift=yt;exports.clearCompositorCache=Rt;exports.clearHueShiftedCache=Lt;exports.composeTemplate=Pt;exports.composeTemplateFullRes=Ze;exports.downloadBlob=Wt;exports.drawContactInfo=jt;exports.drawMultilineText=Nt;exports.drawOvalPortrait=Bt;exports.drawTemplate=ce;exports.drawText=tt;exports.enhancePortrait=_n;exports.exportBillAsPDF=zt;exports.formatDescription=nt;exports.generateBillPDF=_t;exports.getApiKey=De;exports.getDefaultTemplateId=na;exports.getLayout=rt;exports.getRemoveBackgroundEndpoint=Hn;exports.getTemplate=at;exports.getTemplateById=ia;exports.getTemplateDimensions=fn;exports.getTemplateLayers=Je;exports.getTemplateProvider=ra;exports.hasApiKey=Le;exports.hasCustomEndpoint=Mn;exports.listTemplates=oa;exports.loadImage=B;exports.preloadAllTemplates=pn;exports.preloadBaseImages=gn;exports.removeBackground=Ot;exports.renderBackSide=Dt;exports.renderFrontSide=At;exports.resizeImage=pt;exports.setApiKey=Ut;exports.setRemoveBackgroundEndpoint=Dn;exports.setTemplateProvider=aa;exports.staticTemplateProvider=Xt;exports.t=re;exports.useBillCanvasRefs=Fn;exports.useBillStore=y;
|