@antontranelis/money-printer 1.0.64 → 1.0.65
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 +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +648 -640
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),g=require("react"),Kt=require("zustand"),qt=require("zustand/middleware"),Gt=require("jspdf");var he=typeof document<"u"?document.currentScript:null;const Zt=1024,ot=1200,de=new Map;let X=null,it=null;function Ze(e,t){return X||(X=document.createElement("canvas"),it=X.getContext("2d",{willReadFrequently:!0})),(X.width!==e||X.height!==t)&&(X.width=e,X.height=t),it}function be(e){const t=de.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(de.size>10){const l=de.keys().next().value;l&&de.delete(l)}de.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function Jt(){de.clear()}async function gt(e,t=Zt){const n=await be(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,l=Math.round(n.width*r),s=Math.round(n.height*r),i=document.createElement("canvas"),o=i.getContext("2d");if(!o)throw new Error("Failed to get canvas context");return i.width=l,i.height=s,o.drawImage(n,0,0,l,s),i.toDataURL("image/jpeg",.9)}async function Qt(e){const t=await be(e),n=Math.max(t.width,t.height);if(n<=ot){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=ot/n,r=Math.round(t.width*a),l=Math.round(t.height*a),s=document.createElement("canvas"),i=s.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return s.width=r,s.height=l,i.drawImage(t,0,0,r,l),s.toDataURL("image/png")}async function Fe(e,t,n,a=0){const[r,l]=await Promise.all([be(e),be(t)]),s=Ze(r.width,r.height);if(s.clearRect(0,0,r.width,r.height),n>0){const i=a*20;s.save(),s.globalAlpha=n,i>0&&(s.filter=`blur(${i}px)`),s.drawImage(l,0,0,r.width,r.height),s.restore()}return s.drawImage(r,0,0),X.toDataURL("image/png")}async function mt(e,t=.5,n=40){const a=await be(e),r=Ze(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),s=l.data,i=new Uint32Array(s.buffer),o=1+t*.8,u=1-t,h=n%360/360;for(let x=0;x<i.length;x++){const f=i[x],p=f&255,v=f>>8&255,w=f>>16&255,d=f>>24&255;if(d===0)continue;let k=(((77*p+150*v+29*w>>8)/255-.5)*o+.5)*255;k<0?k=0:k>255&&(k=255);const T=k/255,E=.12,[S,N,j]=ht(h,E,T),D=p*u+S*t|0,L=v*u+N*t|0,R=w*u+j*t|0;i[x]=d<<24|R<<16|L<<8|D}return r.putImageData(l,0,0),X.toDataURL("image/png")}function en(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 s=0,i=0;if(a!==r){const o=a-r;switch(i=l>.5?o/(2-a-r):o/(a+r),a){case e:s=((t-n)/o+(t<n?6:0))/6;break;case t:s=((n-e)/o+2)/6;break;case n:s=((e-t)/o+4)/6;break}}return[s,i,l]}function ht(e,t,n){if(t===0){const s=Math.round(n*255);return[s,s,s]}const a=(s,i,o)=>(o<0&&(o+=1),o>1&&(o-=1),o<1/6?s+(i-s)*6*o:o<1/2?i:o<2/3?s+(i-s)*(2/3-o)*6:s),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 tn=29,nn=5;async function pt(e,t){if(Math.abs(t-tn)<=nn)return e;const n=await be(e),a=Ze(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,s=new Uint32Array(l.buffer),i=t%360/360,o=20/360,u=45/360,h=s.length;for(let x=0;x<h;x++){const f=s[x],p=f&255,v=f>>8&255,w=f>>16&255,d=f>>24&255;if(d===0)continue;const[I,k,T]=en(p,v,w);if(k<.08||I<o||I>u)continue;const E=i,S=Math.min(k,.05),[N,j,D]=ht(E,S,T);s[x]=d<<24|D<<16|j<<8|N}return a.putImageData(r,0,0),X.toDataURL("image/png")}const Le="money-generator-portrait";async function an(e){try{if(localStorage.removeItem(Le),!e)return;const t=await Qt(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)}}function rn(){try{return localStorage.getItem(Le)}catch{return null}}function on(){try{localStorage.removeItem(Le)}catch{}}function sn(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Ce=sn(),st={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},y=Kt.create()(qt.persist(e=>({...st,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>(an(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)=>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=>e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}})),reset:()=>(on(),e(st))}),{name:"money-generator-storage",migrate:e=>{const t=e;return t!=null&&t.voucherConfig&&(t.voucherConfig.templateHue=29,t.voucherConfig.hours=1,t.voucherConfig.language=Ce),t&&(t.appLanguage=Ce),t},version:1,partialize:e=>({personalInfo:e.personalInfo,voucherConfig:{...e.voucherConfig,templateHue:29},appLanguage:e.appLanguage,portrait:{original:null,enhanced:null,useEnhanced:e.portrait.useEnhanced,zoom:e.portrait.zoom,panX:e.portrait.panX,panY:e.portrait.panY,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:e.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));if(typeof window<"u"){const e=rn();e&&setTimeout(()=>{const t=y.getState();t.portrait.original||y.setState({portrait:{...t.portrait,original:e}})},0)}const cn={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"}}},un={de:cn,en:ln};function te(e){return un[e]}function Je(e,t,n){if(n&&n.trim())return n;const a=te(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function dn(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function gn(e){return e.replace(/\D/g,"").length>=6}function mn({focusField:e,onFocused:t}={}){const n=y(w=>w.appLanguage),a=y(w=>w.personalInfo),r=y(w=>w.setPersonalInfo),l=te(n),[s,i]=g.useState(!1),[o,u]=g.useState(!1),h=s&&a.email.trim()&&!dn(a.email),x=o&&a.phone.trim()&&!gn(a.phone),f=g.useRef(null),p=g.useRef(null),v=g.useRef(null);return g.useEffect(()=>{if(e){const w=e==="name"?f:e==="email"?p:v;setTimeout(()=>{var d,I;(d=w.current)==null||d.click(),(I=w.current)==null||I.focus(),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:l.form.personalInfo.name})}),c.jsx("input",{ref:f,type:"text",name:"name",autoComplete:"name",placeholder:l.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:a.name,onChange:w=>r({name:w.target.value})})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:l.form.personalInfo.email})}),c.jsx("input",{ref:p,type:"email",name:"email",autoComplete:"email",placeholder:l.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${h?"input-error":""}`,value:a.email,onChange:w=>r({email:w.target.value}),onBlur:()=>i(!0)}),h&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:n==="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:l.form.personalInfo.phone})}),c.jsx("input",{ref:v,type:"tel",name:"phone",autoComplete:"tel",placeholder:l.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${x?"input-error":""}`,value:a.phone,onChange:w=>r({phone:w.target.value}),onBlur:()=>u(!0)}),x&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:n==="de"?"Bitte gib eine gültige Telefonnummer ein":"Please enter a valid phone number"})})]})]})}const We={},hn="https://api.stability.ai/v1/generation",pn="https://api.stability.ai/v2beta/stable-image/edit/remove-background",ft="stability_api_key";let xe=null;function fn(e){xe=e}function bn(){return xe}function xn(){return xe!==null}const wn={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"},ct=[{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 yn(e,t){const n=e/t;let a=ct[0],r=1/0;for(const l of ct){const s=l.width/l.height,i=Math.abs(n-s);i<r&&(r=i,a=l)}return a}function vn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=yn(a.width,a.height),l=document.createElement("canvas");l.width=r.width,l.height=r.height;const s=l.getContext("2d");if(!s){n(new Error("Failed to get canvas context"));return}const i=a.width/a.height,o=r.width/r.height;let u=0,h=0,x=a.width,f=a.height;i>o?(x=a.height*o,u=(a.width-x)/2):(f=a.width/o,h=(a.height-f)/2),s.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 bt(e){var s;const t=e.split(","),n=((s=t[0].match(/:(.*?);/))==null?void 0:s[1])||"image/png",a=atob(t[1]),r=a.length,l=new Uint8Array(r);for(let i=0;i<r;i++)l[i]=a.charCodeAt(i);return new Blob([l],{type:n})}function je(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:he&&he.tagName.toUpperCase()==="SCRIPT"&&he.src||new URL("index.cjs",document.baseURI).href}<"u"&&(We==null?void 0:We.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(ft):null}function xt(e){localStorage.setItem(ft,e)}function Pe(){return xe?!0:je()!==null}async function kn(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 vn(n),s=bt(l),i=new FormData;i.append("init_image",s,"portrait.png"),i.append("init_image_mode","IMAGE_STRENGTH"),i.append("image_strength",String(1-r)),i.append("text_prompts[0][text]",wn[a]),i.append("text_prompts[0][weight]","1"),i.append("cfg_scale","7"),i.append("samples","1"),i.append("steps","30");const u=await fetch(`${hn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:i});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 wt(e){if(xe){const s=await fetch(xe,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!s.ok){const o=await s.json().catch(()=>({}));throw new Error(o.error||`API error: ${s.status}`)}return(await s.json()).imageDataUrl}const t=je();if(!t)throw new Error("No Stability AI API key configured");const n=bt(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(pn,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const s=await r.text();throw console.error("Stability AI remove background error:",s),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((s,i)=>{const o=new FileReader;o.onload=()=>s(o.result),o.onerror=()=>i(new Error("Failed to read result")),o.readAsDataURL(l)})}function In(){const[e,t]=g.useState(!1),[n,a]=g.useState(!1),[r,l]=g.useState(null),[s,i]=g.useState(()=>Pe());g.useEffect(()=>{i(Pe());const f=setTimeout(()=>{i(Pe())},150);return()=>clearTimeout(f)},[]);const o=g.useCallback(()=>l(null),[]),u=g.useCallback(f=>{xt(f),i(!0),l(null)},[]),h=g.useCallback(async(f,p=.5,v=40)=>{t(!0),l(null);try{return await mt(f,p,v)}catch(w){const d=w instanceof Error?w.message:"Enhancement failed";throw l(d),w}finally{t(!1)}},[]),x=g.useCallback(async f=>{a(!0),l(null);try{return await wt(f)}catch(p){const v=p instanceof Error?p.message:"Background removal failed";throw l(v),p}finally{a(!1)}},[]);return{enhance:h,removeBg:x,isEnhancing:e,isRemovingBg:n,error:r,hasKey:s,setApiKey:u,clearError:o}}function yt({isOpen:e,onClose:t,onSubmit:n}){const a=y(u=>u.appLanguage),[r,l]=g.useState("");if(!e)return null;const s=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:s,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 ve({min:e,max:t,step:n,value:a,onChange:r,className:l="",disabled:s=!1}){const i=g.useRef(null),o=g.useRef(null),u=g.useRef(!1),[h,x]=g.useState(!1),f=(a-e)/(t-e)*100,p=g.useCallback(k=>{if(!i.current)return a;const T=i.current.getBoundingClientRect(),E=Math.max(0,Math.min(1,(k-T.left)/T.width)),S=t-e,N=e+E*S,j=Math.round(N/n)*n;return Math.max(e,Math.min(t,j))},[e,t,n,a]),v=g.useCallback(k=>{if(s)return;const T=k.touches[0];o.current={x:T.clientX,y:T.clientY,value:a,decided:!1},u.current=!1},[a,s]),w=g.useCallback(k=>{if(s||!o.current)return;const T=k.touches[0],E=Math.abs(T.clientX-o.current.x),S=Math.abs(T.clientY-o.current.y);if(!o.current.decided){if(E<8&&S<8)return;if(o.current.decided=!0,S>E){o.current=null;return}u.current=!0,x(!0)}if(u.current){const N=p(T.clientX);N!==a&&r(N)}},[s,p,r,a]),d=g.useCallback(k=>{if(o.current&&!o.current.decided){const T=k.changedTouches[0];if(T){const E=p(T.clientX);E!==a&&r(E)}}o.current=null,u.current=!1,x(!1)},[p,r,a]);g.useEffect(()=>{const k=i.current;if(!k)return;const T=E=>{u.current&&E.preventDefault()};return k.addEventListener("touchmove",T,{passive:!1}),()=>{k.removeEventListener("touchmove",T)}},[]);const I=g.useCallback(k=>{if(s)return;const T=p(k.clientX);r(T),x(!0);const E=N=>{const j=p(N.clientX);r(j)},S=()=>{x(!1),document.removeEventListener("mousemove",E),document.removeEventListener("mouseup",S)};document.addEventListener("mousemove",E),document.addEventListener("mouseup",S)},[s,p,r]);return c.jsxs("div",{ref:i,className:`relative h-6 flex items-center cursor-pointer ${s?"opacity-50 cursor-not-allowed":""}`,onTouchStart:v,onTouchMove:w,onTouchEnd:d,onMouseDown:I,children:[c.jsx("div",{className:"absolute inset-x-0 h-2 bg-base-300 rounded-full"}),c.jsx("div",{className:`absolute left-0 h-2 rounded-full transition-colors ${l.includes("range-primary")?"bg-primary":l.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{width:`${f}%`}}),c.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transform -translate-x-1/2 transition-transform ${h?"scale-125":""} ${l.includes("range-primary")?"border-primary":l.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:`${f}%`}})]})}function Tn(){const e=y(b=>b.appLanguage),t=y(b=>b.portrait),n=y(b=>b.setPortrait),a=y(b=>b.setPortraitZoom),r=y(b=>b.setPortraitPan),l=y(b=>b.setPortraitRawImage),s=y(b=>b.setPortraitBgRemoved),i=y(b=>b.setPortraitBgOpacity),o=y(b=>b.setPortraitBgBlur),u=y(b=>b.setPortraitEngravingIntensity),{enhance:h,removeBg:x,isEnhancing:f,isRemovingBg:p,error:v,hasKey:w,setApiKey:d}=In(),I=te(e),k=g.useRef(null),[T,E]=g.useState(!1),[S,N]=g.useState(!1),j=g.useRef(null),D=g.useRef(null),L=t.rawImage,R=t.bgRemovedImage,M=t.bgRemoved,V=t.bgOpacity,G=t.bgBlur,Z=t.engravingIntensity;g.useEffect(()=>{t.original&&!t.rawImage&&l(t.original)},[t.original,t.rawImage,l]),g.useEffect(()=>()=>{j.current&&clearTimeout(j.current),D.current&&clearTimeout(D.current)},[]);const J=y(b=>b.voucherConfig.templateHue),K=g.useRef(J),O=g.useCallback(async b=>{if(!b.type.startsWith("image/"))return;const P=new FileReader;P.onload=async A=>{var F;const B=(F=A.target)==null?void 0:F.result,_=await gt(B);l(_),n(_),s(!1,null),u(0)},P.readAsDataURL(b)},[n,l,s,u]),$=g.useCallback(b=>{b.preventDefault(),E(!1);const P=b.dataTransfer.files[0];P&&O(P)},[O]),Q=g.useCallback(b=>{b.preventDefault(),E(!0)},[]),re=g.useCallback(b=>{b.preventDefault(),E(!1)},[]),De=()=>{var b;(b=k.current)==null||b.click()},we=b=>{var A;const P=(A=b.target.files)==null?void 0:A[0];P&&O(P)},oe=g.useCallback(async(b,P,A)=>{try{return await h(b,P,A)}catch(B){return console.error("Enhancement failed:",B),b}},[h]),le=g.useCallback(async b=>{try{const P=await x(b);return s(!0,P),P}catch(P){return console.error("Background removal failed:",P),b}},[x,s]),ie=g.useCallback(async()=>{const b=y.getState(),P=b.portrait,A=b.voucherConfig.templateHue;if(!P.rawImage)return;let B;P.bgRemoved&&P.bgRemovedImage?B=await Fe(P.bgRemovedImage,P.rawImage,P.bgOpacity,P.bgBlur):B=P.rawImage,P.engravingIntensity>0&&(B=await oe(B,P.engravingIntensity,A)),n(B)},[oe,n]);g.useEffect(()=>{if(K.current===J)return;K.current=J;const b=y.getState().portrait;b.engravingIntensity>0&&b.rawImage&&(j.current&&clearTimeout(j.current),j.current=setTimeout(ie,150))},[J,ie]);const ke=async()=>{if(!L)return;if(!M&&!w){N(!0);return}if(!M){const P=await le(L),A=y.getState(),B=A.portrait,_=A.voucherConfig.templateHue;let F=await Fe(P,L,B.bgOpacity,B.bgBlur);B.engravingIntensity>0&&(F=await oe(F,B.engravingIntensity,_)),n(F)}else{s(!1,null);const P=y.getState(),A=P.portrait.engravingIntensity,B=P.voucherConfig.templateHue;if(A>0){const _=await oe(L,A,B);n(_)}else n(L)}},Ie=b=>{u(b),j.current&&clearTimeout(j.current),L&&(j.current=setTimeout(ie,150))},ye=async b=>{if(d(b),!L)return;const P=await le(L),A=y.getState(),B=A.portrait,_=A.voucherConfig.templateHue;let F=await Fe(P,L,B.bgOpacity,B.bgBlur);B.engravingIntensity>0&&(F=await oe(F,B.engravingIntensity,_)),n(F)},q=b=>{i(b),D.current&&clearTimeout(D.current),!(!L||!R)&&(D.current=setTimeout(ie,150))},Te=b=>{o(b),D.current&&clearTimeout(D.current),!(!L||!R)&&(D.current=setTimeout(ie,150))},Ee=()=>{n(null),l(null),s(!1,null),i(0),o(0),u(0),Jt()};return c.jsxs("div",{className:"space-y-4",children:[t.original?c.jsxs("div",{className:"flex flex-col space-y-4",children:[c.jsxs("div",{className:"flex justify-between items-center w-full",children:[c.jsx("span",{className:"text-sm font-medium text-base-content/70",children:e==="de"?"Portrait-Einstellungen":"Portrait settings"}),c.jsxs("button",{className:"btn btn-xs btn-ghost text-error",onClick:Ee,children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"})}),e==="de"?"Foto entfernen":"Remove photo"]})]}),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(ve,{min:.5,max:2,step:.05,value:t.zoom,onChange:b=>{a(b),b<=1&&(t.panX!==0||t.panY!==0)&&r(0,0)},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(Z*100),"%"]})]}),c.jsx(ve,{min:0,max:1,step:.05,value:Z,onChange:Ie,className:"range range-secondary range-sm",disabled:f||!L})]})]}),M?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(V*100),"%"]})]}),c.jsx(ve,{min:0,max:1,step:.05,value:V,onChange:q,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(G*100),"%"]})]}),c.jsx(ve,{min:0,max:1,step:.05,value:G,onChange:Te,className:"range range-primary range-sm",disabled:V===0})]})]}):c.jsx("div",{className:"form-control w-fit",children:c.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[c.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${p?"opacity-50":""}`,checked:M,onChange:ke,disabled:p||!L}),c.jsxs("span",{className:"label-text flex items-center gap-2",children:[p?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!w&&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.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${p?"border-primary bg-primary/10 pointer-events-none":T?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:$,onDragOver:Q,onDragLeave:re,onClick:De,children:[c.jsx("input",{ref:k,type:"file",accept:"image/*",className:"hidden",onChange:we}),p?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:S,onClose:()=>N(!1),onSubmit:ye})]})}function En(){const e=y(i=>i.appLanguage),t=y(i=>i.voucherConfig.language),n=y(i=>i.voucherConfig.hours);y(i=>i.voucherConfig.templateHue);const a=y(i=>i.setBillLanguage),r=y(i=>i.setHours);y(i=>i.setTemplateHue);const l=te(e),s=[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-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:l.form.voucher.billLanguageGerman}),c.jsx("button",{className:`join-item btn btn-md ${t==="en"?"btn-active 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:s.map(i=>c.jsxs("button",{className:`join-item btn btn-md ${n===i?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(i),children:[i,c.jsxs("span",{className:"hidden sm:inline",children:[" ",i===1?l.form.voucher.hourLabel:l.form.voucher.hoursLabel]})]},i))})]})}),!1]})}const ze=new Map,ue=new Map;async function C(e){return ze.has(e)?ze.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{ze.set(e,a),t(a)},a.onerror=n,a.src=e})}function ce(e,t,n,a){e.drawImage(t,0,0,n,a)}async function vt(e,t,n,a){if(t>=155&&t<=165)return C(e);const r=`${e}:${t}:${n}x${a}`;if(ue.has(r))return C(ue.get(r));const l=await C(e),s=document.createElement("canvas");s.width=n,s.height=a;const i=s.getContext("2d");if(!i)throw new Error("Failed to get canvas context");i.drawImage(l,0,0,n,a);const o=s.toDataURL("image/png"),u=await pt(o,t);if(ue.size>20){const h=ue.keys().next().value;h&&ue.delete(h)}return ue.set(r,u),C(u)}function Pn(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 kt(e,t,n,a,r,l,s=1,i=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,x=r*2,f=l*2;let p,v;u>h?(v=f,p=f*u):(p=x,v=x/u),p*=s,v*=s;const w=Math.max(0,(p-x)/2),d=Math.max(0,(v-f)/2),I=n-p/2+i*w,k=a-v/2+o*d;e.drawImage(t,I,k,p,v),e.restore()}function Qe(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 It(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,s=t.split(" "),i=[];let o="";for(const x of s){const f=o?`${o} ${x}`:x;e.measureText(f).width>r&&o?(i.push(o),o=x):o=f}o&&i.push(o);const u=i.length*l;let h=n.y-u/2;for(const x of i)e.fillText(x,n.x,h),h+=l;e.restore()}function Tt(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 s=r.lineHeight||r.fontSize*1.8,i=[t,n,a].filter(Boolean),o=(i.length-1)*s;let u=r.y-o/2;for(const h of i)h&&(e.fillText(h,r.x,u),u+=s);e.restore()}function Sn(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 Et(e,t,n,a,r,l,s,i,o,u=1,h=0,x=0,f=0,p=1,v="de"){const w=e.getContext("2d");if(!w)return;const d=document.createElement("canvas");d.width=i,d.height=o;const I=d.getContext("2d");if(!I)return;I.clearRect(0,0,i,o);const k=await vt(t,f,i,o);ce(I,k,i,o);const T=await C(n);if(ce(I,T,i,o),r)try{const N=await C(r);kt(I,N,s.portrait.x,s.portrait.y,s.portrait.radiusX,s.portrait.radiusY,u,h,x)}catch(N){console.error("Failed to load portrait:",N)}else Pn(I,s.portrait.x,s.portrait.y,s.portrait.radiusX,s.portrait.radiusY,v);const E=await C(a);ce(I,E,i,o);const S=i/3633;jt(I,p,v,S),l&&Qe(I,l,s.namePlate),e.width=i,e.height=o,w.drawImage(d,0,0)}async function Pt(e,t,n,a,r,l,s,i,o,u,h,x=0,f=1,p="de"){const v=e.getContext("2d");if(!v)return;const w=document.createElement("canvas");w.width=u,w.height=h;const d=w.getContext("2d");if(!d)return;d.clearRect(0,0,u,h);const I=await vt(t,x,u,h);ce(d,I,u,h);const k=await C(n);ce(d,k,u,h);const T=await C(a);ce(d,T,u,h);const E=u/3633;if(jt(d,f,p,E),o.contactInfo&&(r||l||s)&&Tt(d,r,l,s,o.contactInfo),o.description&&i&&It(d,i,o.description),r&&Qe(d,r,o.namePlate),o.signature){const S=p==="de"?"Unterschrift":"Signature";Sn(d,o.signature,S)}e.width=u,e.height=h,v.drawImage(w,0,0)}const pe=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:he&&he.tagName.toUpperCase()==="SCRIPT"&&he.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",z={background:`${pe}templates/background.webp`,frontFrame:`${pe}templates/front_frame.webp`,backFrame:`${pe}templates/back_frame.webp`},fe={1:`${pe}templates/1.png`,5:`${pe}templates/5.png`,10:`${pe}templates/10.png`},St={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,Be=.5,Ln=Math.round(ne*Be),Cn=Math.round(ae*Be),Lt=320,Ct=335,W={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"}},Se=new Map,se=new Map,_e=new Map,Xe=new Map,Ve=new Map;function Rt(e,t,n,a,r,l,s){e.save(),e.font=`900 ${l}px "Times New Roman", Georgia, serif`,e.fillStyle=s,e.textAlign="center",e.textBaseline="middle";const o=e.measureText(t).width/r,u=-Math.PI/2-o/2,h=t.split(""),x=[];for(const p of h)x.push(e.measureText(p).width);let f=u;for(let p=0;p<h.length;p++){const v=h[p],w=x[p],d=f+w/2/r,I=n+r*Math.cos(d),k=a+r*Math.sin(d);e.save(),e.translate(I,k),e.rotate(d+Math.PI/2),e.fillText(v,0,0),e.restore(),f+=w/r}e.restore()}let Y={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function Rn(){const[e,t,n,a,r,l]=await Promise.all([C(z.background),C(z.frontFrame),C(z.backFrame),C(fe[1]),C(fe[5]),C(fe[10])]);Y={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:l}}}function jn(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 s=e<1?.8:.95;return r.toDataURL("image/jpeg",s)}function Bn(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 s=Lt*e,i=Ct*e,o=W.badges,u=(h,x)=>{const f=x/2,p=h.x*e-f,v=h.y*e-f;l.drawImage(t,p,v,x,x)};return u(o.topLeft,s),u(o.topRight,s),u(o.bottomLeft,i),u(o.bottomRight,i),r.toDataURL("image/png")}function jt(e,t,n,a=1){const r=St[n].banner[t];Rt(e,r,W.banner.centerX*a,W.banner.centerY*a,W.banner.radius*a,W.banner.fontSize*a,W.banner.color)}function Bt(e,t,n,a,r,l,s){const i=Math.round(ne*a),o=Math.round(ae*a),u=document.createElement("canvas");u.width=i,u.height=o;const h=u.getContext("2d");if(!h)throw new Error("Failed to get canvas context");h.drawImage(r,0,0,i,o);{const f=Lt*a,p=Ct*a,v=W.badges,w=(d,I)=>{const k=I/2,T=d.x*a-k,E=d.y*a-k;h.drawImage(s,T,E,I,I)};w(v.topLeft,f),w(v.topRight,f),w(v.bottomLeft,p),w(v.bottomRight,p)}if(h.drawImage(l,0,0,i,o),n==="front"){const f=St[t].banner[e];Rt(h,f,W.banner.centerX*a,W.banner.centerY*a,W.banner.radius*a,W.banner.fontSize*a,W.banner.color)}const x=a<1?.8:.95;return u.toDataURL("image/jpeg",x)}async function Nt(e,t,n){const a=`${e}-${t}-${n}`;if(Se.has(a))return Se.get(a);const r=Y.background||await C(z.background),l=n==="front"?Y.frontFrame||await C(z.frontFrame):Y.backFrame||await C(z.backFrame),s=Y.badges[e]||await C(fe[e]),i=Bt(e,t,n,Be,r,l,s);return Se.set(a,i),i}async function Ke(e,t,n){const a=`${e}-${t}-${n}`;if(se.has(a))return se.get(a);const r=Y.background||await C(z.background),l=n==="front"?Y.frontFrame||await C(z.frontFrame):Y.backFrame||await C(z.backFrame),s=Y.badges[e]||await C(fe[e]),i=Bt(e,t,n,1,r,l,s);if(se.size>4){const o=se.keys().next().value;o&&se.delete(o)}return se.set(a,i),i}function Nn(){return{width:ne,height:ae}}function Hn(){Se.clear(),se.clear(),_e.clear(),Xe.clear(),Ve.clear()}async function qe(e,t,n="front",a=Be){const r=`bg-${a}`;let l=_e.get(r);if(!l){const h=Y.background||await C(z.background);l=jn(a,h),_e.set(r,l)}const s=`badges-${e}-${a}`;let i=Xe.get(s);if(!i){const h=Y.badges[e]||await C(fe[e]);i=Bn(a,h),Xe.set(s,i)}const o=`${n}-${a}`;let u=Ve.get(o);if(!u){const h=n==="front"?Y.frontFrame||await C(z.frontFrame):Y.backFrame||await C(z.backFrame),x=Math.round(ne*a),f=Math.round(ae*a),p=document.createElement("canvas");p.width=x,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("Failed to get canvas context");v.drawImage(h,0,0,x,f),u=p.toDataURL("image/png"),Ve.set(o,u)}return{background:l,badges:i,frame:u}}async function Dn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const l of t)for(const s of n)a.push(Nt(r,l,s));await Promise.all(a)}function et(e,t){return{front:"",back:"",width:ne,height:ae}}const Ne={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}}},ge=Ne,me=Ne;function tt(e){return Ne}const Ge=.75;function Mn(e){const t=tt(),n=Ge,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 An(e,t){const n=et();return{...n,width:Math.round(n.width*Ge),height:Math.round(n.height*Ge)}}function Un(e,t){const[n,a]=g.useState(e);return g.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Yn({onPortraitClick:e,onFileDrop:t}={}){const n=y(m=>m.appLanguage),a=y(m=>m.voucherConfig.language),r=y(m=>m.voucherConfig.hours),l=y(m=>m.voucherConfig.description),s=y(m=>m.voucherConfig.templateHue),i=y(m=>m.personalInfo),o=y(m=>m.portrait),u=y(m=>m.currentSide),h=y(m=>m.flipSide),x=y(m=>m.setPortraitPan),f=Un(s,150),p=te(n),v=g.useRef(null),w=g.useRef(null),d=g.useRef(null),[I,k]=g.useState(!1),[T,E]=g.useState(!1),[S,N]=g.useState(!1),[j,D]=g.useState(!1),L=g.useRef(null),R=An(),M=Mn(),V=o.useEnhanced&&o.enhanced?o.enhanced:o.original,G=Je(a,r,l),[Z,J]=g.useState(""),[K,O]=g.useState(""),[$,Q]=g.useState(""),[re,De]=g.useState(""),[we,oe]=g.useState(""),[le,ie]=g.useState(""),[ke,Ie]=g.useState(!0);g.useEffect(()=>{let m=!0;Ie(!0);async function H(){const[U,ee]=await Promise.all([qe(r,a,"front"),qe(r,a,"back")]);m&&(J(U.background),O(U.badges),Q(U.frame),De(ee.background),oe(ee.badges),ie(ee.frame),Ie(!1))}return H(),()=>{m=!1}},[r,a]),g.useEffect(()=>{!v.current||!Z||!K||!$||Et(v.current,Z,K,$,V,i.name,M.front,R.width,R.height,o.zoom,o.panX,o.panY,f,r,a)},[R,Z,K,$,V,i.name,M,o.zoom,o.panX,o.panY,f,r,a]),g.useEffect(()=>{!w.current||!re||!we||!le||Pt(w.current,re,we,le,i.name,i.email,i.phone,G,M.back,R.width,R.height,f,r,a)},[R,re,we,le,i,G,M,f,r,a]);const ye=()=>{k(!I),h()};g.useEffect(()=>{k(u==="back")},[u]);const q=g.useCallback((m,H)=>{if(!d.current||u!=="front")return!1;const U=d.current.getBoundingClientRect(),ee=U.width/R.width,Me=U.height/R.height,Ae=(m-U.left)/ee,Ue=(H-U.top)/Me,{x:Ye,y:_t,radiusX:Xt,radiusY:Vt}=M.front.portrait,at=(Ae-Ye)/Xt,rt=(Ue-_t)/Vt;return at*at+rt*rt<=1},[u,R.width,R.height,M.front.portrait]),Te=g.useCallback((m,H)=>{!o.original||o.zoom<=1||!q(m,H)||(E(!0),L.current={x:m,y:H,panX:o.panX,panY:o.panY})},[o.original,o.zoom,o.panX,o.panY,q]),Ee=g.useCallback((m,H)=>{if(!T||!L.current||!d.current)return;const U=d.current.getBoundingClientRect(),ee=3/Math.max(U.width,U.height),Me=(m-L.current.x)*ee,Ae=(H-L.current.y)*ee,Ue=Math.max(-1,Math.min(1,L.current.panX+Me)),Ye=Math.max(-1,Math.min(1,L.current.panY+Ae));x(Ue,Ye)},[T,x]),b=g.useCallback(()=>{E(!1),L.current=null},[]),P=g.useCallback((m,H)=>{!o.original&&q(m,H)&&e&&e()},[o.original,q,e]),A=m=>{q(m.clientX,m.clientY)&&(m.preventDefault(),o.original&&o.zoom>1&&Te(m.clientX,m.clientY))},B=m=>{T||P(m.clientX,m.clientY)},_=m=>{Ee(m.clientX,m.clientY),N(q(m.clientX,m.clientY))},F=()=>b(),Yt=()=>{b(),N(!1)},Ft=m=>{if(m.touches.length===1){const H=m.touches[0];o.zoom>1&&q(H.clientX,H.clientY)&&Te(H.clientX,H.clientY)}},Wt=m=>{m.touches.length===1&&Ee(m.touches[0].clientX,m.touches[0].clientY)},zt=()=>b(),nt=g.useRef(!1);g.useEffect(()=>{nt.current=T},[T]),g.useEffect(()=>{const m=d.current;if(!m)return;const H=U=>{nt.current&&U.preventDefault()};return m.addEventListener("touchmove",H,{passive:!1}),()=>{m.removeEventListener("touchmove",H)}},[]);const Ot=u==="front"&&o.original&&o.zoom>1,$t=R.width/R.height;return c.jsxs("div",{className:"space-y-4",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-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="front"&&ye(),children:p.preview.front}),c.jsx("button",{className:`join-item btn btn-md ${u==="back"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="back"&&ye(),children:p.preview.back})]}),c.jsxs("button",{className:"btn btn-ghost btn-md",onClick:ye,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:p.preview.flip})]})]}),c.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:$t,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 ${S&&Ot?T?"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)"},onClick:B,onMouseDown:A,onMouseMove:_,onMouseUp:F,onMouseLeave:Yt,onTouchStart:Ft,onTouchMove:Wt,onTouchEnd:zt,children:[c.jsx("canvas",{ref:v,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),c.jsx("canvas",{ref:w,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),!o.original&&u==="front"&&(e||t)&&c.jsx("div",{className:`absolute flex flex-col items-center justify-center cursor-pointer transition-colors duration-300 ease-in-out ${j?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(M.front.portrait.x-M.front.portrait.radiusX)/R.width*100}%`,top:`${(M.front.portrait.y-M.front.portrait.radiusY)/R.height*100}%`,width:`${M.front.portrait.radiusX*2/R.width*100}%`,height:`${M.front.portrait.radiusY*2/R.height*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},onClick:m=>{m.stopPropagation(),e==null||e()},onDragOver:m=>{m.preventDefault(),m.stopPropagation(),D(!0)},onDragLeave:m=>{m.preventDefault(),m.stopPropagation(),D(!1)},onDrop:m=>{m.preventDefault(),m.stopPropagation(),D(!1);const H=m.dataTransfer.files[0];H&&H.type.startsWith("image/")&&t&&t(H)},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",onClick:m=>{m.stopPropagation(),e==null||e()},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
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),g=require("react"),Kt=require("zustand"),qt=require("zustand/middleware"),Gt=require("jspdf");var pe=typeof document<"u"?document.currentScript:null;const Ft=1024,rt=1200,ue=new Map;let V=null,ot=null;function Fe(e,t){return V||(V=document.createElement("canvas"),ot=V.getContext("2d",{willReadFrequently:!0})),(V.width!==e||V.height!==t)&&(V.width=e,V.height=t),ot}function be(e){const t=ue.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(ue.size>10){const c=ue.keys().next().value;c&&ue.delete(c)}ue.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function Zt(){ue.clear()}async function ut(e,t=Ft){const n=await be(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,c=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=c,s.height=i,o.drawImage(n,0,0,c,i),s.toDataURL("image/jpeg",.9)}async function Jt(e){const t=await be(e),n=Math.max(t.width,t.height);if(n<=rt){const o=document.createElement("canvas"),d=o.getContext("2d");if(!d)throw new Error("Failed to get canvas context");return o.width=t.width,o.height=t.height,d.drawImage(t,0,0),o.toDataURL("image/png")}const a=rt/n,r=Math.round(t.width*a),c=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=c,s.drawImage(t,0,0,r,c),i.toDataURL("image/png")}async function We(e,t,n,a=0){const[r,c]=await Promise.all([be(e),be(t)]),i=Fe(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(c,0,0,r.width,r.height),i.restore()}return i.drawImage(r,0,0),V.toDataURL("image/png")}async function gt(e,t=.5,n=40){const a=await be(e),r=Fe(a.width,a.height);r.clearRect(0,0,a.width,a.height),r.drawImage(a,0,0);const c=r.getImageData(0,0,a.width,a.height),i=c.data,s=new Uint32Array(i.buffer),o=1+t*.8,d=1-t,p=n%360/360;for(let x=0;x<s.length;x++){const f=s[x],h=f&255,v=f>>8&255,k=f>>16&255,u=f>>24&255;if(u===0)continue;let w=(((77*h+150*v+29*k>>8)/255-.5)*o+.5)*255;w<0?w=0:w>255&&(w=255);const T=w/255,E=.12,[S,N,B]=mt(p,E,T),D=h*d+S*t|0,L=v*d+N*t|0,j=k*d+B*t|0;s[x]=u<<24|j<<16|L<<8|D}return r.putImageData(c,0,0),V.toDataURL("image/png")}function Qt(e,t,n){e/=255,t/=255,n/=255;const a=Math.max(e,t,n),r=Math.min(e,t,n),c=(a+r)/2;let i=0,s=0;if(a!==r){const o=a-r;switch(s=c>.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,c]}function mt(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,c=2*n-r;return[Math.round(a(c,r,e+1/3)*255),Math.round(a(c,r,e)*255),Math.round(a(c,r,e-1/3)*255)]}const en=29,tn=5;async function pt(e,t){if(Math.abs(t-en)<=tn)return e;const n=await be(e),a=Fe(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),c=r.data,i=new Uint32Array(c.buffer),s=t%360/360,o=20/360,d=45/360,p=i.length;for(let x=0;x<p;x++){const f=i[x],h=f&255,v=f>>8&255,k=f>>16&255,u=f>>24&255;if(u===0)continue;const[I,w,T]=Qt(h,v,k);if(w<.08||I<o||I>d)continue;const E=s,S=Math.min(w,.05),[N,B,D]=mt(E,S,T);i[x]=u<<24|D<<16|B<<8|N}return a.putImageData(r,0,0),V.toDataURL("image/png")}const Le="money-generator-portrait";async function nn(e){try{if(localStorage.removeItem(Le),!e)return;const t=await Jt(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)}}function an(){try{return localStorage.getItem(Le)}catch{return null}}function rn(){try{localStorage.removeItem(Le)}catch{}}function on(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Re=on(),it={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Re,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:Re},y=Kt.create()(qt.persist(e=>({...it,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>(nn(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)=>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=>e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}})),reset:()=>(rn(),e(it))}),{name:"money-generator-storage",migrate:e=>{const t=e;return t!=null&&t.voucherConfig&&(t.voucherConfig.templateHue=29,t.voucherConfig.hours=1,t.voucherConfig.language=Re),t&&(t.appLanguage=Re),t},version:1,partialize:e=>({personalInfo:e.personalInfo,voucherConfig:{...e.voucherConfig,templateHue:29},appLanguage:e.appLanguage,portrait:{original:null,enhanced:null,useEnhanced:e.portrait.useEnhanced,zoom:e.portrait.zoom,panX:e.portrait.panX,panY:e.portrait.panY,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:e.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));if(typeof window<"u"){const e=an();e&&setTimeout(()=>{const t=y.getState();t.portrait.original||y.setState({portrait:{...t.portrait,original:e}})},0)}const sn={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"}}},cn={de:sn,en:ln};function te(e){return cn[e]}function Ze(e,t,n){if(n&&n.trim())return n;const a=te(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function dn(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function un(e){return e.replace(/\D/g,"").length>=6}function gn({focusField:e,onFocused:t,onFormFocusChange:n}={}){const a=y(u=>u.appLanguage),r=y(u=>u.personalInfo),c=y(u=>u.setPersonalInfo),i=te(a),[s,o]=g.useState(!1),[d,p]=g.useState(!1),x=s&&r.email.trim()&&!dn(r.email),f=d&&r.phone.trim()&&!un(r.phone),h=g.useRef(null),v=g.useRef(null),k=g.useRef(null);return g.useEffect(()=>{if(e){const u=e==="name"?h:e==="email"?v:k;setTimeout(()=>{var I,w;(I=u.current)==null||I.click(),(w=u.current)==null||w.focus(),t==null||t()},100)}},[e,t]),l.jsxs("div",{className:"space-y-4",children:[l.jsxs("div",{className:"form-control",children:[l.jsx("label",{className:"label",children:l.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.name})}),l.jsx("input",{ref:h,type:"text",name:"name",autoComplete:"name",placeholder:i.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:r.name,onChange:u=>c({name:u.target.value}),onFocus:()=>n==null?void 0:n(!0),onBlur:()=>n==null?void 0:n(!1)})]}),l.jsxs("div",{className:"form-control",children:[l.jsx("label",{className:"label",children:l.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.email})}),l.jsx("input",{ref:v,type:"email",name:"email",autoComplete:"email",placeholder:i.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${x?"input-error":""}`,value:r.email,onChange:u=>c({email:u.target.value}),onFocus:()=>n==null?void 0:n(!0),onBlur:()=>{o(!0),n==null||n(!1)}}),x&&l.jsx("label",{className:"label",children:l.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"})})]}),l.jsxs("div",{className:"form-control",children:[l.jsx("label",{className:"label",children:l.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.phone})}),l.jsx("input",{ref:k,type:"tel",name:"phone",autoComplete:"tel",placeholder:i.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${f?"input-error":""}`,value:r.phone,onChange:u=>c({phone:u.target.value}),onFocus:()=>n==null?void 0:n(!0),onBlur:()=>{p(!0),n==null||n(!1)}}),f&&l.jsx("label",{className:"label",children:l.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 mn="https://api.stability.ai/v1/generation",pn="https://api.stability.ai/v2beta/stable-image/edit/remove-background",ht="stability_api_key";let xe=null;function hn(e){xe=e}function fn(){return xe}function bn(){return xe!==null}const xn={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"},st=[{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 wn(e,t){const n=e/t;let a=st[0],r=1/0;for(const c of st){const i=c.width/c.height,s=Math.abs(n-i);s<r&&(r=s,a=c)}return a}function yn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=wn(a.width,a.height),c=document.createElement("canvas");c.width=r.width,c.height=r.height;const i=c.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 d=0,p=0,x=a.width,f=a.height;s>o?(x=a.height*o,d=(a.width-x)/2):(f=a.width/o,p=(a.height-f)/2),i.drawImage(a,d,p,x,f,0,0,r.width,r.height),t(c.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function ft(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,c=new Uint8Array(r);for(let s=0;s<r;s++)c[s]=a.charCodeAt(s);return new Blob([c],{type:n})}function Be(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:pe&&pe.tagName.toUpperCase()==="SCRIPT"&&pe.src||new URL("index.cjs",document.baseURI).href}<"u"&&"sk-7mEKklrqaltdtgbX0VoZbkA8E1cl939Spn75jSIYRvp1BW0b"||typeof process<"u"&&((t=process.env)==null?void 0:t.NEXT_PUBLIC_STABILITY_API_KEY);return e&&e!=="your-api-key-here"?e:typeof localStorage<"u"?localStorage.getItem(ht):null}function bt(e){localStorage.setItem(ht,e)}function Pe(){return xe?!0:Be()!==null}async function vn(e){const t=Be();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,c=await yn(n),i=ft(c),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]",xn[a]),s.append("text_prompts[0][weight]","1"),s.append("cfg_scale","7"),s.append("samples","1"),s.append("steps","30");const d=await fetch(`${mn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:s});if(!d.ok){const x=await d.text();throw console.error("Stability AI error:",x),d.status===401?new Error("Invalid API key"):d.status===402?new Error("Insufficient credits"):d.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${d.status}`)}const p=await d.json();if(!p.artifacts||p.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${p.artifacts[0].base64}`}async function xt(e){if(xe){const i=await fetch(xe,{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=Be();if(!t)throw new Error("No Stability AI API key configured");const n=ft(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(pn,{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 c=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(c)})}function kn(){const[e,t]=g.useState(!1),[n,a]=g.useState(!1),[r,c]=g.useState(null),[i,s]=g.useState(()=>Pe());g.useEffect(()=>{s(Pe());const f=setTimeout(()=>{s(Pe())},150);return()=>clearTimeout(f)},[]);const o=g.useCallback(()=>c(null),[]),d=g.useCallback(f=>{bt(f),s(!0),c(null)},[]),p=g.useCallback(async(f,h=.5,v=40)=>{t(!0),c(null);try{return await gt(f,h,v)}catch(k){const u=k instanceof Error?k.message:"Enhancement failed";throw c(u),k}finally{t(!1)}},[]),x=g.useCallback(async f=>{a(!0),c(null);try{return await xt(f)}catch(h){const v=h instanceof Error?h.message:"Background removal failed";throw c(v),h}finally{a(!1)}},[]);return{enhance:p,removeBg:x,isEnhancing:e,isRemovingBg:n,error:r,hasKey:i,setApiKey:d,clearError:o}}function wt({isOpen:e,onClose:t,onSubmit:n}){const a=y(d=>d.appLanguage),[r,c]=g.useState("");if(!e)return null;const i=d=>{d.preventDefault(),r.trim()&&(n(r.trim()),c(""),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 l.jsxs("dialog",{className:"modal modal-open",children:[l.jsxs("div",{className:"modal-box",children:[l.jsx("h3",{className:"font-bold text-lg",children:o.title}),l.jsx("p",{className:"py-4 text-sm opacity-80",children:o.description}),l.jsxs("form",{onSubmit:i,children:[l.jsxs("div",{className:"form-control",children:[l.jsx("input",{type:"password",placeholder:o.placeholder,className:"input input-bordered w-full",value:r,onChange:d=>c(d.target.value),autoFocus:!0}),l.jsx("label",{className:"label",children:l.jsx("span",{className:"label-text-alt",children:o.hint})})]}),l.jsxs("div",{className:"modal-action",children:[l.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:o.cancel}),l.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:o.submit})]})]})]}),l.jsx("form",{method:"dialog",className:"modal-backdrop",children:l.jsx("button",{onClick:t,children:"close"})})]})}function ve({min:e,max:t,step:n,value:a,onChange:r,className:c="",disabled:i=!1}){const s=g.useRef(null),o=g.useRef(null),d=g.useRef(!1),[p,x]=g.useState(!1),f=(a-e)/(t-e)*100,h=g.useCallback(w=>{if(!s.current)return a;const T=s.current.getBoundingClientRect(),E=Math.max(0,Math.min(1,(w-T.left)/T.width)),S=t-e,N=e+E*S,B=Math.round(N/n)*n;return Math.max(e,Math.min(t,B))},[e,t,n,a]),v=g.useCallback(w=>{if(i)return;const T=w.touches[0];o.current={x:T.clientX,y:T.clientY,value:a,decided:!1},d.current=!1},[a,i]),k=g.useCallback(w=>{if(i||!o.current)return;const T=w.touches[0],E=Math.abs(T.clientX-o.current.x),S=Math.abs(T.clientY-o.current.y);if(!o.current.decided){if(E<8&&S<8)return;if(o.current.decided=!0,S>E){o.current=null;return}d.current=!0,x(!0)}if(d.current){const N=h(T.clientX);N!==a&&r(N)}},[i,h,r,a]),u=g.useCallback(w=>{if(o.current&&!o.current.decided){const T=w.changedTouches[0];if(T){const E=h(T.clientX);E!==a&&r(E)}}o.current=null,d.current=!1,x(!1)},[h,r,a]);g.useEffect(()=>{const w=s.current;if(!w)return;const T=E=>{d.current&&E.preventDefault()};return w.addEventListener("touchmove",T,{passive:!1}),()=>{w.removeEventListener("touchmove",T)}},[]);const I=g.useCallback(w=>{if(i)return;const T=h(w.clientX);r(T),x(!0);const E=N=>{const B=h(N.clientX);r(B)},S=()=>{x(!1),document.removeEventListener("mousemove",E),document.removeEventListener("mouseup",S)};document.addEventListener("mousemove",E),document.addEventListener("mouseup",S)},[i,h,r]);return l.jsxs("div",{ref:s,className:`relative h-6 flex items-center cursor-pointer ${i?"opacity-50 cursor-not-allowed":""}`,onTouchStart:v,onTouchMove:k,onTouchEnd:u,onMouseDown:I,children:[l.jsx("div",{className:"absolute inset-x-0 h-2 bg-base-300 rounded-full"}),l.jsx("div",{className:`absolute left-0 h-2 rounded-full transition-colors ${c.includes("range-primary")?"bg-primary":c.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{width:`${f}%`}}),l.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transform -translate-x-1/2 transition-transform ${p?"scale-125":""} ${c.includes("range-primary")?"border-primary":c.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:`${f}%`}})]})}function In(){const e=y(b=>b.appLanguage),t=y(b=>b.portrait),n=y(b=>b.setPortrait),a=y(b=>b.setPortraitZoom),r=y(b=>b.setPortraitPan),c=y(b=>b.setPortraitRawImage),i=y(b=>b.setPortraitBgRemoved),s=y(b=>b.setPortraitBgOpacity),o=y(b=>b.setPortraitBgBlur),d=y(b=>b.setPortraitEngravingIntensity),{enhance:p,removeBg:x,isEnhancing:f,isRemovingBg:h,error:v,hasKey:k,setApiKey:u}=kn(),I=te(e),w=g.useRef(null),[T,E]=g.useState(!1),[S,N]=g.useState(!1),B=g.useRef(null),D=g.useRef(null),L=t.rawImage,j=t.bgRemovedImage,M=t.bgRemoved,K=t.bgOpacity,F=t.bgBlur,Z=t.engravingIntensity;g.useEffect(()=>{t.original&&!t.rawImage&&c(t.original)},[t.original,t.rawImage,c]),g.useEffect(()=>()=>{B.current&&clearTimeout(B.current),D.current&&clearTimeout(D.current)},[]);const J=y(b=>b.voucherConfig.templateHue),q=g.useRef(J),O=g.useCallback(async b=>{if(!b.type.startsWith("image/"))return;const P=new FileReader;P.onload=async A=>{var W;const C=(W=A.target)==null?void 0:W.result,X=await ut(C);c(X),n(X),i(!1,null),d(0)},P.readAsDataURL(b)},[n,c,i,d]),$=g.useCallback(b=>{b.preventDefault(),E(!1);const P=b.dataTransfer.files[0];P&&O(P)},[O]),Q=g.useCallback(b=>{b.preventDefault(),E(!0)},[]),re=g.useCallback(b=>{b.preventDefault(),E(!1)},[]),De=()=>{var b;(b=w.current)==null||b.click()},we=b=>{var A;const P=(A=b.target.files)==null?void 0:A[0];P&&O(P)},oe=g.useCallback(async(b,P,A)=>{try{return await p(b,P,A)}catch(C){return console.error("Enhancement failed:",C),b}},[p]),ce=g.useCallback(async b=>{try{const P=await x(b);return i(!0,P),P}catch(P){return console.error("Background removal failed:",P),b}},[x,i]),ie=g.useCallback(async()=>{const b=y.getState(),P=b.portrait,A=b.voucherConfig.templateHue;if(!P.rawImage)return;let C;P.bgRemoved&&P.bgRemovedImage?C=await We(P.bgRemovedImage,P.rawImage,P.bgOpacity,P.bgBlur):C=P.rawImage,P.engravingIntensity>0&&(C=await oe(C,P.engravingIntensity,A)),n(C)},[oe,n]);g.useEffect(()=>{if(q.current===J)return;q.current=J;const b=y.getState().portrait;b.engravingIntensity>0&&b.rawImage&&(B.current&&clearTimeout(B.current),B.current=setTimeout(ie,150))},[J,ie]);const ke=async()=>{if(!L)return;if(!M&&!k){N(!0);return}if(!M){const P=await ce(L),A=y.getState(),C=A.portrait,X=A.voucherConfig.templateHue;let W=await We(P,L,C.bgOpacity,C.bgBlur);C.engravingIntensity>0&&(W=await oe(W,C.engravingIntensity,X)),n(W)}else{i(!1,null);const P=y.getState(),A=P.portrait.engravingIntensity,C=P.voucherConfig.templateHue;if(A>0){const X=await oe(L,A,C);n(X)}else n(L)}},Ie=b=>{d(b),B.current&&clearTimeout(B.current),L&&(B.current=setTimeout(ie,150))},ye=async b=>{if(u(b),!L)return;const P=await ce(L),A=y.getState(),C=A.portrait,X=A.voucherConfig.templateHue;let W=await We(P,L,C.bgOpacity,C.bgBlur);C.engravingIntensity>0&&(W=await oe(W,C.engravingIntensity,X)),n(W)},G=b=>{s(b),D.current&&clearTimeout(D.current),!(!L||!j)&&(D.current=setTimeout(ie,150))},Te=b=>{o(b),D.current&&clearTimeout(D.current),!(!L||!j)&&(D.current=setTimeout(ie,150))},Ee=()=>{n(null),c(null),i(!1,null),s(0),o(0),d(0),Zt()};return l.jsxs("div",{className:"space-y-4",children:[t.original?l.jsxs("div",{className:"flex flex-col space-y-4",children:[l.jsxs("div",{className:"flex justify-between items-center w-full",children:[l.jsx("span",{className:"text-sm font-medium text-base-content/70",children:e==="de"?"Portrait-Einstellungen":"Portrait settings"}),l.jsxs("button",{className:"btn btn-xs btn-ghost text-error",onClick:Ee,children:[l.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"})}),e==="de"?"Foto entfernen":"Remove photo"]})]}),l.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[l.jsxs("div",{className:"form-control w-full",children:[l.jsxs("label",{className:"label",children:[l.jsx("span",{className:"label-text",children:I.form.portrait.zoom}),l.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),l.jsx(ve,{min:.5,max:2,step:.05,value:t.zoom,onChange:b=>{a(b),b<=1&&(t.panX!==0||t.panY!==0)&&r(0,0)},className:"range range-primary range-sm"})]}),l.jsxs("div",{className:"form-control w-full",children:[l.jsxs("label",{className:"label",children:[l.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",f&&l.jsx("span",{className:"loading loading-spinner loading-xs"})]}),l.jsxs("span",{className:"label-text-alt",children:[Math.round(Z*100),"%"]})]}),l.jsx(ve,{min:0,max:1,step:.05,value:Z,onChange:Ie,className:"range range-secondary range-sm",disabled:f||!L})]})]}),M?l.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[l.jsxs("div",{className:"form-control w-full",children:[l.jsxs("label",{className:"label",children:[l.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),l.jsxs("span",{className:"label-text-alt",children:[Math.round(K*100),"%"]})]}),l.jsx(ve,{min:0,max:1,step:.05,value:K,onChange:G,className:"range range-primary range-sm"})]}),l.jsxs("div",{className:"form-control w-full",children:[l.jsxs("label",{className:"label",children:[l.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),l.jsxs("span",{className:"label-text-alt",children:[Math.round(F*100),"%"]})]}),l.jsx(ve,{min:0,max:1,step:.05,value:F,onChange:Te,className:"range range-primary range-sm",disabled:K===0})]})]}):l.jsx("div",{className:"form-control w-fit",children:l.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[l.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${h?"opacity-50":""}`,checked:M,onChange:ke,disabled:h||!L}),l.jsxs("span",{className:"label-text flex items-center gap-2",children:[h?l.jsxs(l.Fragment,{children:[l.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!k&&l.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),v&&l.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[l.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:l.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"})}),l.jsx("span",{children:v})]})]}):l.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${h?"border-primary bg-primary/10 pointer-events-none":T?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:$,onDragOver:Q,onDragLeave:re,onClick:De,children:[l.jsx("input",{ref:w,type:"file",accept:"image/*",className:"hidden",onChange:we}),h?l.jsxs("div",{className:"flex flex-col items-center gap-2",children:[l.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),l.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):l.jsxs("div",{className:"flex flex-col items-center gap-2",children:[l.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:l.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"})}),l.jsx("p",{className:"font-medium",children:I.form.portrait.upload}),l.jsx("p",{className:"text-sm text-base-content/60",children:I.form.portrait.dragDrop})]})]}),l.jsx(wt,{isOpen:S,onClose:()=>N(!1),onSubmit:ye})]})}function Tn(){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 c=te(e),i=[1,5,10];return l.jsxs("div",{className:"space-y-4",children:[l.jsx("div",{className:"form-control",children:l.jsxs("div",{className:"flex items-center justify-between gap-2",children:[l.jsx("span",{className:"label-text font-medium",children:c.form.voucher.billLanguage}),l.jsxs("div",{className:"join border border-base-300 rounded-lg shadow",children:[l.jsx("button",{className:`join-item btn btn-md ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:c.form.voucher.billLanguageGerman}),l.jsx("button",{className:`join-item btn btn-md ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:c.form.voucher.billLanguageEnglish})]})]})}),l.jsx("div",{className:"form-control",children:l.jsxs("div",{className:"flex items-center justify-between gap-2",children:[l.jsx("span",{className:"label-text font-medium",children:c.form.voucher.hours}),l.jsx("div",{className:"join border border-base-300 rounded-lg shadow",children:i.map(s=>l.jsxs("button",{className:`join-item btn btn-md ${n===s?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(s),children:[s,l.jsxs("span",{className:"hidden sm:inline",children:[" ",s===1?c.form.voucher.hourLabel:c.form.voucher.hoursLabel]})]},s))})]})}),!1]})}const ze=new Map,de=new Map;async function R(e){return ze.has(e)?ze.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{ze.set(e,a),t(a)},a.onerror=n,a.src=e})}function le(e,t,n,a){e.drawImage(t,0,0,n,a)}async function yt(e,t,n,a){if(t>=155&&t<=165)return R(e);const r=`${e}:${t}:${n}x${a}`;if(de.has(r))return R(de.get(r));const c=await R(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(c,0,0,n,a);const o=i.toDataURL("image/png"),d=await pt(o,t);if(de.size>20){const p=de.keys().next().value;p&&de.delete(p)}return de.set(r,d),R(d)}function En(e,t,n,a,r,c="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 vt(e,t,n,a,r,c,i=1,s=0,o=0){e.save(),e.beginPath(),e.ellipse(n,a,r,c,0,0,Math.PI*2),e.closePath(),e.clip();const d=t.width/t.height,p=r/c,x=r*2,f=c*2;let h,v;d>p?(v=f,h=f*d):(h=x,v=x/d),h*=i,v*=i;const k=Math.max(0,(h-x)/2),u=Math.max(0,(v-f)/2),I=n-h/2+s*k,w=a-v/2+o*u;e.drawImage(t,I,w,h,v),e.restore()}function Je(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 kt(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,c=n.lineHeight||n.fontSize*1.4,i=t.split(" "),s=[];let o="";for(const x of i){const f=o?`${o} ${x}`:x;e.measureText(f).width>r&&o?(s.push(o),o=x):o=f}o&&s.push(o);const d=s.length*c;let p=n.y-d/2;for(const x of s)e.fillText(x,n.x,p),p+=c;e.restore()}function It(e,t,n,a,r,c="#2a3a2a"){e.save(),e.font=`${r.fontSize}px "Times New Roman", serif`,e.textAlign=r.align||"center",e.textBaseline="middle",e.fillStyle=c;const i=r.lineHeight||r.fontSize*1.8,s=[t,n,a].filter(Boolean),o=(s.length-1)*i;let d=r.y-o/2;for(const p of s)p&&(e.fillText(p,r.x,d),d+=i);e.restore()}function Pn(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 Tt(e,t,n,a,r,c,i,s,o,d=1,p=0,x=0,f=0,h=1,v="de"){const k=e.getContext("2d");if(!k)return;const u=document.createElement("canvas");u.width=s,u.height=o;const I=u.getContext("2d");if(!I)return;I.clearRect(0,0,s,o);const w=await yt(t,f,s,o);le(I,w,s,o);const T=await R(n);if(le(I,T,s,o),r)try{const N=await R(r);vt(I,N,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,d,p,x)}catch(N){console.error("Failed to load portrait:",N)}else En(I,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,v);const E=await R(a);le(I,E,s,o);const S=s/3633;jt(I,h,v,S),c&&Je(I,c,i.namePlate),e.width=s,e.height=o,k.drawImage(u,0,0)}async function Et(e,t,n,a,r,c,i,s,o,d,p,x=0,f=1,h="de"){const v=e.getContext("2d");if(!v)return;const k=document.createElement("canvas");k.width=d,k.height=p;const u=k.getContext("2d");if(!u)return;u.clearRect(0,0,d,p);const I=await yt(t,x,d,p);le(u,I,d,p);const w=await R(n);le(u,w,d,p);const T=await R(a);le(u,T,d,p);const E=d/3633;if(jt(u,f,h,E),o.contactInfo&&(r||c||i)&&It(u,r,c,i,o.contactInfo),o.description&&s&&kt(u,s,o.description),r&&Je(u,r,o.namePlate),o.signature){const S=h==="de"?"Unterschrift":"Signature";Pn(u,o.signature,S)}e.width=d,e.height=p,v.drawImage(k,0,0)}const he=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:pe&&pe.tagName.toUpperCase()==="SCRIPT"&&pe.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",_={background:`${he}templates/background.webp`,frontFrame:`${he}templates/front_frame.webp`,backFrame:`${he}templates/back_frame.webp`},fe={1:`${he}templates/1.png`,5:`${he}templates/5.png`,10:`${he}templates/10.png`},Pt={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,Ce=.5,Sn=Math.round(ne*Ce),Ln=Math.round(ae*Ce),St=320,Lt=335,z={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"}},Se=new Map,se=new Map,$e=new Map,Xe=new Map,Ve=new Map;function Rt(e,t,n,a,r,c,i){e.save(),e.font=`900 ${c}px "Times New Roman", Georgia, serif`,e.fillStyle=i,e.textAlign="center",e.textBaseline="middle";const o=e.measureText(t).width/r,d=-Math.PI/2-o/2,p=t.split(""),x=[];for(const h of p)x.push(e.measureText(h).width);let f=d;for(let h=0;h<p.length;h++){const v=p[h],k=x[h],u=f+k/2/r,I=n+r*Math.cos(u),w=a+r*Math.sin(u);e.save(),e.translate(I,w),e.rotate(u+Math.PI/2),e.fillText(v,0,0),e.restore(),f+=k/r}e.restore()}let Y={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function Rn(){const[e,t,n,a,r,c]=await Promise.all([R(_.background),R(_.frontFrame),R(_.backFrame),R(fe[1]),R(fe[5]),R(fe[10])]);Y={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:c}}}function jn(e,t){const n=Math.round(ne*e),a=Math.round(ae*e),r=document.createElement("canvas");r.width=n,r.height=a;const c=r.getContext("2d");if(!c)throw new Error("Failed to get canvas context");c.drawImage(t,0,0,n,a);const i=e<1?.8:.95;return r.toDataURL("image/jpeg",i)}function Bn(e,t){const n=Math.round(ne*e),a=Math.round(ae*e),r=document.createElement("canvas");r.width=n,r.height=a;const c=r.getContext("2d");if(!c)throw new Error("Failed to get canvas context");const i=St*e,s=Lt*e,o=z.badges,d=(p,x)=>{const f=x/2,h=p.x*e-f,v=p.y*e-f;c.drawImage(t,h,v,x,x)};return d(o.topLeft,i),d(o.topRight,i),d(o.bottomLeft,s),d(o.bottomRight,s),r.toDataURL("image/png")}function jt(e,t,n,a=1){const r=Pt[n].banner[t];Rt(e,r,z.banner.centerX*a,z.banner.centerY*a,z.banner.radius*a,z.banner.fontSize*a,z.banner.color)}function Bt(e,t,n,a,r,c,i){const s=Math.round(ne*a),o=Math.round(ae*a),d=document.createElement("canvas");d.width=s,d.height=o;const p=d.getContext("2d");if(!p)throw new Error("Failed to get canvas context");p.drawImage(r,0,0,s,o);{const f=St*a,h=Lt*a,v=z.badges,k=(u,I)=>{const w=I/2,T=u.x*a-w,E=u.y*a-w;p.drawImage(i,T,E,I,I)};k(v.topLeft,f),k(v.topRight,f),k(v.bottomLeft,h),k(v.bottomRight,h)}if(p.drawImage(c,0,0,s,o),n==="front"){const f=Pt[t].banner[e];Rt(p,f,z.banner.centerX*a,z.banner.centerY*a,z.banner.radius*a,z.banner.fontSize*a,z.banner.color)}const x=a<1?.8:.95;return d.toDataURL("image/jpeg",x)}async function Ct(e,t,n){const a=`${e}-${t}-${n}`;if(Se.has(a))return Se.get(a);const r=Y.background||await R(_.background),c=n==="front"?Y.frontFrame||await R(_.frontFrame):Y.backFrame||await R(_.backFrame),i=Y.badges[e]||await R(fe[e]),s=Bt(e,t,n,Ce,r,c,i);return Se.set(a,s),s}async function Ke(e,t,n){const a=`${e}-${t}-${n}`;if(se.has(a))return se.get(a);const r=Y.background||await R(_.background),c=n==="front"?Y.frontFrame||await R(_.frontFrame):Y.backFrame||await R(_.backFrame),i=Y.badges[e]||await R(fe[e]),s=Bt(e,t,n,1,r,c,i);if(se.size>4){const o=se.keys().next().value;o&&se.delete(o)}return se.set(a,s),s}function Cn(){return{width:ne,height:ae}}function Nn(){Se.clear(),se.clear(),$e.clear(),Xe.clear(),Ve.clear()}async function qe(e,t,n="front",a=Ce){const r=`bg-${a}`;let c=$e.get(r);if(!c){const p=Y.background||await R(_.background);c=jn(a,p),$e.set(r,c)}const i=`badges-${e}-${a}`;let s=Xe.get(i);if(!s){const p=Y.badges[e]||await R(fe[e]);s=Bn(a,p),Xe.set(i,s)}const o=`${n}-${a}`;let d=Ve.get(o);if(!d){const p=n==="front"?Y.frontFrame||await R(_.frontFrame):Y.backFrame||await R(_.backFrame),x=Math.round(ne*a),f=Math.round(ae*a),h=document.createElement("canvas");h.width=x,h.height=f;const v=h.getContext("2d");if(!v)throw new Error("Failed to get canvas context");v.drawImage(p,0,0,x,f),d=h.toDataURL("image/png"),Ve.set(o,d)}return{background:c,badges:s,frame:d}}async function Hn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const c of t)for(const i of n)a.push(Ct(r,c,i));await Promise.all(a)}function Qe(e,t){return{front:"",back:"",width:ne,height:ae}}const Ne={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}}},ge=Ne,me=Ne;function et(e){return Ne}const Ge=.75;function Dn(e){const t=et(),n=Ge,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 Mn(e,t){const n=Qe();return{...n,width:Math.round(n.width*Ge),height:Math.round(n.height*Ge)}}function An(e,t){const[n,a]=g.useState(e);return g.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Un({onPortraitClick:e,onFileDrop:t}={}){const n=y(m=>m.appLanguage),a=y(m=>m.voucherConfig.language),r=y(m=>m.voucherConfig.hours),c=y(m=>m.voucherConfig.description),i=y(m=>m.voucherConfig.templateHue),s=y(m=>m.personalInfo),o=y(m=>m.portrait),d=y(m=>m.currentSide),p=y(m=>m.flipSide),x=y(m=>m.setPortraitPan),f=An(i,150),h=te(n),v=g.useRef(null),k=g.useRef(null),u=g.useRef(null),[I,w]=g.useState(!1),[T,E]=g.useState(!1),[S,N]=g.useState(!1),[B,D]=g.useState(!1),L=g.useRef(null),j=Mn(),M=Dn(),K=o.useEnhanced&&o.enhanced?o.enhanced:o.original,F=Ze(a,r,c),[Z,J]=g.useState(""),[q,O]=g.useState(""),[$,Q]=g.useState(""),[re,De]=g.useState(""),[we,oe]=g.useState(""),[ce,ie]=g.useState(""),[ke,Ie]=g.useState(!0);g.useEffect(()=>{let m=!0;Ie(!0);async function H(){const[U,ee]=await Promise.all([qe(r,a,"front"),qe(r,a,"back")]);m&&(J(U.background),O(U.badges),Q(U.frame),De(ee.background),oe(ee.badges),ie(ee.frame),Ie(!1))}return H(),()=>{m=!1}},[r,a]),g.useEffect(()=>{!v.current||!Z||!q||!$||Tt(v.current,Z,q,$,K,s.name,M.front,j.width,j.height,o.zoom,o.panX,o.panY,f,r,a)},[j,Z,q,$,K,s.name,M,o.zoom,o.panX,o.panY,f,r,a]),g.useEffect(()=>{!k.current||!re||!we||!ce||Et(k.current,re,we,ce,s.name,s.email,s.phone,F,M.back,j.width,j.height,f,r,a)},[j,re,we,ce,s,F,M,f,r,a]);const ye=()=>{w(!I),p()};g.useEffect(()=>{w(d==="back")},[d]);const G=g.useCallback((m,H)=>{if(!u.current||d!=="front")return!1;const U=u.current.getBoundingClientRect(),ee=U.width/j.width,Me=U.height/j.height,Ae=(m-U.left)/ee,Ue=(H-U.top)/Me,{x:Ye,y:$t,radiusX:Xt,radiusY:Vt}=M.front.portrait,nt=(Ae-Ye)/Xt,at=(Ue-$t)/Vt;return nt*nt+at*at<=1},[d,j.width,j.height,M.front.portrait]),Te=g.useCallback((m,H)=>{!o.original||o.zoom<=1||!G(m,H)||(E(!0),L.current={x:m,y:H,panX:o.panX,panY:o.panY})},[o.original,o.zoom,o.panX,o.panY,G]),Ee=g.useCallback((m,H)=>{if(!T||!L.current||!u.current)return;const U=u.current.getBoundingClientRect(),ee=3/Math.max(U.width,U.height),Me=(m-L.current.x)*ee,Ae=(H-L.current.y)*ee,Ue=Math.max(-1,Math.min(1,L.current.panX+Me)),Ye=Math.max(-1,Math.min(1,L.current.panY+Ae));x(Ue,Ye)},[T,x]),b=g.useCallback(()=>{E(!1),L.current=null},[]),P=g.useCallback((m,H)=>{!o.original&&G(m,H)&&e&&e()},[o.original,G,e]),A=m=>{G(m.clientX,m.clientY)&&(m.preventDefault(),o.original&&o.zoom>1&&Te(m.clientX,m.clientY))},C=m=>{T||P(m.clientX,m.clientY)},X=m=>{Ee(m.clientX,m.clientY),N(G(m.clientX,m.clientY))},W=()=>b(),Ut=()=>{b(),N(!1)},Yt=m=>{if(m.touches.length===1){const H=m.touches[0];o.zoom>1&&G(H.clientX,H.clientY)&&Te(H.clientX,H.clientY)}},Wt=m=>{m.touches.length===1&&Ee(m.touches[0].clientX,m.touches[0].clientY)},zt=()=>b(),tt=g.useRef(!1);g.useEffect(()=>{tt.current=T},[T]),g.useEffect(()=>{const m=u.current;if(!m)return;const H=U=>{tt.current&&U.preventDefault()};return m.addEventListener("touchmove",H,{passive:!1}),()=>{m.removeEventListener("touchmove",H)}},[]);const _t=d==="front"&&o.original&&o.zoom>1,Ot=j.width/j.height;return l.jsxs("div",{className:"space-y-4",children:[l.jsxs("div",{className:"flex justify-between items-center mb-6",children:[l.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[l.jsx("button",{className:`join-item btn btn-md ${d==="front"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>d!=="front"&&ye(),children:h.preview.front}),l.jsx("button",{className:`join-item btn btn-md ${d==="back"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>d!=="back"&&ye(),children:h.preview.back})]}),l.jsxs("button",{className:"btn btn-ghost btn-md",onClick:ye,children:[l.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.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"})}),l.jsx("span",{className:"hidden sm:inline",children:h.preview.flip})]})]}),l.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:Ot,perspective:"1500px"},children:[ke&&l.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:l.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),l.jsxs("div",{ref:u,className:`relative w-full h-full shadow-lg ${S&&_t?T?"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)"},onClick:C,onMouseDown:A,onMouseMove:X,onMouseUp:W,onMouseLeave:Ut,onTouchStart:Yt,onTouchMove:Wt,onTouchEnd:zt,children:[l.jsx("canvas",{ref:v,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),l.jsx("canvas",{ref:k,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),!o.original&&d==="front"&&(e||t)&&l.jsx("div",{className:`absolute flex flex-col items-center justify-center cursor-pointer transition-colors duration-300 ease-in-out ${B?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(M.front.portrait.x-M.front.portrait.radiusX)/j.width*100}%`,top:`${(M.front.portrait.y-M.front.portrait.radiusY)/j.height*100}%`,width:`${M.front.portrait.radiusX*2/j.width*100}%`,height:`${M.front.portrait.radiusY*2/j.height*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},onClick:m=>{m.stopPropagation(),e==null||e()},onDragOver:m=>{m.preventDefault(),m.stopPropagation(),D(!0)},onDragLeave:m=>{m.preventDefault(),m.stopPropagation(),D(!1)},onDrop:m=>{m.preventDefault(),m.stopPropagation(),D(!1);const H=m.dataTransfer.files[0];H&&H.type.startsWith("image/")&&t&&t(H)},children:l.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",onClick:m=>{m.stopPropagation(),e==null||e()},children:[l.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:[l.jsx("circle",{cx:"12",cy:"8",r:"4"}),l.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),l.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
|
|
2
2
|
hochladen`:`Upload
|
|
3
|
-
photo`})]})})]})]})]})}function
|
|
3
|
+
photo`})]})})]})]})]})}function Yn(){const e=g.useRef(null),t=g.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Wn=`
|
|
4
4
|
// RGB to HSL conversion
|
|
5
5
|
function rgbToHsl(r, g, b) {
|
|
6
6
|
r /= 255;
|
|
@@ -375,4 +375,4 @@ self.onmessage = async (e) => {
|
|
|
375
375
|
});
|
|
376
376
|
}
|
|
377
377
|
};
|
|
378
|
-
`;let
|
|
378
|
+
`;let _e=null,lt=null;function zn(){if(!_e){const e=new Blob([Wn],{type:"application/javascript"});lt=URL.createObjectURL(e),_e=new Worker(lt,{type:"module"})}return _e}async function Oe(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function ct(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 Nt(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:r,layout:c,portrait:i,portraitZoom:s=1,portraitPanX:o=0,portraitPanY:d=0,templateHue:p=160,name:x,email:f,phone:h,description:v,language:k="de"}=e,[u,I]=await Promise.all([Oe(t),Oe(n)]);let w=null;return i&&(w=await Oe(i)),new Promise((T,E)=>{const S=zn(),N=setTimeout(()=>{S.removeEventListener("message",B),S.removeEventListener("error",D),URL.revokeObjectURL(u),URL.revokeObjectURL(I),w&&URL.revokeObjectURL(w),E(new Error("PDF generation timed out. Please try again."))},6e4),B=L=>{if(clearTimeout(N),S.removeEventListener("message",B),S.removeEventListener("error",D),URL.revokeObjectURL(u),URL.revokeObjectURL(I),w&&URL.revokeObjectURL(w),L.data.type==="success")try{const{frontImageData:j,backImageData:M,width:K,height:F}=L.data;if(!j||!M||!K||!F){E(new Error("Invalid response from worker"));return}const Z=ct(j,"image/jpeg"),J=ct(M,"image/jpeg"),q=600,O=K/q*25.4,$=F/q*25.4,Q=new Gt.jsPDF({orientation:O>$?"landscape":"portrait",unit:"mm",format:[O,$]});Q.addImage(Z,"JPEG",0,0,O,$),Q.addPage([O,$]),Q.addImage(J,"JPEG",0,0,O,$);const re=Q.output("blob");T(re)}catch(j){E(j)}else E(new Error(L.data.error))},D=L=>{S.removeEventListener("message",B),S.removeEventListener("error",D),URL.revokeObjectURL(u),URL.revokeObjectURL(I),w&&URL.revokeObjectURL(w),E(new Error(L.message))};S.addEventListener("message",B),S.addEventListener("error",D),S.postMessage({type:"generate",frontTemplateUrl:u,backTemplateUrl:I,portraitUrl:w,templateWidth:a,templateHeight:r,templateHue:p,portraitZoom:s,portraitPanX:o,portraitPanY:d,layout:{front:{portrait:c.front.portrait,namePlate:c.front.namePlate},back:{namePlate:c.back.namePlate,contactInfo:c.back.contactInfo,description:c.back.description,signature:c.back.signature}},name:x,email:f,phone:h,description:v,language:k})})}function Ht(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 Dt(e){const t=await Nt(e);Ht(t,e.filename)}function _n(){const e=y(u=>u.appLanguage),t=y(u=>u.voucherConfig.language),n=y(u=>u.voucherConfig.hours),a=y(u=>u.voucherConfig.description),r=y(u=>u.voucherConfig.templateHue),c=y(u=>u.personalInfo),i=y(u=>u.portrait),s=y(u=>u.isExporting),o=y(u=>u.setIsExporting),d=te(e),p=Qe(),x=et(),f=i.useEnhanced&&i.enhanced?i.enhanced:i.original,h=Ze(t,n,a),v=c.name.trim().length>0&&c.email.trim().length>0&&c.phone.trim().length>0&&i.original!==null,k=async()=>{if(!(!v||s)){o(!0);try{const[u,I]=await Promise.all([Ke(n,t,"front"),Ke(n,t,"back")]),w=`zeitgutschein-${n}h-${c.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await Dt({frontTemplateSrc:u,backTemplateSrc:I,templateWidth:p.width,templateHeight:p.height,layout:x,portrait:f,portraitZoom:i.zoom,portraitPanX:i.panX,portraitPanY:i.panY,templateHue:r,name:c.name,email:c.email,phone:c.phone,description:h,filename:w,language:t})}catch(u){console.error("PDF export failed:",u)}finally{o(!1)}}};return l.jsxs("button",{className:`btn btn-primary w-full btn-md ${v?"":"btn-disabled"}`,onClick:k,disabled:!v,"aria-busy":s,children:[s?l.jsx("span",{className:"loading loading-spinner loading-sm"}):l.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),d.export.button]})}function Mt(){const e=y(a=>a.appLanguage),t=y(a=>a.setAppLanguage),n=a=>{t(a)};return l.jsxs("div",{className:"join",children:[l.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),l.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function On(){const e=y(n=>n.appLanguage),t=te(e);return l.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg shrink-0",children:[l.jsx("div",{className:"navbar-start",children:l.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),l.jsx("div",{className:"navbar-center hidden sm:flex",children:l.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),l.jsx("div",{className:"navbar-end",children:l.jsx(Mt,{})})]})}const je="/",$n={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:ge.front.portrait,name:ge.front.namePlate},back:{name:ge.back.namePlate,contactInfo:ge.back.contactInfo,description:ge.back.description}},languages:["de"]},Xn={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:me.front.portrait,name:me.front.namePlate},back:{name:me.back.namePlate,contactInfo:me.back.contactInfo,description:me.back.description}},languages:["en"]},dt=[$n,Xn],At={async listTemplates(e){let t=[...dt];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=dt.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Vn(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let He=At;function Kn(e){He=e}function qn(){return He}async function Gn(e){return He.listTemplates(e)}async function Fn(e){return He.getTemplate(e)}exports.ApiKeyModal=wt;exports.BillPreview=Un;exports.ExportButton=_n;exports.Header=On;exports.LAYOUT_HDPI=ge;exports.LAYOUT_LDPI=me;exports.LanguageToggle=Mt;exports.PREVIEW_HEIGHT=Ln;exports.PREVIEW_WIDTH=Sn;exports.PersonalInfoForm=gn;exports.PortraitUpload=In;exports.TEMPLATE_HEIGHT=ae;exports.TEMPLATE_LAYOUT=Ne;exports.TEMPLATE_WIDTH=ne;exports.TouchSlider=ve;exports.VoucherConfig=Tn;exports.applyEngravingEffect=gt;exports.applyHueShift=pt;exports.clearCompositorCache=Nn;exports.composeTemplate=Ct;exports.composeTemplateFullRes=Ke;exports.downloadBlob=Ht;exports.drawContactInfo=It;exports.drawMultilineText=kt;exports.drawOvalPortrait=vt;exports.drawTemplate=le;exports.drawText=Je;exports.enhancePortrait=vn;exports.exportBillAsPDF=Dt;exports.formatDescription=Ze;exports.generateBillPDF=Nt;exports.getApiKey=Be;exports.getDefaultTemplateId=Vn;exports.getLayout=et;exports.getRemoveBackgroundEndpoint=fn;exports.getTemplate=Qe;exports.getTemplateById=Fn;exports.getTemplateDimensions=Cn;exports.getTemplateLayers=qe;exports.getTemplateProvider=qn;exports.hasApiKey=Pe;exports.hasCustomEndpoint=bn;exports.listTemplates=Gn;exports.loadImage=R;exports.preloadAllTemplates=Hn;exports.preloadBaseImages=Rn;exports.removeBackground=xt;exports.renderBackSide=Et;exports.renderFrontSide=Tt;exports.resizeImage=ut;exports.setApiKey=bt;exports.setRemoveBackgroundEndpoint=hn;exports.setTemplateProvider=Kn;exports.staticTemplateProvider=At;exports.t=te;exports.useBillCanvasRefs=Yn;exports.useBillStore=y;
|
package/dist/index.d.ts
CHANGED
|
@@ -258,11 +258,12 @@ export declare interface PersonalInfo {
|
|
|
258
258
|
phone: string;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
export declare function PersonalInfoForm({ focusField, onFocused }?: PersonalInfoFormProps): JSX.Element;
|
|
261
|
+
export declare function PersonalInfoForm({ focusField, onFocused, onFormFocusChange }?: PersonalInfoFormProps): JSX.Element;
|
|
262
262
|
|
|
263
263
|
declare interface PersonalInfoFormProps {
|
|
264
264
|
focusField?: 'name' | 'email' | 'phone' | null;
|
|
265
265
|
onFocused?: () => void;
|
|
266
|
+
onFormFocusChange?: (focused: boolean) => void;
|
|
266
267
|
}
|
|
267
268
|
|
|
268
269
|
export declare interface PortraitConfig extends CanvasPosition {
|