@antontranelis/money-printer 1.0.49 → 1.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +4 -2
- package/dist/index.js +91 -74
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),d=require("react"),Ot=require("zustand"),Xt=require("zustand/middleware"),Vt=require("jspdf");var ge=typeof document<"u"?document.currentScript:null;function Kt(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Se=Kt(),at={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Se,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:Se},v=Ot.create()(Xt.persist(e=>({...at,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>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:()=>e(at)}),{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=Se),t&&(t.appLanguage=Se),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})})),qt={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"}}},Gt={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {bannerText} of my time or an equivalent thank you",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},Zt={de:qt,en:Gt};function J(e){return Zt[e]}function qe(e,t,n){if(n&&n.trim())return n;const a=J(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function Jt(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function Qt(e){return e.replace(/\D/g,"").length>=6}function en({focusField:e,onFocused:t}={}){const n=v(w=>w.appLanguage),a=v(w=>w.personalInfo),r=v(w=>w.setPersonalInfo),c=J(n),[l,s]=d.useState(!1),[i,u]=d.useState(!1),h=l&&a.email.trim()&&!Jt(a.email),x=i&&a.phone.trim()&&!Qt(a.phone),p=d.useRef(null),f=d.useRef(null),y=d.useRef(null);return d.useEffect(()=>{if(e){const w=e==="name"?p:e==="email"?f:y;setTimeout(()=>{var g,I;(g=w.current)==null||g.click(),(I=w.current)==null||I.focus(),t==null||t()},100)}},[e,t]),o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:c.form.personalInfo.name})}),o.jsx("input",{ref:p,type:"text",name:"name",autoComplete:"name",placeholder:c.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-lg sm:input-md",value:a.name,onChange:w=>r({name:w.target.value})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:c.form.personalInfo.email})}),o.jsx("input",{ref:f,type:"email",name:"email",autoComplete:"email",placeholder:c.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-lg sm:input-md ${h?"input-error":""}`,value:a.email,onChange:w=>r({email:w.target.value}),onBlur:()=>s(!0)}),h&&o.jsx("label",{className:"label",children:o.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"})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:c.form.personalInfo.phone})}),o.jsx("input",{ref:y,type:"tel",name:"phone",autoComplete:"tel",placeholder:c.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-lg sm:input-md ${x?"input-error":""}`,value:a.phone,onChange:w=>r({phone:w.target.value}),onBlur:()=>u(!0)}),x&&o.jsx("label",{className:"label",children:o.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 tn=1024,ce=new Map;let V=null,rt=null;function Ge(e,t){return V||(V=document.createElement("canvas"),rt=V.getContext("2d",{willReadFrequently:!0})),(V.width!==e||V.height!==t)&&(V.width=e,V.height=t),rt}function ye(e){const t=ce.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(ce.size>10){const c=ce.keys().next().value;c&&ce.delete(c)}ce.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function nn(){ce.clear()}async function ct(e,t=tn){const n=await ye(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,c=Math.round(n.width*r),l=Math.round(n.height*r),s=document.createElement("canvas"),i=s.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return s.width=c,s.height=l,i.drawImage(n,0,0,c,l),s.toDataURL("image/jpeg",.9)}async function We(e,t,n,a=0){const[r,c]=await Promise.all([ye(e),ye(t)]),l=Ge(r.width,r.height);if(l.clearRect(0,0,r.width,r.height),n>0){const s=a*20;l.save(),l.globalAlpha=n,s>0&&(l.filter=`blur(${s}px)`),l.drawImage(c,0,0,r.width,r.height),l.restore()}return l.drawImage(r,0,0),V.toDataURL("image/png")}async function ut(e,t=.5,n=40){const a=await ye(e),r=Ge(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),l=c.data,s=new Uint32Array(l.buffer),i=1+t*.8,u=1-t,h=n%360/360;for(let x=0;x<s.length;x++){const p=s[x],f=p&255,y=p>>8&255,w=p>>16&255,g=p>>24&255;if(g===0)continue;let k=(((77*f+150*y+29*w>>8)/255-.5)*i+.5)*255;k<0?k=0:k>255&&(k=255);const T=k/255,P=.12,[C,j,N]=dt(h,P,T),H=f*u+C*t|0,S=y*u+j*t|0,R=w*u+N*t|0;s[x]=g<<24|R<<16|S<<8|H}return r.putImageData(c,0,0),V.toDataURL("image/png")}function an(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 l=0,s=0;if(a!==r){const i=a-r;switch(s=c>.5?i/(2-a-r):i/(a+r),a){case e:l=((t-n)/i+(t<n?6:0))/6;break;case t:l=((n-e)/i+2)/6;break;case n:l=((e-t)/i+4)/6;break}}return[l,s,c]}function dt(e,t,n){if(t===0){const l=Math.round(n*255);return[l,l,l]}const a=(l,s,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?l+(s-l)*6*i:i<1/2?s:i<2/3?l+(s-l)*(2/3-i)*6:l),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 rn=29,on=5;async function gt(e,t){if(Math.abs(t-rn)<=on)return e;const n=await ye(e),a=Ge(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,l=new Uint32Array(c.buffer),s=t%360/360,i=20/360,u=45/360,h=l.length;for(let x=0;x<h;x++){const p=l[x],f=p&255,y=p>>8&255,w=p>>16&255,g=p>>24&255;if(g===0)continue;const[I,k,T]=an(f,y,w);if(k<.08||I<i||I>u)continue;const P=s,C=Math.min(k,.05),[j,N,H]=dt(P,C,T);l[x]=g<<24|H<<16|N<<8|j}return a.putImageData(r,0,0),V.toDataURL("image/png")}const sn="https://api.stability.ai/v1/generation",ln="https://api.stability.ai/v2beta/stable-image/edit/remove-background",mt="stability_api_key";let pe=null;function cn(e){pe=e}function un(){return pe}function dn(){return pe!==null}const gn={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"},ot=[{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 mn(e,t){const n=e/t;let a=ot[0],r=1/0;for(const c of ot){const l=c.width/c.height,s=Math.abs(n-l);s<r&&(r=s,a=c)}return a}function hn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=mn(a.width,a.height),c=document.createElement("canvas");c.width=r.width,c.height=r.height;const l=c.getContext("2d");if(!l){n(new Error("Failed to get canvas context"));return}const s=a.width/a.height,i=r.width/r.height;let u=0,h=0,x=a.width,p=a.height;s>i?(x=a.height*i,u=(a.width-x)/2):(p=a.width/i,h=(a.height-p)/2),l.drawImage(a,u,h,x,p,0,0,r.width,r.height),t(c.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function ht(e){var l;const t=e.split(","),n=((l=t[0].match(/:(.*?);/))==null?void 0:l[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 Ce(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"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(mt):null}function pt(e){localStorage.setItem(mt,e)}function Ee(){return pe?!0:Ce()!==null}async function pn(e){const t=Ce();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,c=await hn(n),l=ht(c),s=new FormData;s.append("init_image",l,"portrait.png"),s.append("init_image_mode","IMAGE_STRENGTH"),s.append("image_strength",String(1-r)),s.append("text_prompts[0][text]",gn[a]),s.append("text_prompts[0][weight]","1"),s.append("cfg_scale","7"),s.append("samples","1"),s.append("steps","30");const u=await fetch(`${sn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:s});if(!u.ok){const x=await u.text();throw console.error("Stability AI error:",x),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const h=await u.json();if(!h.artifacts||h.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${h.artifacts[0].base64}`}async function ft(e){if(pe){const l=await fetch(pe,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!l.ok){const i=await l.json().catch(()=>({}));throw new Error(i.error||`API error: ${l.status}`)}return(await l.json()).imageDataUrl}const t=Ce();if(!t)throw new Error("No Stability AI API key configured");const n=ht(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(ln,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const l=await r.text();throw console.error("Stability AI remove background error:",l),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((l,s)=>{const i=new FileReader;i.onload=()=>l(i.result),i.onerror=()=>s(new Error("Failed to read result")),i.readAsDataURL(c)})}function fn(){const[e,t]=d.useState(!1),[n,a]=d.useState(!1),[r,c]=d.useState(null),[l,s]=d.useState(()=>Ee());d.useEffect(()=>{s(Ee());const p=setTimeout(()=>{s(Ee())},150);return()=>clearTimeout(p)},[]);const i=d.useCallback(()=>c(null),[]),u=d.useCallback(p=>{pt(p),s(!0),c(null)},[]),h=d.useCallback(async(p,f=.5,y=40)=>{t(!0),c(null);try{return await ut(p,f,y)}catch(w){const g=w instanceof Error?w.message:"Enhancement failed";throw c(g),w}finally{t(!1)}},[]),x=d.useCallback(async p=>{a(!0),c(null);try{return await ft(p)}catch(f){const y=f instanceof Error?f.message:"Background removal failed";throw c(y),f}finally{a(!1)}},[]);return{enhance:h,removeBg:x,isEnhancing:e,isRemovingBg:n,error:r,hasKey:l,setApiKey:u,clearError:i}}function bt({isOpen:e,onClose:t,onSubmit:n}){const a=v(u=>u.appLanguage),[r,c]=d.useState("");if(!e)return null;const l=u=>{u.preventDefault(),r.trim()&&(n(r.trim()),c(""),t())},i={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[a];return o.jsxs("dialog",{className:"modal modal-open",children:[o.jsxs("div",{className:"modal-box",children:[o.jsx("h3",{className:"font-bold text-lg",children:i.title}),o.jsx("p",{className:"py-4 text-sm opacity-80",children:i.description}),o.jsxs("form",{onSubmit:l,children:[o.jsxs("div",{className:"form-control",children:[o.jsx("input",{type:"password",placeholder:i.placeholder,className:"input input-bordered w-full",value:r,onChange:u=>c(u.target.value),autoFocus:!0}),o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text-alt",children:i.hint})})]}),o.jsxs("div",{className:"modal-action",children:[o.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:i.cancel}),o.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:i.submit})]})]})]}),o.jsx("form",{method:"dialog",className:"modal-backdrop",children:o.jsx("button",{onClick:t,children:"close"})})]})}function we({min:e,max:t,step:n,value:a,onChange:r,className:c="",disabled:l=!1}){const s=d.useRef(null),i=d.useRef(null),u=d.useRef(!1),[h,x]=d.useState(!1),p=(a-e)/(t-e)*100,f=d.useCallback(k=>{if(!s.current)return a;const T=s.current.getBoundingClientRect(),P=Math.max(0,Math.min(1,(k-T.left)/T.width)),C=t-e,j=e+P*C,N=Math.round(j/n)*n;return Math.max(e,Math.min(t,N))},[e,t,n,a]),y=d.useCallback(k=>{if(l)return;const T=k.touches[0];i.current={x:T.clientX,y:T.clientY,value:a,decided:!1},u.current=!1},[a,l]),w=d.useCallback(k=>{if(l||!i.current)return;const T=k.touches[0],P=Math.abs(T.clientX-i.current.x),C=Math.abs(T.clientY-i.current.y);if(!i.current.decided){if(P<8&&C<8)return;if(i.current.decided=!0,C>P){i.current=null;return}u.current=!0,x(!0)}if(u.current){const j=f(T.clientX);j!==a&&r(j)}},[l,f,r,a]),g=d.useCallback(()=>{i.current=null,u.current=!1,x(!1)},[]);d.useEffect(()=>{const k=s.current;if(!k)return;const T=P=>{P.preventDefault()};return k.addEventListener("touchstart",T,{passive:!1}),k.addEventListener("touchmove",T,{passive:!1}),()=>{k.removeEventListener("touchstart",T),k.removeEventListener("touchmove",T)}},[]);const I=d.useCallback(k=>{if(l)return;const T=f(k.clientX);r(T),x(!0);const P=j=>{const N=f(j.clientX);r(N)},C=()=>{x(!1),document.removeEventListener("mousemove",P),document.removeEventListener("mouseup",C)};document.addEventListener("mousemove",P),document.addEventListener("mouseup",C)},[l,f,r]);return o.jsxs("div",{ref:s,className:`relative h-6 flex items-center cursor-pointer ${l?"opacity-50 cursor-not-allowed":""}`,onTouchStart:y,onTouchMove:w,onTouchEnd:g,onMouseDown:I,children:[o.jsx("div",{className:"absolute inset-x-0 h-2 bg-base-300 rounded-full"}),o.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:`${p}%`}}),o.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":""} ${c.includes("range-primary")?"border-primary":c.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:`${p}%`}})]})}function bn(){const e=v(b=>b.appLanguage),t=v(b=>b.portrait),n=v(b=>b.setPortrait),a=v(b=>b.setPortraitZoom),r=v(b=>b.setPortraitPan),c=v(b=>b.setPortraitRawImage),l=v(b=>b.setPortraitBgRemoved),s=v(b=>b.setPortraitBgOpacity),i=v(b=>b.setPortraitBgBlur),u=v(b=>b.setPortraitEngravingIntensity),{enhance:h,removeBg:x,isEnhancing:p,isRemovingBg:f,error:y,hasKey:w,setApiKey:g}=fn(),I=J(e),k=d.useRef(null),[T,P]=d.useState(!1),[C,j]=d.useState(!1),N=d.useRef(null),H=d.useRef(null),S=t.rawImage,R=t.bgRemovedImage,M=t.bgRemoved,K=t.bgOpacity,te=t.bgBlur,G=t.engravingIntensity;d.useEffect(()=>{t.original&&!t.rawImage&&c(t.original)},[t.original,t.rawImage,c]),d.useEffect(()=>()=>{N.current&&clearTimeout(N.current),H.current&&clearTimeout(H.current)},[]);const Y=v(b=>b.voucherConfig.templateHue),z=d.useRef(Y),O=d.useCallback(async b=>{if(!b.type.startsWith("image/"))return;const E=new FileReader;E.onload=async A=>{var _;const B=(_=A.target)==null?void 0:_.result,X=await ct(B);c(X),n(X),l(!1,null),u(0)},E.readAsDataURL(b)},[n,c,l,u]),ne=d.useCallback(b=>{b.preventDefault(),P(!1);const E=b.dataTransfer.files[0];E&&O(E)},[O]),Ne=d.useCallback(b=>{b.preventDefault(),P(!0)},[]),fe=d.useCallback(b=>{b.preventDefault(),P(!1)},[]),He=()=>{var b;(b=k.current)==null||b.click()},be=b=>{var A;const E=(A=b.target.files)==null?void 0:A[0];E&&O(E)},ae=d.useCallback(async(b,E,A)=>{try{return await h(b,E,A)}catch(B){return console.error("Enhancement failed:",B),b}},[h]),se=d.useCallback(async b=>{try{const E=await x(b);return l(!0,E),E}catch(E){return console.error("Background removal failed:",E),b}},[x,l]),re=d.useCallback(async()=>{const b=v.getState(),E=b.portrait,A=b.voucherConfig.templateHue;if(!E.rawImage)return;let B;E.bgRemoved&&E.bgRemovedImage?B=await We(E.bgRemovedImage,E.rawImage,E.bgOpacity,E.bgBlur):B=E.rawImage,E.engravingIntensity>0&&(B=await ae(B,E.engravingIntensity,A)),n(B)},[ae,n]);d.useEffect(()=>{if(z.current===Y)return;z.current=Y;const b=v.getState().portrait;b.engravingIntensity>0&&b.rawImage&&(N.current&&clearTimeout(N.current),N.current=setTimeout(re,150))},[Y,re]);const ve=async()=>{if(!S)return;if(!M&&!w){j(!0);return}if(!M){const E=await se(S),A=v.getState(),B=A.portrait,X=A.voucherConfig.templateHue;let _=await We(E,S,B.bgOpacity,B.bgBlur);B.engravingIntensity>0&&(_=await ae(_,B.engravingIntensity,X)),n(_)}else{l(!1,null);const E=v.getState(),A=E.portrait.engravingIntensity,B=E.voucherConfig.templateHue;if(A>0){const X=await ae(S,A,B);n(X)}else n(S)}},ke=b=>{u(b),N.current&&clearTimeout(N.current),S&&(N.current=setTimeout(re,150))},xe=async b=>{if(g(b),!S)return;const E=await se(S),A=v.getState(),B=A.portrait,X=A.voucherConfig.templateHue;let _=await We(E,S,B.bgOpacity,B.bgBlur);B.engravingIntensity>0&&(_=await ae(_,B.engravingIntensity,X)),n(_)},q=b=>{s(b),H.current&&clearTimeout(H.current),!(!S||!R)&&(H.current=setTimeout(re,150))},Ie=b=>{i(b),H.current&&clearTimeout(H.current),!(!S||!R)&&(H.current=setTimeout(re,150))},Te=()=>{n(null),c(null),l(!1,null),s(0),i(0),u(0),nn()};return o.jsxs("div",{className:"space-y-4",children:[t.original?o.jsxs("div",{className:"flex flex-col space-y-4",children:[o.jsxs("div",{className:"flex justify-between items-center w-full",children:[o.jsx("span",{className:"text-sm font-medium text-base-content/70",children:e==="de"?"Portrait-Einstellungen":"Portrait settings"}),o.jsxs("button",{className:"btn btn-xs btn-ghost text-error",onClick:Te,children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"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"]})]}),o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:I.form.portrait.zoom}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),o.jsx(we,{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"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",p&&o.jsx("span",{className:"loading loading-spinner loading-xs"})]}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(G*100),"%"]})]}),o.jsx(we,{min:0,max:1,step:.05,value:G,onChange:ke,className:"range range-secondary range-sm",disabled:p||!S})]})]}),M?o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(K*100),"%"]})]}),o.jsx(we,{min:0,max:1,step:.05,value:K,onChange:q,className:"range range-primary range-sm"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(te*100),"%"]})]}),o.jsx(we,{min:0,max:1,step:.05,value:te,onChange:Ie,className:"range range-primary range-sm",disabled:K===0})]})]}):o.jsx("div",{className:"form-control w-fit",children:o.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[o.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${f?"opacity-50":""}`,checked:M,onChange:ve,disabled:f||!S}),o.jsxs("span",{className:"label-text flex items-center gap-2",children:[f?o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!w&&o.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),y&&o.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"stroke-current shrink-0 h-5 w-5",fill:"none",viewBox:"0 0 24 24",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),o.jsx("span",{children:y})]})]}):o.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${f?"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:ne,onDragOver:Ne,onDragLeave:fe,onClick:He,children:[o.jsx("input",{ref:k,type:"file",accept:"image/*",className:"hidden",onChange:be}),f?o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),o.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),o.jsx("p",{className:"font-medium",children:I.form.portrait.upload}),o.jsx("p",{className:"text-sm text-base-content/60",children:I.form.portrait.dragDrop})]})]}),o.jsx(bt,{isOpen:C,onClose:()=>j(!1),onSubmit:xe})]})}function xn(){const e=v(s=>s.appLanguage),t=v(s=>s.voucherConfig.language),n=v(s=>s.voucherConfig.hours);v(s=>s.voucherConfig.templateHue);const a=v(s=>s.setBillLanguage),r=v(s=>s.setHours);v(s=>s.setTemplateHue);const c=J(e),l=[1,5,10];return o.jsxs("div",{className:"space-y-4",children:[o.jsx("div",{className:"form-control",children:o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("span",{className:"label-text font-medium",children:c.form.voucher.billLanguage}),o.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:c.form.voucher.billLanguageGerman}),o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:c.form.voucher.billLanguageEnglish})]})]})}),o.jsx("div",{className:"form-control",children:o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("span",{className:"label-text font-medium",children:c.form.voucher.hours}),o.jsx("div",{className:"join border border-base-300 rounded-lg",children:l.map(s=>o.jsxs("button",{className:`join-item btn btn-md sm:btn-sm ${n===s?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(s),children:[s,o.jsxs("span",{className:"hidden sm:inline",children:[" ",s===1?c.form.voucher.hourLabel:c.form.voucher.hoursLabel]})]},s))})]})}),!1]})}const Ye=new Map,le=new Map;async function L(e){return Ye.has(e)?Ye.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{Ye.set(e,a),t(a)},a.onerror=n,a.src=e})}function ie(e,t,n,a){e.drawImage(t,0,0,n,a)}async function xt(e,t,n,a){if(t>=155&&t<=165)return L(e);const r=`${e}:${t}:${n}x${a}`;if(le.has(r))return L(le.get(r));const c=await L(e),l=document.createElement("canvas");l.width=n,l.height=a;const s=l.getContext("2d");if(!s)throw new Error("Failed to get canvas context");s.drawImage(c,0,0,n,a);const i=l.toDataURL("image/png"),u=await gt(i,t);if(le.size>20){const h=le.keys().next().value;h&&le.delete(h)}return le.set(r,u),L(u)}function wn(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 wt(e,t,n,a,r,c,l=1,s=0,i=0){e.save(),e.beginPath(),e.ellipse(n,a,r,c,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,h=r/c,x=r*2,p=c*2;let f,y;u>h?(y=p,f=p*u):(f=x,y=x/u),f*=l,y*=l;const w=Math.max(0,(f-x)/2),g=Math.max(0,(y-p)/2),I=n-f/2+s*w,k=a-y/2+i*g;e.drawImage(t,I,k,f,y),e.restore()}function Ze(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 yt(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,l=t.split(" "),s=[];let i="";for(const x of l){const p=i?`${i} ${x}`:x;e.measureText(p).width>r&&i?(s.push(i),i=x):i=p}i&&s.push(i);const u=s.length*c;let h=n.y-u/2;for(const x of s)e.fillText(x,n.x,h),h+=c;e.restore()}function vt(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 l=r.lineHeight||r.fontSize*1.8,s=[t,n,a].filter(Boolean),i=(s.length-1)*l;let u=r.y-i/2;for(const h of s)h&&(e.fillText(h,r.x,u),u+=l);e.restore()}function yn(e,t,n,a="#2a3a2a"){e.save(),e.strokeStyle=a,e.lineWidth=Math.max(2,t.labelFontSize/16),e.beginPath(),e.moveTo(t.x-t.width/2,t.y),e.lineTo(t.x+t.width/2,t.y),e.stroke(),e.font=`${t.labelFontSize}px "Times New Roman", serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=a,e.fillText(n,t.x,t.y+t.labelFontSize*.3),e.restore()}async function kt(e,t,n,a,r,c,l,s,i,u=1,h=0,x=0,p=0,f=1,y="de"){const w=e.getContext("2d");if(!w)return;const g=document.createElement("canvas");g.width=s,g.height=i;const I=g.getContext("2d");if(!I)return;I.clearRect(0,0,s,i);const k=await xt(t,p,s,i);ie(I,k,s,i);const T=await L(n);if(ie(I,T,s,i),r)try{const j=await L(r);wt(I,j,l.portrait.x,l.portrait.y,l.portrait.radiusX,l.portrait.radiusY,u,h,x)}catch(j){console.error("Failed to load portrait:",j)}else wn(I,l.portrait.x,l.portrait.y,l.portrait.radiusX,l.portrait.radiusY,y);const P=await L(a);ie(I,P,s,i);const C=s/3633;Lt(I,f,y,C),c&&Ze(I,c,l.namePlate),e.width=s,e.height=i,w.drawImage(g,0,0)}async function It(e,t,n,a,r,c,l,s,i,u,h,x=0,p=1,f="de"){const y=e.getContext("2d");if(!y)return;const w=document.createElement("canvas");w.width=u,w.height=h;const g=w.getContext("2d");if(!g)return;g.clearRect(0,0,u,h);const I=await xt(t,x,u,h);ie(g,I,u,h);const k=await L(n);ie(g,k,u,h);const T=await L(a);ie(g,T,u,h);const P=u/3633;if(Lt(g,p,f,P),i.contactInfo&&(r||c||l)&&vt(g,r,c,l,i.contactInfo),i.description&&s&&yt(g,s,i.description),r&&Ze(g,r,i.namePlate),i.signature){const C=f==="de"?"Unterschrift":"Signature";yn(g,i.signature,C)}e.width=u,e.height=h,y.drawImage(w,0,0)}const me=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",F={background:`${me}templates/background.webp`,frontFrame:`${me}templates/front_frame.webp`,backFrame:`${me}templates/back_frame.webp`},he={1:`${me}templates/1.png`,5:`${me}templates/5.png`,10:`${me}templates/10.png`},Tt={de:{banner:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"}},en:{banner:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}}},Q=3633,ee=1920,je=.5,vn=Math.round(Q*je),kn=Math.round(ee*je),Et=320,Pt=335,$={badges:{topLeft:{x:286,y:235},topRight:{x:3340,y:230},bottomLeft:{x:282,y:1665},bottomRight:{x:3345,y:1665}},banner:{centerX:1816,centerY:3820,radius:3610,fontSize:103,color:"#2a3a2a"}},Pe=new Map,oe=new Map,$e=new Map,Fe=new Map,Oe=new Map;function St(e,t,n,a,r,c,l){e.save(),e.font=`900 ${c}px "Times New Roman", Georgia, serif`,e.fillStyle=l,e.textAlign="center",e.textBaseline="middle";const i=e.measureText(t).width/r,u=-Math.PI/2-i/2,h=t.split(""),x=[];for(const f of h)x.push(e.measureText(f).width);let p=u;for(let f=0;f<h.length;f++){const y=h[f],w=x[f],g=p+w/2/r,I=n+r*Math.cos(g),k=a+r*Math.sin(g);e.save(),e.translate(I,k),e.rotate(g+Math.PI/2),e.fillText(y,0,0),e.restore(),p+=w/r}e.restore()}let W={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function In(){const[e,t,n,a,r,c]=await Promise.all([L(F.background),L(F.frontFrame),L(F.backFrame),L(he[1]),L(he[5]),L(he[10])]);W={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:c}}}function Tn(e,t){const n=Math.round(Q*e),a=Math.round(ee*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 l=e<1?.8:.95;return r.toDataURL("image/jpeg",l)}function En(e,t){const n=Math.round(Q*e),a=Math.round(ee*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 l=Et*e,s=Pt*e,i=$.badges,u=(h,x)=>{const p=x/2,f=h.x*e-p,y=h.y*e-p;c.drawImage(t,f,y,x,x)};return u(i.topLeft,l),u(i.topRight,l),u(i.bottomLeft,s),u(i.bottomRight,s),r.toDataURL("image/png")}function Lt(e,t,n,a=1){const r=Tt[n].banner[t];St(e,r,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}function Ct(e,t,n,a,r,c,l){const s=Math.round(Q*a),i=Math.round(ee*a),u=document.createElement("canvas");u.width=s,u.height=i;const h=u.getContext("2d");if(!h)throw new Error("Failed to get canvas context");h.drawImage(r,0,0,s,i);{const p=Et*a,f=Pt*a,y=$.badges,w=(g,I)=>{const k=I/2,T=g.x*a-k,P=g.y*a-k;h.drawImage(l,T,P,I,I)};w(y.topLeft,p),w(y.topRight,p),w(y.bottomLeft,f),w(y.bottomRight,f)}if(h.drawImage(c,0,0,s,i),n==="front"){const p=Tt[t].banner[e];St(h,p,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}const x=a<1?.8:.95;return u.toDataURL("image/jpeg",x)}async function jt(e,t,n){const a=`${e}-${t}-${n}`;if(Pe.has(a))return Pe.get(a);const r=W.background||await L(F.background),c=n==="front"?W.frontFrame||await L(F.frontFrame):W.backFrame||await L(F.backFrame),l=W.badges[e]||await L(he[e]),s=Ct(e,t,n,je,r,c,l);return Pe.set(a,s),s}async function Xe(e,t,n){const a=`${e}-${t}-${n}`;if(oe.has(a))return oe.get(a);const r=W.background||await L(F.background),c=n==="front"?W.frontFrame||await L(F.frontFrame):W.backFrame||await L(F.backFrame),l=W.badges[e]||await L(he[e]),s=Ct(e,t,n,1,r,c,l);if(oe.size>4){const i=oe.keys().next().value;i&&oe.delete(i)}return oe.set(a,s),s}function Pn(){return{width:Q,height:ee}}function Sn(){Pe.clear(),oe.clear(),$e.clear(),Fe.clear(),Oe.clear()}async function Ve(e,t,n="front",a=je){const r=`bg-${a}`;let c=$e.get(r);if(!c){const h=W.background||await L(F.background);c=Tn(a,h),$e.set(r,c)}const l=`badges-${e}-${a}`;let s=Fe.get(l);if(!s){const h=W.badges[e]||await L(he[e]);s=En(a,h),Fe.set(l,s)}const i=`${n}-${a}`;let u=Oe.get(i);if(!u){const h=n==="front"?W.frontFrame||await L(F.frontFrame):W.backFrame||await L(F.backFrame),x=Math.round(Q*a),p=Math.round(ee*a),f=document.createElement("canvas");f.width=x,f.height=p;const y=f.getContext("2d");if(!y)throw new Error("Failed to get canvas context");y.drawImage(h,0,0,x,p),u=f.toDataURL("image/png"),Oe.set(i,u)}return{background:c,badges:s,frame:u}}async function Ln(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const c of t)for(const l of n)a.push(jt(r,c,l));await Promise.all(a)}function Je(e,t){return{front:"",back:"",width:Q,height:ee}}const Re={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},ue=Re,de=Re;function Qe(e){return Re}const Ke=.75;function Cn(e){const t=Qe(),n=Ke,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 jn(e,t){const n=Je();return{...n,width:Math.round(n.width*Ke),height:Math.round(n.height*Ke)}}function Rn(e,t){const[n,a]=d.useState(e);return d.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Bn({onPortraitClick:e,onFileDrop:t}={}){const n=v(m=>m.appLanguage),a=v(m=>m.voucherConfig.language),r=v(m=>m.voucherConfig.hours),c=v(m=>m.voucherConfig.description),l=v(m=>m.voucherConfig.templateHue),s=v(m=>m.personalInfo),i=v(m=>m.portrait),u=v(m=>m.currentSide),h=v(m=>m.flipSide),x=v(m=>m.setPortraitPan),p=Rn(l,150),f=J(n),y=d.useRef(null),w=d.useRef(null),g=d.useRef(null),[I,k]=d.useState(!1),[T,P]=d.useState(!1),[C,j]=d.useState(!1),[N,H]=d.useState(!1),S=d.useRef(null),R=jn(),M=Cn(),K=i.useEnhanced&&i.enhanced?i.enhanced:i.original,te=qe(a,r,c),[G,Y]=d.useState(""),[z,O]=d.useState(""),[ne,Ne]=d.useState(""),[fe,He]=d.useState(""),[be,ae]=d.useState(""),[se,re]=d.useState(""),[ve,ke]=d.useState(!0);d.useEffect(()=>{let m=!0;ke(!0);async function D(){const[U,Z]=await Promise.all([Ve(r,a,"front"),Ve(r,a,"back")]);m&&(Y(U.background),O(U.badges),Ne(U.frame),He(Z.background),ae(Z.badges),re(Z.frame),ke(!1))}return D(),()=>{m=!1}},[r,a]),d.useEffect(()=>{!y.current||!G||!z||!ne||kt(y.current,G,z,ne,K,s.name,M.front,R.width,R.height,i.zoom,i.panX,i.panY,p,r,a)},[R,G,z,ne,K,s.name,M,i.zoom,i.panX,i.panY,p,r,a]),d.useEffect(()=>{!w.current||!fe||!be||!se||It(w.current,fe,be,se,s.name,s.email,s.phone,te,M.back,R.width,R.height,p,r,a)},[R,fe,be,se,s,te,M,p,r,a]);const xe=()=>{k(!I),h()};d.useEffect(()=>{k(u==="back")},[u]);const q=d.useCallback((m,D)=>{if(!g.current||u!=="front")return!1;const U=g.current.getBoundingClientRect(),Z=U.width/R.width,De=U.height/R.height,Me=(m-U.left)/Z,Ae=(D-U.top)/De,{x:Ue,y:_t,radiusX:$t,radiusY:Ft}=M.front.portrait,tt=(Me-Ue)/$t,nt=(Ae-_t)/Ft;return tt*tt+nt*nt<=1},[u,R.width,R.height,M.front.portrait]),Ie=d.useCallback((m,D)=>{!i.original||i.zoom<=1||!q(m,D)||(P(!0),S.current={x:m,y:D,panX:i.panX,panY:i.panY})},[i.original,i.zoom,i.panX,i.panY,q]),Te=d.useCallback((m,D)=>{if(!T||!S.current||!g.current)return;const U=g.current.getBoundingClientRect(),Z=3/Math.max(U.width,U.height),De=(m-S.current.x)*Z,Me=(D-S.current.y)*Z,Ae=Math.max(-1,Math.min(1,S.current.panX+De)),Ue=Math.max(-1,Math.min(1,S.current.panY+Me));x(Ae,Ue)},[T,x]),b=d.useCallback(()=>{P(!1),S.current=null},[]),E=d.useCallback((m,D)=>{!i.original&&q(m,D)&&e&&e()},[i.original,q,e]),A=m=>{q(m.clientX,m.clientY)&&(m.preventDefault(),i.original&&i.zoom>1&&Ie(m.clientX,m.clientY))},B=m=>{T||E(m.clientX,m.clientY)},X=m=>{Te(m.clientX,m.clientY),j(q(m.clientX,m.clientY))},_=()=>b(),Mt=()=>{b(),j(!1)},At=m=>{if(m.touches.length===1){const D=m.touches[0];i.zoom>1&&q(D.clientX,D.clientY)&&Ie(D.clientX,D.clientY)}},Ut=m=>{m.touches.length===1&&Te(m.touches[0].clientX,m.touches[0].clientY)},Wt=()=>b(),et=d.useRef(!1);d.useEffect(()=>{et.current=T},[T]),d.useEffect(()=>{const m=g.current;if(!m)return;const D=U=>{et.current&&U.preventDefault()};return m.addEventListener("touchmove",D,{passive:!1}),()=>{m.removeEventListener("touchmove",D)}},[]);const Yt=u==="front"&&i.original&&i.zoom>1,zt=R.width/R.height;return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex justify-between items-center",children:[o.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${u==="front"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="front"&&xe(),children:f.preview.front}),o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${u==="back"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="back"&&xe(),children:f.preview.back})]}),o.jsxs("button",{className:"btn btn-ghost btn-md sm:btn-sm",onClick:xe,children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),o.jsx("span",{className:"hidden sm:inline",children:f.preview.flip})]})]}),o.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:zt,perspective:"1500px"},children:[ve&&o.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),o.jsxs("div",{ref:g,className:`relative w-full h-full shadow-lg ${C&&Yt?T?"cursor-grabbing":"cursor-grab":""} ${ve?"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:X,onMouseUp:_,onMouseLeave:Mt,onTouchStart:At,onTouchMove:Ut,onTouchEnd:Wt,children:[o.jsx("canvas",{ref:y,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),o.jsx("canvas",{ref:w,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),!i.original&&u==="front"&&(e||t)&&o.jsx("div",{className:`absolute flex flex-col items-center justify-center cursor-pointer transition-colors duration-300 ease-in-out ${N?"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(),H(!0)},onDragLeave:m=>{m.preventDefault(),m.stopPropagation(),H(!1)},onDrop:m=>{m.preventDefault(),m.stopPropagation(),H(!1);const D=m.dataTransfer.files[0];D&&D.type.startsWith("image/")&&t&&t(D)},children:o.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:[o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-7 h-6 sm:w-11 sm:h-10 text-base-content/50",fill:"none",viewBox:"0 0 26 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[o.jsx("circle",{cx:"11",cy:"8",r:"4"}),o.jsx("path",{d:"M3 21c0-4 4-6 8-6s8 2 8 6"}),o.jsx("line",{x1:"22",y1:"4",x2:"22",y2:"10",strokeWidth:2}),o.jsx("line",{x1:"19",y1:"7",x2:"25",y2:"7",strokeWidth:2})]}),o.jsx("span",{className:"text-[10px] sm:text-xs",children:n==="de"?"Foto hochladen":"Upload photo"})]})})]})]})]})}function Nn(){const e=d.useRef(null),t=d.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Hn=`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),d=require("react"),Ot=require("zustand"),Xt=require("zustand/middleware"),Vt=require("jspdf");var ge=typeof document<"u"?document.currentScript:null;function Kt(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Le=Kt(),at={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Le,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:Le},v=Ot.create()(Xt.persist(e=>({...at,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>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:()=>e(at)}),{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=Le),t&&(t.appLanguage=Le),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})})),qt={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"}}},Gt={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {bannerText} of my time or an equivalent thank you",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},Zt={de:qt,en:Gt};function J(e){return Zt[e]}function qe(e,t,n){if(n&&n.trim())return n;const a=J(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function Jt(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function Qt(e){return e.replace(/\D/g,"").length>=6}function en({focusField:e,onFocused:t}={}){const n=v(w=>w.appLanguage),a=v(w=>w.personalInfo),r=v(w=>w.setPersonalInfo),c=J(n),[l,s]=d.useState(!1),[i,u]=d.useState(!1),h=l&&a.email.trim()&&!Jt(a.email),x=i&&a.phone.trim()&&!Qt(a.phone),p=d.useRef(null),f=d.useRef(null),y=d.useRef(null);return d.useEffect(()=>{if(e){const w=e==="name"?p:e==="email"?f:y;setTimeout(()=>{var g,I;(g=w.current)==null||g.click(),(I=w.current)==null||I.focus(),t==null||t()},100)}},[e,t]),o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:c.form.personalInfo.name})}),o.jsx("input",{ref:p,type:"text",name:"name",autoComplete:"name",placeholder:c.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-lg sm:input-md",value:a.name,onChange:w=>r({name:w.target.value})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:c.form.personalInfo.email})}),o.jsx("input",{ref:f,type:"email",name:"email",autoComplete:"email",placeholder:c.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-lg sm:input-md ${h?"input-error":""}`,value:a.email,onChange:w=>r({email:w.target.value}),onBlur:()=>s(!0)}),h&&o.jsx("label",{className:"label",children:o.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"})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:c.form.personalInfo.phone})}),o.jsx("input",{ref:y,type:"tel",name:"phone",autoComplete:"tel",placeholder:c.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-lg sm:input-md ${x?"input-error":""}`,value:a.phone,onChange:w=>r({phone:w.target.value}),onBlur:()=>u(!0)}),x&&o.jsx("label",{className:"label",children:o.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 tn=1024,ce=new Map;let V=null,rt=null;function Ge(e,t){return V||(V=document.createElement("canvas"),rt=V.getContext("2d",{willReadFrequently:!0})),(V.width!==e||V.height!==t)&&(V.width=e,V.height=t),rt}function ye(e){const t=ce.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(ce.size>10){const c=ce.keys().next().value;c&&ce.delete(c)}ce.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function nn(){ce.clear()}async function ct(e,t=tn){const n=await ye(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,c=Math.round(n.width*r),l=Math.round(n.height*r),s=document.createElement("canvas"),i=s.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return s.width=c,s.height=l,i.drawImage(n,0,0,c,l),s.toDataURL("image/jpeg",.9)}async function Ye(e,t,n,a=0){const[r,c]=await Promise.all([ye(e),ye(t)]),l=Ge(r.width,r.height);if(l.clearRect(0,0,r.width,r.height),n>0){const s=a*20;l.save(),l.globalAlpha=n,s>0&&(l.filter=`blur(${s}px)`),l.drawImage(c,0,0,r.width,r.height),l.restore()}return l.drawImage(r,0,0),V.toDataURL("image/png")}async function ut(e,t=.5,n=40){const a=await ye(e),r=Ge(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),l=c.data,s=new Uint32Array(l.buffer),i=1+t*.8,u=1-t,h=n%360/360;for(let x=0;x<s.length;x++){const p=s[x],f=p&255,y=p>>8&255,w=p>>16&255,g=p>>24&255;if(g===0)continue;let k=(((77*f+150*y+29*w>>8)/255-.5)*i+.5)*255;k<0?k=0:k>255&&(k=255);const T=k/255,P=.12,[C,j,N]=dt(h,P,T),H=f*u+C*t|0,L=y*u+j*t|0,R=w*u+N*t|0;s[x]=g<<24|R<<16|L<<8|H}return r.putImageData(c,0,0),V.toDataURL("image/png")}function an(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 l=0,s=0;if(a!==r){const i=a-r;switch(s=c>.5?i/(2-a-r):i/(a+r),a){case e:l=((t-n)/i+(t<n?6:0))/6;break;case t:l=((n-e)/i+2)/6;break;case n:l=((e-t)/i+4)/6;break}}return[l,s,c]}function dt(e,t,n){if(t===0){const l=Math.round(n*255);return[l,l,l]}const a=(l,s,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?l+(s-l)*6*i:i<1/2?s:i<2/3?l+(s-l)*(2/3-i)*6:l),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 rn=29,on=5;async function gt(e,t){if(Math.abs(t-rn)<=on)return e;const n=await ye(e),a=Ge(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,l=new Uint32Array(c.buffer),s=t%360/360,i=20/360,u=45/360,h=l.length;for(let x=0;x<h;x++){const p=l[x],f=p&255,y=p>>8&255,w=p>>16&255,g=p>>24&255;if(g===0)continue;const[I,k,T]=an(f,y,w);if(k<.08||I<i||I>u)continue;const P=s,C=Math.min(k,.05),[j,N,H]=dt(P,C,T);l[x]=g<<24|H<<16|N<<8|j}return a.putImageData(r,0,0),V.toDataURL("image/png")}const sn="https://api.stability.ai/v1/generation",ln="https://api.stability.ai/v2beta/stable-image/edit/remove-background",mt="stability_api_key";let pe=null;function cn(e){pe=e}function un(){return pe}function dn(){return pe!==null}const gn={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"},ot=[{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 mn(e,t){const n=e/t;let a=ot[0],r=1/0;for(const c of ot){const l=c.width/c.height,s=Math.abs(n-l);s<r&&(r=s,a=c)}return a}function hn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=mn(a.width,a.height),c=document.createElement("canvas");c.width=r.width,c.height=r.height;const l=c.getContext("2d");if(!l){n(new Error("Failed to get canvas context"));return}const s=a.width/a.height,i=r.width/r.height;let u=0,h=0,x=a.width,p=a.height;s>i?(x=a.height*i,u=(a.width-x)/2):(p=a.width/i,h=(a.height-p)/2),l.drawImage(a,u,h,x,p,0,0,r.width,r.height),t(c.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function ht(e){var l;const t=e.split(","),n=((l=t[0].match(/:(.*?);/))==null?void 0:l[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 Ce(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"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(mt):null}function pt(e){localStorage.setItem(mt,e)}function Ee(){return pe?!0:Ce()!==null}async function pn(e){const t=Ce();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,c=await hn(n),l=ht(c),s=new FormData;s.append("init_image",l,"portrait.png"),s.append("init_image_mode","IMAGE_STRENGTH"),s.append("image_strength",String(1-r)),s.append("text_prompts[0][text]",gn[a]),s.append("text_prompts[0][weight]","1"),s.append("cfg_scale","7"),s.append("samples","1"),s.append("steps","30");const u=await fetch(`${sn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:s});if(!u.ok){const x=await u.text();throw console.error("Stability AI error:",x),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const h=await u.json();if(!h.artifacts||h.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${h.artifacts[0].base64}`}async function ft(e){if(pe){const l=await fetch(pe,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!l.ok){const i=await l.json().catch(()=>({}));throw new Error(i.error||`API error: ${l.status}`)}return(await l.json()).imageDataUrl}const t=Ce();if(!t)throw new Error("No Stability AI API key configured");const n=ht(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(ln,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const l=await r.text();throw console.error("Stability AI remove background error:",l),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((l,s)=>{const i=new FileReader;i.onload=()=>l(i.result),i.onerror=()=>s(new Error("Failed to read result")),i.readAsDataURL(c)})}function fn(){const[e,t]=d.useState(!1),[n,a]=d.useState(!1),[r,c]=d.useState(null),[l,s]=d.useState(()=>Ee());d.useEffect(()=>{s(Ee());const p=setTimeout(()=>{s(Ee())},150);return()=>clearTimeout(p)},[]);const i=d.useCallback(()=>c(null),[]),u=d.useCallback(p=>{pt(p),s(!0),c(null)},[]),h=d.useCallback(async(p,f=.5,y=40)=>{t(!0),c(null);try{return await ut(p,f,y)}catch(w){const g=w instanceof Error?w.message:"Enhancement failed";throw c(g),w}finally{t(!1)}},[]),x=d.useCallback(async p=>{a(!0),c(null);try{return await ft(p)}catch(f){const y=f instanceof Error?f.message:"Background removal failed";throw c(y),f}finally{a(!1)}},[]);return{enhance:h,removeBg:x,isEnhancing:e,isRemovingBg:n,error:r,hasKey:l,setApiKey:u,clearError:i}}function bt({isOpen:e,onClose:t,onSubmit:n}){const a=v(u=>u.appLanguage),[r,c]=d.useState("");if(!e)return null;const l=u=>{u.preventDefault(),r.trim()&&(n(r.trim()),c(""),t())},i={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[a];return o.jsxs("dialog",{className:"modal modal-open",children:[o.jsxs("div",{className:"modal-box",children:[o.jsx("h3",{className:"font-bold text-lg",children:i.title}),o.jsx("p",{className:"py-4 text-sm opacity-80",children:i.description}),o.jsxs("form",{onSubmit:l,children:[o.jsxs("div",{className:"form-control",children:[o.jsx("input",{type:"password",placeholder:i.placeholder,className:"input input-bordered w-full",value:r,onChange:u=>c(u.target.value),autoFocus:!0}),o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text-alt",children:i.hint})})]}),o.jsxs("div",{className:"modal-action",children:[o.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:i.cancel}),o.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:i.submit})]})]})]}),o.jsx("form",{method:"dialog",className:"modal-backdrop",children:o.jsx("button",{onClick:t,children:"close"})})]})}function we({min:e,max:t,step:n,value:a,onChange:r,className:c="",disabled:l=!1}){const s=d.useRef(null),i=d.useRef(null),u=d.useRef(!1),[h,x]=d.useState(!1),p=(a-e)/(t-e)*100,f=d.useCallback(k=>{if(!s.current)return a;const T=s.current.getBoundingClientRect(),P=Math.max(0,Math.min(1,(k-T.left)/T.width)),C=t-e,j=e+P*C,N=Math.round(j/n)*n;return Math.max(e,Math.min(t,N))},[e,t,n,a]),y=d.useCallback(k=>{if(l)return;const T=k.touches[0];i.current={x:T.clientX,y:T.clientY,value:a,decided:!1},u.current=!1},[a,l]),w=d.useCallback(k=>{if(l||!i.current)return;const T=k.touches[0],P=Math.abs(T.clientX-i.current.x),C=Math.abs(T.clientY-i.current.y);if(!i.current.decided){if(P<8&&C<8)return;if(i.current.decided=!0,C>P){i.current=null;return}u.current=!0,x(!0)}if(u.current){const j=f(T.clientX);j!==a&&r(j)}},[l,f,r,a]),g=d.useCallback(()=>{i.current=null,u.current=!1,x(!1)},[]);d.useEffect(()=>{const k=s.current;if(!k)return;const T=P=>{P.preventDefault()};return k.addEventListener("touchstart",T,{passive:!1}),k.addEventListener("touchmove",T,{passive:!1}),()=>{k.removeEventListener("touchstart",T),k.removeEventListener("touchmove",T)}},[]);const I=d.useCallback(k=>{if(l)return;const T=f(k.clientX);r(T),x(!0);const P=j=>{const N=f(j.clientX);r(N)},C=()=>{x(!1),document.removeEventListener("mousemove",P),document.removeEventListener("mouseup",C)};document.addEventListener("mousemove",P),document.addEventListener("mouseup",C)},[l,f,r]);return o.jsxs("div",{ref:s,className:`relative h-6 flex items-center cursor-pointer ${l?"opacity-50 cursor-not-allowed":""}`,onTouchStart:y,onTouchMove:w,onTouchEnd:g,onMouseDown:I,children:[o.jsx("div",{className:"absolute inset-x-0 h-2 bg-base-300 rounded-full"}),o.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:`${p}%`}}),o.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":""} ${c.includes("range-primary")?"border-primary":c.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:`${p}%`}})]})}function bn(){const e=v(b=>b.appLanguage),t=v(b=>b.portrait),n=v(b=>b.setPortrait),a=v(b=>b.setPortraitZoom),r=v(b=>b.setPortraitPan),c=v(b=>b.setPortraitRawImage),l=v(b=>b.setPortraitBgRemoved),s=v(b=>b.setPortraitBgOpacity),i=v(b=>b.setPortraitBgBlur),u=v(b=>b.setPortraitEngravingIntensity),{enhance:h,removeBg:x,isEnhancing:p,isRemovingBg:f,error:y,hasKey:w,setApiKey:g}=fn(),I=J(e),k=d.useRef(null),[T,P]=d.useState(!1),[C,j]=d.useState(!1),N=d.useRef(null),H=d.useRef(null),L=t.rawImage,R=t.bgRemovedImage,M=t.bgRemoved,K=t.bgOpacity,te=t.bgBlur,G=t.engravingIntensity;d.useEffect(()=>{t.original&&!t.rawImage&&c(t.original)},[t.original,t.rawImage,c]),d.useEffect(()=>()=>{N.current&&clearTimeout(N.current),H.current&&clearTimeout(H.current)},[]);const W=v(b=>b.voucherConfig.templateHue),z=d.useRef(W),O=d.useCallback(async b=>{if(!b.type.startsWith("image/"))return;const E=new FileReader;E.onload=async A=>{var _;const B=(_=A.target)==null?void 0:_.result,X=await ct(B);c(X),n(X),l(!1,null),u(0)},E.readAsDataURL(b)},[n,c,l,u]),ne=d.useCallback(b=>{b.preventDefault(),P(!1);const E=b.dataTransfer.files[0];E&&O(E)},[O]),Ne=d.useCallback(b=>{b.preventDefault(),P(!0)},[]),fe=d.useCallback(b=>{b.preventDefault(),P(!1)},[]),He=()=>{var b;(b=k.current)==null||b.click()},be=b=>{var A;const E=(A=b.target.files)==null?void 0:A[0];E&&O(E)},ae=d.useCallback(async(b,E,A)=>{try{return await h(b,E,A)}catch(B){return console.error("Enhancement failed:",B),b}},[h]),se=d.useCallback(async b=>{try{const E=await x(b);return l(!0,E),E}catch(E){return console.error("Background removal failed:",E),b}},[x,l]),re=d.useCallback(async()=>{const b=v.getState(),E=b.portrait,A=b.voucherConfig.templateHue;if(!E.rawImage)return;let B;E.bgRemoved&&E.bgRemovedImage?B=await Ye(E.bgRemovedImage,E.rawImage,E.bgOpacity,E.bgBlur):B=E.rawImage,E.engravingIntensity>0&&(B=await ae(B,E.engravingIntensity,A)),n(B)},[ae,n]);d.useEffect(()=>{if(z.current===W)return;z.current=W;const b=v.getState().portrait;b.engravingIntensity>0&&b.rawImage&&(N.current&&clearTimeout(N.current),N.current=setTimeout(re,150))},[W,re]);const ve=async()=>{if(!L)return;if(!M&&!w){j(!0);return}if(!M){const E=await se(L),A=v.getState(),B=A.portrait,X=A.voucherConfig.templateHue;let _=await Ye(E,L,B.bgOpacity,B.bgBlur);B.engravingIntensity>0&&(_=await ae(_,B.engravingIntensity,X)),n(_)}else{l(!1,null);const E=v.getState(),A=E.portrait.engravingIntensity,B=E.voucherConfig.templateHue;if(A>0){const X=await ae(L,A,B);n(X)}else n(L)}},ke=b=>{u(b),N.current&&clearTimeout(N.current),L&&(N.current=setTimeout(re,150))},xe=async b=>{if(g(b),!L)return;const E=await se(L),A=v.getState(),B=A.portrait,X=A.voucherConfig.templateHue;let _=await Ye(E,L,B.bgOpacity,B.bgBlur);B.engravingIntensity>0&&(_=await ae(_,B.engravingIntensity,X)),n(_)},q=b=>{s(b),H.current&&clearTimeout(H.current),!(!L||!R)&&(H.current=setTimeout(re,150))},Ie=b=>{i(b),H.current&&clearTimeout(H.current),!(!L||!R)&&(H.current=setTimeout(re,150))},Te=()=>{n(null),c(null),l(!1,null),s(0),i(0),u(0),nn()};return o.jsxs("div",{className:"space-y-4",children:[t.original?o.jsxs("div",{className:"flex flex-col space-y-4",children:[o.jsxs("div",{className:"flex justify-between items-center w-full",children:[o.jsx("span",{className:"text-sm font-medium text-base-content/70",children:e==="de"?"Portrait-Einstellungen":"Portrait settings"}),o.jsxs("button",{className:"btn btn-xs btn-ghost text-error",onClick:Te,children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"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"]})]}),o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:I.form.portrait.zoom}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),o.jsx(we,{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"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",p&&o.jsx("span",{className:"loading loading-spinner loading-xs"})]}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(G*100),"%"]})]}),o.jsx(we,{min:0,max:1,step:.05,value:G,onChange:ke,className:"range range-secondary range-sm",disabled:p||!L})]})]}),M?o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(K*100),"%"]})]}),o.jsx(we,{min:0,max:1,step:.05,value:K,onChange:q,className:"range range-primary range-sm"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(te*100),"%"]})]}),o.jsx(we,{min:0,max:1,step:.05,value:te,onChange:Ie,className:"range range-primary range-sm",disabled:K===0})]})]}):o.jsx("div",{className:"form-control w-fit",children:o.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[o.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${f?"opacity-50":""}`,checked:M,onChange:ve,disabled:f||!L}),o.jsxs("span",{className:"label-text flex items-center gap-2",children:[f?o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!w&&o.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),y&&o.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"stroke-current shrink-0 h-5 w-5",fill:"none",viewBox:"0 0 24 24",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),o.jsx("span",{children:y})]})]}):o.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${f?"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:ne,onDragOver:Ne,onDragLeave:fe,onClick:He,children:[o.jsx("input",{ref:k,type:"file",accept:"image/*",className:"hidden",onChange:be}),f?o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),o.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),o.jsx("p",{className:"font-medium",children:I.form.portrait.upload}),o.jsx("p",{className:"text-sm text-base-content/60",children:I.form.portrait.dragDrop})]})]}),o.jsx(bt,{isOpen:C,onClose:()=>j(!1),onSubmit:xe})]})}function xn(){const e=v(s=>s.appLanguage),t=v(s=>s.voucherConfig.language),n=v(s=>s.voucherConfig.hours);v(s=>s.voucherConfig.templateHue);const a=v(s=>s.setBillLanguage),r=v(s=>s.setHours);v(s=>s.setTemplateHue);const c=J(e),l=[1,5,10];return o.jsxs("div",{className:"space-y-4",children:[o.jsx("div",{className:"form-control",children:o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("span",{className:"label-text font-medium",children:c.form.voucher.billLanguage}),o.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:c.form.voucher.billLanguageGerman}),o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:c.form.voucher.billLanguageEnglish})]})]})}),o.jsx("div",{className:"form-control",children:o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("span",{className:"label-text font-medium",children:c.form.voucher.hours}),o.jsx("div",{className:"join border border-base-300 rounded-lg",children:l.map(s=>o.jsxs("button",{className:`join-item btn btn-md sm:btn-sm ${n===s?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(s),children:[s,o.jsxs("span",{className:"hidden sm:inline",children:[" ",s===1?c.form.voucher.hourLabel:c.form.voucher.hoursLabel]})]},s))})]})}),!1]})}const We=new Map,le=new Map;async function S(e){return We.has(e)?We.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{We.set(e,a),t(a)},a.onerror=n,a.src=e})}function ie(e,t,n,a){e.drawImage(t,0,0,n,a)}async function xt(e,t,n,a){if(t>=155&&t<=165)return S(e);const r=`${e}:${t}:${n}x${a}`;if(le.has(r))return S(le.get(r));const c=await S(e),l=document.createElement("canvas");l.width=n,l.height=a;const s=l.getContext("2d");if(!s)throw new Error("Failed to get canvas context");s.drawImage(c,0,0,n,a);const i=l.toDataURL("image/png"),u=await gt(i,t);if(le.size>20){const h=le.keys().next().value;h&&le.delete(h)}return le.set(r,u),S(u)}function wn(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 wt(e,t,n,a,r,c,l=1,s=0,i=0){e.save(),e.beginPath(),e.ellipse(n,a,r,c,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,h=r/c,x=r*2,p=c*2;let f,y;u>h?(y=p,f=p*u):(f=x,y=x/u),f*=l,y*=l;const w=Math.max(0,(f-x)/2),g=Math.max(0,(y-p)/2),I=n-f/2+s*w,k=a-y/2+i*g;e.drawImage(t,I,k,f,y),e.restore()}function Ze(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 yt(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,l=t.split(" "),s=[];let i="";for(const x of l){const p=i?`${i} ${x}`:x;e.measureText(p).width>r&&i?(s.push(i),i=x):i=p}i&&s.push(i);const u=s.length*c;let h=n.y-u/2;for(const x of s)e.fillText(x,n.x,h),h+=c;e.restore()}function vt(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 l=r.lineHeight||r.fontSize*1.8,s=[t,n,a].filter(Boolean),i=(s.length-1)*l;let u=r.y-i/2;for(const h of s)h&&(e.fillText(h,r.x,u),u+=l);e.restore()}function yn(e,t,n,a="#2a3a2a"){e.save(),e.strokeStyle=a,e.lineWidth=Math.max(2,t.labelFontSize/16),e.beginPath(),e.moveTo(t.x-t.width/2,t.y),e.lineTo(t.x+t.width/2,t.y),e.stroke(),e.font=`${t.labelFontSize}px "Times New Roman", serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=a,e.fillText(n,t.x,t.y+t.labelFontSize*.3),e.restore()}async function kt(e,t,n,a,r,c,l,s,i,u=1,h=0,x=0,p=0,f=1,y="de"){const w=e.getContext("2d");if(!w)return;const g=document.createElement("canvas");g.width=s,g.height=i;const I=g.getContext("2d");if(!I)return;I.clearRect(0,0,s,i);const k=await xt(t,p,s,i);ie(I,k,s,i);const T=await S(n);if(ie(I,T,s,i),r)try{const j=await S(r);wt(I,j,l.portrait.x,l.portrait.y,l.portrait.radiusX,l.portrait.radiusY,u,h,x)}catch(j){console.error("Failed to load portrait:",j)}else wn(I,l.portrait.x,l.portrait.y,l.portrait.radiusX,l.portrait.radiusY,y);const P=await S(a);ie(I,P,s,i);const C=s/3633;St(I,f,y,C),c&&Ze(I,c,l.namePlate),e.width=s,e.height=i,w.drawImage(g,0,0)}async function It(e,t,n,a,r,c,l,s,i,u,h,x=0,p=1,f="de"){const y=e.getContext("2d");if(!y)return;const w=document.createElement("canvas");w.width=u,w.height=h;const g=w.getContext("2d");if(!g)return;g.clearRect(0,0,u,h);const I=await xt(t,x,u,h);ie(g,I,u,h);const k=await S(n);ie(g,k,u,h);const T=await S(a);ie(g,T,u,h);const P=u/3633;if(St(g,p,f,P),i.contactInfo&&(r||c||l)&&vt(g,r,c,l,i.contactInfo),i.description&&s&&yt(g,s,i.description),r&&Ze(g,r,i.namePlate),i.signature){const C=f==="de"?"Unterschrift":"Signature";yn(g,i.signature,C)}e.width=u,e.height=h,y.drawImage(w,0,0)}const me=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",F={background:`${me}templates/background.webp`,frontFrame:`${me}templates/front_frame.webp`,backFrame:`${me}templates/back_frame.webp`},he={1:`${me}templates/1.png`,5:`${me}templates/5.png`,10:`${me}templates/10.png`},Tt={de:{banner:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"}},en:{banner:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}}},Q=3633,ee=1920,je=.5,vn=Math.round(Q*je),kn=Math.round(ee*je),Et=320,Pt=335,$={badges:{topLeft:{x:286,y:235},topRight:{x:3340,y:230},bottomLeft:{x:282,y:1665},bottomRight:{x:3345,y:1665}},banner:{centerX:1816,centerY:3820,radius:3610,fontSize:103,color:"#2a3a2a"}},Pe=new Map,oe=new Map,$e=new Map,Fe=new Map,Oe=new Map;function Lt(e,t,n,a,r,c,l){e.save(),e.font=`900 ${c}px "Times New Roman", Georgia, serif`,e.fillStyle=l,e.textAlign="center",e.textBaseline="middle";const i=e.measureText(t).width/r,u=-Math.PI/2-i/2,h=t.split(""),x=[];for(const f of h)x.push(e.measureText(f).width);let p=u;for(let f=0;f<h.length;f++){const y=h[f],w=x[f],g=p+w/2/r,I=n+r*Math.cos(g),k=a+r*Math.sin(g);e.save(),e.translate(I,k),e.rotate(g+Math.PI/2),e.fillText(y,0,0),e.restore(),p+=w/r}e.restore()}let Y={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function In(){const[e,t,n,a,r,c]=await Promise.all([S(F.background),S(F.frontFrame),S(F.backFrame),S(he[1]),S(he[5]),S(he[10])]);Y={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:c}}}function Tn(e,t){const n=Math.round(Q*e),a=Math.round(ee*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 l=e<1?.8:.95;return r.toDataURL("image/jpeg",l)}function En(e,t){const n=Math.round(Q*e),a=Math.round(ee*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 l=Et*e,s=Pt*e,i=$.badges,u=(h,x)=>{const p=x/2,f=h.x*e-p,y=h.y*e-p;c.drawImage(t,f,y,x,x)};return u(i.topLeft,l),u(i.topRight,l),u(i.bottomLeft,s),u(i.bottomRight,s),r.toDataURL("image/png")}function St(e,t,n,a=1){const r=Tt[n].banner[t];Lt(e,r,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}function Ct(e,t,n,a,r,c,l){const s=Math.round(Q*a),i=Math.round(ee*a),u=document.createElement("canvas");u.width=s,u.height=i;const h=u.getContext("2d");if(!h)throw new Error("Failed to get canvas context");h.drawImage(r,0,0,s,i);{const p=Et*a,f=Pt*a,y=$.badges,w=(g,I)=>{const k=I/2,T=g.x*a-k,P=g.y*a-k;h.drawImage(l,T,P,I,I)};w(y.topLeft,p),w(y.topRight,p),w(y.bottomLeft,f),w(y.bottomRight,f)}if(h.drawImage(c,0,0,s,i),n==="front"){const p=Tt[t].banner[e];Lt(h,p,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}const x=a<1?.8:.95;return u.toDataURL("image/jpeg",x)}async function jt(e,t,n){const a=`${e}-${t}-${n}`;if(Pe.has(a))return Pe.get(a);const r=Y.background||await S(F.background),c=n==="front"?Y.frontFrame||await S(F.frontFrame):Y.backFrame||await S(F.backFrame),l=Y.badges[e]||await S(he[e]),s=Ct(e,t,n,je,r,c,l);return Pe.set(a,s),s}async function Xe(e,t,n){const a=`${e}-${t}-${n}`;if(oe.has(a))return oe.get(a);const r=Y.background||await S(F.background),c=n==="front"?Y.frontFrame||await S(F.frontFrame):Y.backFrame||await S(F.backFrame),l=Y.badges[e]||await S(he[e]),s=Ct(e,t,n,1,r,c,l);if(oe.size>4){const i=oe.keys().next().value;i&&oe.delete(i)}return oe.set(a,s),s}function Pn(){return{width:Q,height:ee}}function Ln(){Pe.clear(),oe.clear(),$e.clear(),Fe.clear(),Oe.clear()}async function Ve(e,t,n="front",a=je){const r=`bg-${a}`;let c=$e.get(r);if(!c){const h=Y.background||await S(F.background);c=Tn(a,h),$e.set(r,c)}const l=`badges-${e}-${a}`;let s=Fe.get(l);if(!s){const h=Y.badges[e]||await S(he[e]);s=En(a,h),Fe.set(l,s)}const i=`${n}-${a}`;let u=Oe.get(i);if(!u){const h=n==="front"?Y.frontFrame||await S(F.frontFrame):Y.backFrame||await S(F.backFrame),x=Math.round(Q*a),p=Math.round(ee*a),f=document.createElement("canvas");f.width=x,f.height=p;const y=f.getContext("2d");if(!y)throw new Error("Failed to get canvas context");y.drawImage(h,0,0,x,p),u=f.toDataURL("image/png"),Oe.set(i,u)}return{background:c,badges:s,frame:u}}async function Sn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const c of t)for(const l of n)a.push(jt(r,c,l));await Promise.all(a)}function Je(e,t){return{front:"",back:"",width:Q,height:ee}}const Re={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},ue=Re,de=Re;function Qe(e){return Re}const Ke=.75;function Cn(e){const t=Qe(),n=Ke,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 jn(e,t){const n=Je();return{...n,width:Math.round(n.width*Ke),height:Math.round(n.height*Ke)}}function Rn(e,t){const[n,a]=d.useState(e);return d.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Bn({onPortraitClick:e,onFileDrop:t}={}){const n=v(m=>m.appLanguage),a=v(m=>m.voucherConfig.language),r=v(m=>m.voucherConfig.hours),c=v(m=>m.voucherConfig.description),l=v(m=>m.voucherConfig.templateHue),s=v(m=>m.personalInfo),i=v(m=>m.portrait),u=v(m=>m.currentSide),h=v(m=>m.flipSide),x=v(m=>m.setPortraitPan),p=Rn(l,150),f=J(n),y=d.useRef(null),w=d.useRef(null),g=d.useRef(null),[I,k]=d.useState(!1),[T,P]=d.useState(!1),[C,j]=d.useState(!1),[N,H]=d.useState(!1),L=d.useRef(null),R=jn(),M=Cn(),K=i.useEnhanced&&i.enhanced?i.enhanced:i.original,te=qe(a,r,c),[G,W]=d.useState(""),[z,O]=d.useState(""),[ne,Ne]=d.useState(""),[fe,He]=d.useState(""),[be,ae]=d.useState(""),[se,re]=d.useState(""),[ve,ke]=d.useState(!0);d.useEffect(()=>{let m=!0;ke(!0);async function D(){const[U,Z]=await Promise.all([Ve(r,a,"front"),Ve(r,a,"back")]);m&&(W(U.background),O(U.badges),Ne(U.frame),He(Z.background),ae(Z.badges),re(Z.frame),ke(!1))}return D(),()=>{m=!1}},[r,a]),d.useEffect(()=>{!y.current||!G||!z||!ne||kt(y.current,G,z,ne,K,s.name,M.front,R.width,R.height,i.zoom,i.panX,i.panY,p,r,a)},[R,G,z,ne,K,s.name,M,i.zoom,i.panX,i.panY,p,r,a]),d.useEffect(()=>{!w.current||!fe||!be||!se||It(w.current,fe,be,se,s.name,s.email,s.phone,te,M.back,R.width,R.height,p,r,a)},[R,fe,be,se,s,te,M,p,r,a]);const xe=()=>{k(!I),h()};d.useEffect(()=>{k(u==="back")},[u]);const q=d.useCallback((m,D)=>{if(!g.current||u!=="front")return!1;const U=g.current.getBoundingClientRect(),Z=U.width/R.width,De=U.height/R.height,Me=(m-U.left)/Z,Ae=(D-U.top)/De,{x:Ue,y:_t,radiusX:$t,radiusY:Ft}=M.front.portrait,tt=(Me-Ue)/$t,nt=(Ae-_t)/Ft;return tt*tt+nt*nt<=1},[u,R.width,R.height,M.front.portrait]),Ie=d.useCallback((m,D)=>{!i.original||i.zoom<=1||!q(m,D)||(P(!0),L.current={x:m,y:D,panX:i.panX,panY:i.panY})},[i.original,i.zoom,i.panX,i.panY,q]),Te=d.useCallback((m,D)=>{if(!T||!L.current||!g.current)return;const U=g.current.getBoundingClientRect(),Z=3/Math.max(U.width,U.height),De=(m-L.current.x)*Z,Me=(D-L.current.y)*Z,Ae=Math.max(-1,Math.min(1,L.current.panX+De)),Ue=Math.max(-1,Math.min(1,L.current.panY+Me));x(Ae,Ue)},[T,x]),b=d.useCallback(()=>{P(!1),L.current=null},[]),E=d.useCallback((m,D)=>{!i.original&&q(m,D)&&e&&e()},[i.original,q,e]),A=m=>{q(m.clientX,m.clientY)&&(m.preventDefault(),i.original&&i.zoom>1&&Ie(m.clientX,m.clientY))},B=m=>{T||E(m.clientX,m.clientY)},X=m=>{Te(m.clientX,m.clientY),j(q(m.clientX,m.clientY))},_=()=>b(),Mt=()=>{b(),j(!1)},At=m=>{if(m.touches.length===1){const D=m.touches[0];i.zoom>1&&q(D.clientX,D.clientY)&&Ie(D.clientX,D.clientY)}},Ut=m=>{m.touches.length===1&&Te(m.touches[0].clientX,m.touches[0].clientY)},Yt=()=>b(),et=d.useRef(!1);d.useEffect(()=>{et.current=T},[T]),d.useEffect(()=>{const m=g.current;if(!m)return;const D=U=>{et.current&&U.preventDefault()};return m.addEventListener("touchmove",D,{passive:!1}),()=>{m.removeEventListener("touchmove",D)}},[]);const Wt=u==="front"&&i.original&&i.zoom>1,zt=R.width/R.height;return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex justify-between items-center",children:[o.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${u==="front"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="front"&&xe(),children:f.preview.front}),o.jsx("button",{className:`join-item btn btn-md sm:btn-sm ${u==="back"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="back"&&xe(),children:f.preview.back})]}),o.jsxs("button",{className:"btn btn-ghost btn-md sm:btn-sm",onClick:xe,children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),o.jsx("span",{className:"hidden sm:inline",children:f.preview.flip})]})]}),o.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:zt,perspective:"1500px"},children:[ve&&o.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),o.jsxs("div",{ref:g,className:`relative w-full h-full shadow-lg ${C&&Wt?T?"cursor-grabbing":"cursor-grab":""} ${ve?"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:X,onMouseUp:_,onMouseLeave:Mt,onTouchStart:At,onTouchMove:Ut,onTouchEnd:Yt,children:[o.jsx("canvas",{ref:y,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),o.jsx("canvas",{ref:w,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),!i.original&&u==="front"&&(e||t)&&o.jsx("div",{className:`absolute flex flex-col items-center justify-center cursor-pointer transition-colors duration-300 ease-in-out ${N?"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(),H(!0)},onDragLeave:m=>{m.preventDefault(),m.stopPropagation(),H(!1)},onDrop:m=>{m.preventDefault(),m.stopPropagation(),H(!1);const D=m.dataTransfer.files[0];D&&D.type.startsWith("image/")&&t&&t(D)},children:o.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 relative 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:[o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"absolute top-1 right-1 sm:top-1.5 sm:right-1.5 w-3 h-3 sm:w-4 sm:h-4 text-base-content/60",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,strokeLinecap:"round",strokeLinejoin:"round",children:[o.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),o.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]}),o.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:[o.jsx("circle",{cx:"12",cy:"8",r:"4"}),o.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),o.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
|
|
2
|
+
hochladen`:`Upload
|
|
3
|
+
photo`})]})})]})]})]})}function Nn(){const e=d.useRef(null),t=d.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Hn=`
|
|
2
4
|
// RGB to HSL conversion
|
|
3
5
|
function rgbToHsl(r, g, b) {
|
|
4
6
|
r /= 255;
|
|
@@ -373,4 +375,4 @@ self.onmessage = async (e) => {
|
|
|
373
375
|
});
|
|
374
376
|
}
|
|
375
377
|
};
|
|
376
|
-
`;let ze=null,it=null;function Dn(){if(!ze){const e=new Blob([Hn],{type:"application/javascript"});it=URL.createObjectURL(e),ze=new Worker(it,{type:"module"})}return ze}async function _e(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function st(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 Rt(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:r,layout:c,portrait:l,portraitZoom:s=1,portraitPanX:i=0,portraitPanY:u=0,templateHue:h=160,name:x,email:p,phone:f,description:y,language:w="de"}=e,[g,I]=await Promise.all([_e(t),_e(n)]);let k=null;return l&&(k=await _e(l)),new Promise((T,P)=>{const C=Dn(),j=H=>{if(C.removeEventListener("message",j),C.removeEventListener("error",N),URL.revokeObjectURL(g),URL.revokeObjectURL(I),k&&URL.revokeObjectURL(k),H.data.type==="success")try{const{frontImageData:
|
|
378
|
+
`;let ze=null,it=null;function Dn(){if(!ze){const e=new Blob([Hn],{type:"application/javascript"});it=URL.createObjectURL(e),ze=new Worker(it,{type:"module"})}return ze}async function _e(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function st(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 Rt(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:r,layout:c,portrait:l,portraitZoom:s=1,portraitPanX:i=0,portraitPanY:u=0,templateHue:h=160,name:x,email:p,phone:f,description:y,language:w="de"}=e,[g,I]=await Promise.all([_e(t),_e(n)]);let k=null;return l&&(k=await _e(l)),new Promise((T,P)=>{const C=Dn(),j=H=>{if(C.removeEventListener("message",j),C.removeEventListener("error",N),URL.revokeObjectURL(g),URL.revokeObjectURL(I),k&&URL.revokeObjectURL(k),H.data.type==="success")try{const{frontImageData:L,backImageData:R,width:M,height:K}=H.data;if(!L||!R||!M||!K){P(new Error("Invalid response from worker"));return}const te=st(L,"image/jpeg"),G=st(R,"image/jpeg"),W=M/96*25.4,z=K/96*25.4,O=new Vt.jsPDF({orientation:W>z?"landscape":"portrait",unit:"mm",format:[W,z]});O.addImage(te,"JPEG",0,0,W,z),O.addPage([W,z]),O.addImage(G,"JPEG",0,0,W,z);const ne=O.output("blob");T(ne)}catch(L){P(L)}else P(new Error(H.data.error))},N=H=>{C.removeEventListener("message",j),C.removeEventListener("error",N),URL.revokeObjectURL(g),URL.revokeObjectURL(I),k&&URL.revokeObjectURL(k),P(new Error(H.message))};C.addEventListener("message",j),C.addEventListener("error",N),C.postMessage({type:"generate",frontTemplateUrl:g,backTemplateUrl:I,portraitUrl:k,templateWidth:a,templateHeight:r,templateHue:h,portraitZoom:s,portraitPanX:i,portraitPanY:u,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:p,phone:f,description:y,language:w})})}function Bt(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 Nt(e){const t=await Rt(e);Bt(t,e.filename)}function Mn(){const e=v(g=>g.appLanguage),t=v(g=>g.voucherConfig.language),n=v(g=>g.voucherConfig.hours),a=v(g=>g.voucherConfig.description),r=v(g=>g.voucherConfig.templateHue),c=v(g=>g.personalInfo),l=v(g=>g.portrait),s=v(g=>g.isExporting),i=v(g=>g.setIsExporting),u=J(e),h=Je(),x=Qe(),p=l.useEnhanced&&l.enhanced?l.enhanced:l.original,f=qe(t,n,a),y=c.name.trim().length>0&&c.email.trim().length>0&&c.phone.trim().length>0&&l.original!==null,w=async()=>{if(!(!y||s)){i(!0);try{const[g,I]=await Promise.all([Xe(n,t,"front"),Xe(n,t,"back")]),k=`zeitgutschein-${n}h-${c.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await Nt({frontTemplateSrc:g,backTemplateSrc:I,templateWidth:h.width,templateHeight:h.height,layout:x,portrait:p,portraitZoom:l.zoom,portraitPanX:l.panX,portraitPanY:l.panY,templateHue:r,name:c.name,email:c.email,phone:c.phone,description:f,filename:k,language:t})}catch(g){console.error("PDF export failed:",g)}finally{i(!1)}}};return o.jsxs("button",{className:`btn btn-primary w-full btn-lg sm:btn-md ${y?"":"btn-disabled"}`,onClick:w,disabled:!y,"aria-busy":s,children:[s?o.jsx("span",{className:"loading loading-spinner loading-sm"}):o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),u.export.button]})}function Ht(){const e=v(a=>a.appLanguage),t=v(a=>a.setAppLanguage),n=a=>{t(a)};return o.jsxs("div",{className:"join",children:[o.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),o.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function An(){const e=v(n=>n.appLanguage),t=J(e);return o.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[o.jsx("div",{className:"navbar-start",children:o.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),o.jsx("div",{className:"navbar-center hidden sm:flex",children:o.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),o.jsx("div",{className:"navbar-end",children:o.jsx(Ht,{})})]})}const Se="/",Un={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${Se}templates/front_hdpi_de.jpg`,back:`${Se}templates/back_hdpi_de.jpg`,width:6144,height:4096},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:ue.front.portrait,name:ue.front.namePlate},back:{name:ue.back.namePlate,contactInfo:ue.back.contactInfo,description:ue.back.description}},languages:["de"]},Yn={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${Se}templates/front_ldpi_en.png`,back:`${Se}templates/back_ldpi_en.png`,width:1536,height:1024},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:de.front.portrait,name:de.front.namePlate},back:{name:de.back.namePlate,contactInfo:de.back.contactInfo,description:de.back.description}},languages:["en"]},lt=[Un,Yn],Dt={async listTemplates(e){let t=[...lt];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=lt.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Wn(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let Be=Dt;function zn(e){Be=e}function _n(){return Be}async function $n(e){return Be.listTemplates(e)}async function Fn(e){return Be.getTemplate(e)}exports.ApiKeyModal=bt;exports.BillPreview=Bn;exports.ExportButton=Mn;exports.Header=An;exports.LAYOUT_HDPI=ue;exports.LAYOUT_LDPI=de;exports.LanguageToggle=Ht;exports.PREVIEW_HEIGHT=kn;exports.PREVIEW_WIDTH=vn;exports.PersonalInfoForm=en;exports.PortraitUpload=bn;exports.TEMPLATE_HEIGHT=ee;exports.TEMPLATE_LAYOUT=Re;exports.TEMPLATE_WIDTH=Q;exports.TouchSlider=we;exports.VoucherConfig=xn;exports.applyEngravingEffect=ut;exports.applyHueShift=gt;exports.clearCompositorCache=Ln;exports.composeTemplate=jt;exports.composeTemplateFullRes=Xe;exports.downloadBlob=Bt;exports.drawContactInfo=vt;exports.drawMultilineText=yt;exports.drawOvalPortrait=wt;exports.drawTemplate=ie;exports.drawText=Ze;exports.enhancePortrait=pn;exports.exportBillAsPDF=Nt;exports.formatDescription=qe;exports.generateBillPDF=Rt;exports.getApiKey=Ce;exports.getDefaultTemplateId=Wn;exports.getLayout=Qe;exports.getRemoveBackgroundEndpoint=un;exports.getTemplate=Je;exports.getTemplateById=Fn;exports.getTemplateDimensions=Pn;exports.getTemplateLayers=Ve;exports.getTemplateProvider=_n;exports.hasApiKey=Ee;exports.hasCustomEndpoint=dn;exports.listTemplates=$n;exports.loadImage=S;exports.preloadAllTemplates=Sn;exports.preloadBaseImages=In;exports.removeBackground=ft;exports.renderBackSide=It;exports.renderFrontSide=kt;exports.resizeImage=ct;exports.setApiKey=pt;exports.setRemoveBackgroundEndpoint=cn;exports.setTemplateProvider=zn;exports.staticTemplateProvider=Dt;exports.t=J;exports.useBillCanvasRefs=Nn;exports.useBillStore=v;
|
package/dist/index.js
CHANGED
|
@@ -430,8 +430,8 @@ async function Xt(e, t = 0.5, n = 40) {
|
|
|
430
430
|
if (u === 0) continue;
|
|
431
431
|
let k = (((77 * p + 150 * v + 29 * w >> 8) / 255 - 0.5) * o + 0.5) * 255;
|
|
432
432
|
k < 0 ? k = 0 : k > 255 && (k = 255);
|
|
433
|
-
const P = k / 255,
|
|
434
|
-
i[b] = u << 24 | N << 16 |
|
|
433
|
+
const P = k / 255, L = 0.12, [S, B, H] = ct(m, L, P), D = p * c + S * t | 0, E = v * c + B * t | 0, N = w * c + H * t | 0;
|
|
434
|
+
i[b] = u << 24 | N << 16 | E << 8 | D;
|
|
435
435
|
}
|
|
436
436
|
return r.putImageData(l, 0, 0), Z.toDataURL("image/png");
|
|
437
437
|
}
|
|
@@ -479,7 +479,7 @@ async function Kt(e, t) {
|
|
|
479
479
|
if (u === 0) continue;
|
|
480
480
|
const [I, k, P] = _t(p, v, w);
|
|
481
481
|
if (k < 0.08 || I < o || I > c) continue;
|
|
482
|
-
const
|
|
482
|
+
const L = i, S = Math.min(k, 0.05), [B, H, D] = ct(L, S, P);
|
|
483
483
|
s[b] = u << 24 | D << 16 | H << 8 | B;
|
|
484
484
|
}
|
|
485
485
|
return a.putImageData(r, 0, 0), Z.toDataURL("image/png");
|
|
@@ -715,7 +715,7 @@ function an({ isOpen: e, onClose: t, onSubmit: n }) {
|
|
|
715
715
|
/* @__PURE__ */ d("form", { method: "dialog", className: "modal-backdrop", children: /* @__PURE__ */ d("button", { onClick: t, children: "close" }) })
|
|
716
716
|
] });
|
|
717
717
|
}
|
|
718
|
-
function
|
|
718
|
+
function Ee({
|
|
719
719
|
min: e,
|
|
720
720
|
max: t,
|
|
721
721
|
step: n,
|
|
@@ -726,7 +726,7 @@ function Le({
|
|
|
726
726
|
}) {
|
|
727
727
|
const i = z(null), o = z(null), c = z(!1), [m, b] = A(!1), h = (a - e) / (t - e) * 100, p = U((k) => {
|
|
728
728
|
if (!i.current) return a;
|
|
729
|
-
const P = i.current.getBoundingClientRect(),
|
|
729
|
+
const P = i.current.getBoundingClientRect(), L = Math.max(0, Math.min(1, (k - P.left) / P.width)), S = t - e, B = e + L * S, H = Math.round(B / n) * n;
|
|
730
730
|
return Math.max(e, Math.min(t, H));
|
|
731
731
|
}, [e, t, n, a]), v = U((k) => {
|
|
732
732
|
if (s) return;
|
|
@@ -739,10 +739,10 @@ function Le({
|
|
|
739
739
|
}, c.current = !1;
|
|
740
740
|
}, [a, s]), w = U((k) => {
|
|
741
741
|
if (s || !o.current) return;
|
|
742
|
-
const P = k.touches[0],
|
|
742
|
+
const P = k.touches[0], L = Math.abs(P.clientX - o.current.x), S = Math.abs(P.clientY - o.current.y);
|
|
743
743
|
if (!o.current.decided) {
|
|
744
|
-
if (
|
|
745
|
-
if (o.current.decided = !0, S >
|
|
744
|
+
if (L < 8 && S < 8) return;
|
|
745
|
+
if (o.current.decided = !0, S > L) {
|
|
746
746
|
o.current = null;
|
|
747
747
|
return;
|
|
748
748
|
}
|
|
@@ -758,8 +758,8 @@ function Le({
|
|
|
758
758
|
F(() => {
|
|
759
759
|
const k = i.current;
|
|
760
760
|
if (!k) return;
|
|
761
|
-
const P = (
|
|
762
|
-
|
|
761
|
+
const P = (L) => {
|
|
762
|
+
L.preventDefault();
|
|
763
763
|
};
|
|
764
764
|
return k.addEventListener("touchstart", P, { passive: !1 }), k.addEventListener("touchmove", P, { passive: !1 }), () => {
|
|
765
765
|
k.removeEventListener("touchstart", P), k.removeEventListener("touchmove", P);
|
|
@@ -769,13 +769,13 @@ function Le({
|
|
|
769
769
|
if (s) return;
|
|
770
770
|
const P = p(k.clientX);
|
|
771
771
|
r(P), b(!0);
|
|
772
|
-
const
|
|
772
|
+
const L = (B) => {
|
|
773
773
|
const H = p(B.clientX);
|
|
774
774
|
r(H);
|
|
775
775
|
}, S = () => {
|
|
776
|
-
b(!1), document.removeEventListener("mousemove",
|
|
776
|
+
b(!1), document.removeEventListener("mousemove", L), document.removeEventListener("mouseup", S);
|
|
777
777
|
};
|
|
778
|
-
document.addEventListener("mousemove",
|
|
778
|
+
document.addEventListener("mousemove", L), document.addEventListener("mouseup", S);
|
|
779
779
|
}, [s, p, r]);
|
|
780
780
|
return /* @__PURE__ */ y(
|
|
781
781
|
"div",
|
|
@@ -807,7 +807,7 @@ function Le({
|
|
|
807
807
|
);
|
|
808
808
|
}
|
|
809
809
|
function Un() {
|
|
810
|
-
const e = x((f) => f.appLanguage), t = x((f) => f.portrait), n = x((f) => f.setPortrait), a = x((f) => f.setPortraitZoom), r = x((f) => f.setPortraitPan), l = x((f) => f.setPortraitRawImage), s = x((f) => f.setPortraitBgRemoved), i = x((f) => f.setPortraitBgOpacity), o = x((f) => f.setPortraitBgBlur), c = x((f) => f.setPortraitEngravingIntensity), { enhance: m, removeBg: b, isEnhancing: h, isRemovingBg: p, error: v, hasKey: w, setApiKey: u } = nn(), I = se(e), k = z(null), [P,
|
|
810
|
+
const e = x((f) => f.appLanguage), t = x((f) => f.portrait), n = x((f) => f.setPortrait), a = x((f) => f.setPortraitZoom), r = x((f) => f.setPortraitPan), l = x((f) => f.setPortraitRawImage), s = x((f) => f.setPortraitBgRemoved), i = x((f) => f.setPortraitBgOpacity), o = x((f) => f.setPortraitBgBlur), c = x((f) => f.setPortraitEngravingIntensity), { enhance: m, removeBg: b, isEnhancing: h, isRemovingBg: p, error: v, hasKey: w, setApiKey: u } = nn(), I = se(e), k = z(null), [P, L] = A(!1), [S, B] = A(!1), H = z(null), D = z(null), E = t.rawImage, N = t.bgRemovedImage, Y = t.bgRemoved, J = t.bgOpacity, ne = t.bgBlur, ee = t.engravingIntensity;
|
|
811
811
|
F(() => {
|
|
812
812
|
t.original && !t.rawImage && l(t.original);
|
|
813
813
|
}, [t.original, t.rawImage, l]), F(() => () => {
|
|
@@ -827,15 +827,15 @@ function Un() {
|
|
|
827
827
|
[n, l, s, c]
|
|
828
828
|
), ae = U(
|
|
829
829
|
(f) => {
|
|
830
|
-
f.preventDefault(),
|
|
830
|
+
f.preventDefault(), L(!1);
|
|
831
831
|
const T = f.dataTransfer.files[0];
|
|
832
832
|
T && q(T);
|
|
833
833
|
},
|
|
834
834
|
[q]
|
|
835
835
|
), He = U((f) => {
|
|
836
|
-
f.preventDefault(),
|
|
836
|
+
f.preventDefault(), L(!0);
|
|
837
837
|
}, []), be = U((f) => {
|
|
838
|
-
f.preventDefault(),
|
|
838
|
+
f.preventDefault(), L(!1);
|
|
839
839
|
}, []), De = () => {
|
|
840
840
|
var f;
|
|
841
841
|
(f = k.current) == null || f.click();
|
|
@@ -869,36 +869,36 @@ function Un() {
|
|
|
869
869
|
f.engravingIntensity > 0 && f.rawImage && (H.current && clearTimeout(H.current), H.current = setTimeout(oe, 150));
|
|
870
870
|
}, [X, oe]);
|
|
871
871
|
const Ie = async () => {
|
|
872
|
-
if (!
|
|
872
|
+
if (!E) return;
|
|
873
873
|
if (!Y && !w) {
|
|
874
874
|
B(!0);
|
|
875
875
|
return;
|
|
876
876
|
}
|
|
877
877
|
if (!Y) {
|
|
878
|
-
const T = await de(
|
|
879
|
-
let j = await We(T,
|
|
878
|
+
const T = await de(E), W = x.getState(), R = W.portrait, G = W.voucherConfig.templateHue;
|
|
879
|
+
let j = await We(T, E, R.bgOpacity, R.bgBlur);
|
|
880
880
|
R.engravingIntensity > 0 && (j = await re(j, R.engravingIntensity, G)), n(j);
|
|
881
881
|
} else {
|
|
882
882
|
s(!1, null);
|
|
883
883
|
const T = x.getState(), W = T.portrait.engravingIntensity, R = T.voucherConfig.templateHue;
|
|
884
884
|
if (W > 0) {
|
|
885
|
-
const G = await re(
|
|
885
|
+
const G = await re(E, W, R);
|
|
886
886
|
n(G);
|
|
887
887
|
} else
|
|
888
|
-
n(
|
|
888
|
+
n(E);
|
|
889
889
|
}
|
|
890
890
|
}, Pe = (f) => {
|
|
891
|
-
c(f), H.current && clearTimeout(H.current),
|
|
891
|
+
c(f), H.current && clearTimeout(H.current), E && (H.current = setTimeout(oe, 150));
|
|
892
892
|
}, ye = async (f) => {
|
|
893
|
-
if (u(f), !
|
|
894
|
-
const T = await de(
|
|
895
|
-
let j = await We(T,
|
|
893
|
+
if (u(f), !E) return;
|
|
894
|
+
const T = await de(E), W = x.getState(), R = W.portrait, G = W.voucherConfig.templateHue;
|
|
895
|
+
let j = await We(T, E, R.bgOpacity, R.bgBlur);
|
|
896
896
|
R.engravingIntensity > 0 && (j = await re(j, R.engravingIntensity, G)), n(j);
|
|
897
897
|
}, Q = (f) => {
|
|
898
|
-
i(f), D.current && clearTimeout(D.current), !(!
|
|
898
|
+
i(f), D.current && clearTimeout(D.current), !(!E || !N) && (D.current = setTimeout(oe, 150));
|
|
899
899
|
}, Te = (f) => {
|
|
900
|
-
o(f), D.current && clearTimeout(D.current), !(!
|
|
901
|
-
},
|
|
900
|
+
o(f), D.current && clearTimeout(D.current), !(!E || !N) && (D.current = setTimeout(oe, 150));
|
|
901
|
+
}, Le = () => {
|
|
902
902
|
n(null), l(null), s(!1, null), i(0), o(0), c(0), Ft();
|
|
903
903
|
};
|
|
904
904
|
return /* @__PURE__ */ y("div", { className: "space-y-4", children: [
|
|
@@ -909,7 +909,7 @@ function Un() {
|
|
|
909
909
|
"button",
|
|
910
910
|
{
|
|
911
911
|
className: "btn btn-xs btn-ghost text-error",
|
|
912
|
-
onClick:
|
|
912
|
+
onClick: Le,
|
|
913
913
|
children: [
|
|
914
914
|
/* @__PURE__ */ d(
|
|
915
915
|
"svg",
|
|
@@ -945,7 +945,7 @@ function Un() {
|
|
|
945
945
|
] })
|
|
946
946
|
] }),
|
|
947
947
|
/* @__PURE__ */ d(
|
|
948
|
-
|
|
948
|
+
Ee,
|
|
949
949
|
{
|
|
950
950
|
min: 0.5,
|
|
951
951
|
max: 2,
|
|
@@ -970,7 +970,7 @@ function Un() {
|
|
|
970
970
|
] })
|
|
971
971
|
] }),
|
|
972
972
|
/* @__PURE__ */ d(
|
|
973
|
-
|
|
973
|
+
Ee,
|
|
974
974
|
{
|
|
975
975
|
min: 0,
|
|
976
976
|
max: 1,
|
|
@@ -978,7 +978,7 @@ function Un() {
|
|
|
978
978
|
value: ee,
|
|
979
979
|
onChange: Pe,
|
|
980
980
|
className: "range range-secondary range-sm",
|
|
981
|
-
disabled: h || !
|
|
981
|
+
disabled: h || !E
|
|
982
982
|
}
|
|
983
983
|
)
|
|
984
984
|
] })
|
|
@@ -995,7 +995,7 @@ function Un() {
|
|
|
995
995
|
] })
|
|
996
996
|
] }),
|
|
997
997
|
/* @__PURE__ */ d(
|
|
998
|
-
|
|
998
|
+
Ee,
|
|
999
999
|
{
|
|
1000
1000
|
min: 0,
|
|
1001
1001
|
max: 1,
|
|
@@ -1015,7 +1015,7 @@ function Un() {
|
|
|
1015
1015
|
] })
|
|
1016
1016
|
] }),
|
|
1017
1017
|
/* @__PURE__ */ d(
|
|
1018
|
-
|
|
1018
|
+
Ee,
|
|
1019
1019
|
{
|
|
1020
1020
|
min: 0,
|
|
1021
1021
|
max: 1,
|
|
@@ -1038,7 +1038,7 @@ function Un() {
|
|
|
1038
1038
|
className: `toggle toggle-primary ${p ? "opacity-50" : ""}`,
|
|
1039
1039
|
checked: Y,
|
|
1040
1040
|
onChange: Ie,
|
|
1041
|
-
disabled: p || !
|
|
1041
|
+
disabled: p || !E
|
|
1042
1042
|
}
|
|
1043
1043
|
),
|
|
1044
1044
|
/* @__PURE__ */ y("span", { className: "label-text flex items-center gap-2", children: [
|
|
@@ -1268,8 +1268,8 @@ async function dn(e, t, n, a, r, l, s, i, o, c = 1, m = 0, b = 0, h = 0, p = 1,
|
|
|
1268
1268
|
s.portrait.radiusY,
|
|
1269
1269
|
v
|
|
1270
1270
|
);
|
|
1271
|
-
const
|
|
1272
|
-
me(I,
|
|
1271
|
+
const L = await C(a);
|
|
1272
|
+
me(I, L, i, o);
|
|
1273
1273
|
const S = i / 3633;
|
|
1274
1274
|
wt(I, p, v, S), l && mt(I, l, s.namePlate), e.width = i, e.height = o, w.drawImage(u, 0, 0);
|
|
1275
1275
|
}
|
|
@@ -1287,8 +1287,8 @@ async function un(e, t, n, a, r, l, s, i, o, c, m, b = 0, h = 1, p = "de") {
|
|
|
1287
1287
|
me(u, k, c, m);
|
|
1288
1288
|
const P = await C(a);
|
|
1289
1289
|
me(u, P, c, m);
|
|
1290
|
-
const
|
|
1291
|
-
if (wt(u, h, p,
|
|
1290
|
+
const L = c / 3633;
|
|
1291
|
+
if (wt(u, h, p, L), o.contactInfo && (r || l || s) && ln(u, r, l, s, o.contactInfo), o.description && i && sn(u, i, o.description), r && mt(u, r, o.namePlate), o.signature) {
|
|
1292
1292
|
const S = p === "de" ? "Unterschrift" : "Signature";
|
|
1293
1293
|
cn(u, o.signature, S);
|
|
1294
1294
|
}
|
|
@@ -1411,8 +1411,8 @@ function yt(e, t, n, a, r, l, s) {
|
|
|
1411
1411
|
m.drawImage(r, 0, 0, i, o);
|
|
1412
1412
|
{
|
|
1413
1413
|
const h = pt * a, p = ft * a, v = V.badges, w = (u, I) => {
|
|
1414
|
-
const k = I / 2, P = u.x * a - k,
|
|
1415
|
-
m.drawImage(s, P,
|
|
1414
|
+
const k = I / 2, P = u.x * a - k, L = u.y * a - k;
|
|
1415
|
+
m.drawImage(s, P, L, I, I);
|
|
1416
1416
|
};
|
|
1417
1417
|
w(v.topLeft, h), w(v.topRight, h), w(v.bottomLeft, p), w(v.bottomRight, p);
|
|
1418
1418
|
}
|
|
@@ -1624,7 +1624,7 @@ function bn(e, t) {
|
|
|
1624
1624
|
}, [e, t]), n;
|
|
1625
1625
|
}
|
|
1626
1626
|
function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
1627
|
-
const n = x((g) => g.appLanguage), a = x((g) => g.voucherConfig.language), r = x((g) => g.voucherConfig.hours), l = x((g) => g.voucherConfig.description), s = x((g) => g.voucherConfig.templateHue), i = x((g) => g.personalInfo), o = x((g) => g.portrait), c = x((g) => g.currentSide), m = x((g) => g.flipSide), b = x((g) => g.setPortraitPan), h = bn(s, 150), p = se(n), v = z(null), w = z(null), u = z(null), [I, k] = A(!1), [P,
|
|
1627
|
+
const n = x((g) => g.appLanguage), a = x((g) => g.voucherConfig.language), r = x((g) => g.voucherConfig.hours), l = x((g) => g.voucherConfig.description), s = x((g) => g.voucherConfig.templateHue), i = x((g) => g.personalInfo), o = x((g) => g.portrait), c = x((g) => g.currentSide), m = x((g) => g.flipSide), b = x((g) => g.setPortraitPan), h = bn(s, 150), p = se(n), v = z(null), w = z(null), u = z(null), [I, k] = A(!1), [P, L] = A(!1), [S, B] = A(!1), [H, D] = A(!1), E = z(null), N = fn(), Y = pn(), J = o.useEnhanced && o.enhanced ? o.enhanced : o.original, ne = lt(a, r, l), [ee, X] = A(""), [_, q] = A(""), [ae, He] = A(""), [be, De] = A(""), [we, re] = A(""), [de, oe] = A(""), [Ie, Pe] = A(!0);
|
|
1628
1628
|
F(() => {
|
|
1629
1629
|
let g = !0;
|
|
1630
1630
|
Pe(!0);
|
|
@@ -1685,18 +1685,18 @@ function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
|
1685
1685
|
const $ = u.current.getBoundingClientRect(), te = $.width / N.width, Me = $.height / N.height, Ae = (g - $.left) / te, Ue = (M - $.top) / Me, { x: Ye, y: St, radiusX: Ct, radiusY: Bt } = Y.front.portrait, Je = (Ae - Ye) / Ct, Qe = (Ue - St) / Bt;
|
|
1686
1686
|
return Je * Je + Qe * Qe <= 1;
|
|
1687
1687
|
}, [c, N.width, N.height, Y.front.portrait]), Te = U((g, M) => {
|
|
1688
|
-
!o.original || o.zoom <= 1 || !Q(g, M) || (
|
|
1688
|
+
!o.original || o.zoom <= 1 || !Q(g, M) || (L(!0), E.current = {
|
|
1689
1689
|
x: g,
|
|
1690
1690
|
y: M,
|
|
1691
1691
|
panX: o.panX,
|
|
1692
1692
|
panY: o.panY
|
|
1693
1693
|
});
|
|
1694
|
-
}, [o.original, o.zoom, o.panX, o.panY, Q]),
|
|
1695
|
-
if (!P || !
|
|
1696
|
-
const $ = u.current.getBoundingClientRect(), te = 3 / Math.max($.width, $.height), Me = (g -
|
|
1694
|
+
}, [o.original, o.zoom, o.panX, o.panY, Q]), Le = U((g, M) => {
|
|
1695
|
+
if (!P || !E.current || !u.current) return;
|
|
1696
|
+
const $ = u.current.getBoundingClientRect(), te = 3 / Math.max($.width, $.height), Me = (g - E.current.x) * te, Ae = (M - E.current.y) * te, Ue = Math.max(-1, Math.min(1, E.current.panX + Me)), Ye = Math.max(-1, Math.min(1, E.current.panY + Ae));
|
|
1697
1697
|
b(Ue, Ye);
|
|
1698
1698
|
}, [P, b]), f = U(() => {
|
|
1699
|
-
|
|
1699
|
+
L(!1), E.current = null;
|
|
1700
1700
|
}, []), T = U((g, M) => {
|
|
1701
1701
|
!o.original && Q(g, M) && e && e();
|
|
1702
1702
|
}, [o.original, Q, e]), W = (g) => {
|
|
@@ -1704,7 +1704,7 @@ function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
|
1704
1704
|
}, R = (g) => {
|
|
1705
1705
|
P || T(g.clientX, g.clientY);
|
|
1706
1706
|
}, G = (g) => {
|
|
1707
|
-
|
|
1707
|
+
Le(g.clientX, g.clientY), B(Q(g.clientX, g.clientY));
|
|
1708
1708
|
}, j = () => f(), kt = () => {
|
|
1709
1709
|
f(), B(!1);
|
|
1710
1710
|
}, It = (g) => {
|
|
@@ -1713,7 +1713,7 @@ function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
|
1713
1713
|
o.zoom > 1 && Q(M.clientX, M.clientY) && Te(M.clientX, M.clientY);
|
|
1714
1714
|
}
|
|
1715
1715
|
}, Pt = (g) => {
|
|
1716
|
-
g.touches.length === 1 &&
|
|
1716
|
+
g.touches.length === 1 && Le(g.touches[0].clientX, g.touches[0].clientY);
|
|
1717
1717
|
}, Tt = () => f(), Ze = z(!1);
|
|
1718
1718
|
F(() => {
|
|
1719
1719
|
Ze.current = P;
|
|
@@ -1727,7 +1727,7 @@ function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
|
1727
1727
|
g.removeEventListener("touchmove", M);
|
|
1728
1728
|
};
|
|
1729
1729
|
}, []);
|
|
1730
|
-
const
|
|
1730
|
+
const Lt = c === "front" && o.original && o.zoom > 1, Et = N.width / N.height;
|
|
1731
1731
|
return /* @__PURE__ */ y("div", { className: "space-y-4", children: [
|
|
1732
1732
|
/* @__PURE__ */ y("div", { className: "flex justify-between items-center", children: [
|
|
1733
1733
|
/* @__PURE__ */ y("div", { className: "join border border-base-300 rounded-lg", children: [
|
|
@@ -1775,14 +1775,14 @@ function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
|
1775
1775
|
"div",
|
|
1776
1776
|
{
|
|
1777
1777
|
className: "relative w-full overflow-visible",
|
|
1778
|
-
style: { aspectRatio:
|
|
1778
|
+
style: { aspectRatio: Et, perspective: "1500px" },
|
|
1779
1779
|
children: [
|
|
1780
1780
|
Ie && /* @__PURE__ */ d("div", { className: "absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10", children: /* @__PURE__ */ d("span", { className: "loading loading-spinner loading-lg text-primary" }) }),
|
|
1781
1781
|
/* @__PURE__ */ y(
|
|
1782
1782
|
"div",
|
|
1783
1783
|
{
|
|
1784
1784
|
ref: u,
|
|
1785
|
-
className: `relative w-full h-full shadow-lg ${S &&
|
|
1785
|
+
className: `relative w-full h-full shadow-lg ${S && Lt ? P ? "cursor-grabbing" : "cursor-grab" : ""} ${Ie ? "opacity-0" : "opacity-100"} transition-opacity duration-300`,
|
|
1786
1786
|
style: {
|
|
1787
1787
|
transformStyle: "preserve-3d",
|
|
1788
1788
|
transition: "transform 0.6s ease-in-out, opacity 0.3s ease-in-out",
|
|
@@ -1850,7 +1850,7 @@ function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
|
1850
1850
|
children: /* @__PURE__ */ y(
|
|
1851
1851
|
"button",
|
|
1852
1852
|
{
|
|
1853
|
-
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",
|
|
1853
|
+
className: "btn btn-dash hover:btn-dash hover:border-base-content/60 relative 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",
|
|
1854
1854
|
onClick: (g) => {
|
|
1855
1855
|
g.stopPropagation(), e == null || e();
|
|
1856
1856
|
},
|
|
@@ -1859,22 +1859,39 @@ function _n({ onPortraitClick: e, onFileDrop: t } = {}) {
|
|
|
1859
1859
|
"svg",
|
|
1860
1860
|
{
|
|
1861
1861
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1862
|
-
className: "w-
|
|
1862
|
+
className: "absolute top-1 right-1 sm:top-1.5 sm:right-1.5 w-3 h-3 sm:w-4 sm:h-4 text-base-content/60",
|
|
1863
1863
|
fill: "none",
|
|
1864
|
-
viewBox: "0 0
|
|
1864
|
+
viewBox: "0 0 24 24",
|
|
1865
|
+
stroke: "currentColor",
|
|
1866
|
+
strokeWidth: 2.5,
|
|
1867
|
+
strokeLinecap: "round",
|
|
1868
|
+
strokeLinejoin: "round",
|
|
1869
|
+
children: [
|
|
1870
|
+
/* @__PURE__ */ d("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
|
|
1871
|
+
/* @__PURE__ */ d("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
1872
|
+
]
|
|
1873
|
+
}
|
|
1874
|
+
),
|
|
1875
|
+
/* @__PURE__ */ y(
|
|
1876
|
+
"svg",
|
|
1877
|
+
{
|
|
1878
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1879
|
+
className: "w-7 h-6 sm:w-10 sm:h-9 text-base-content/50",
|
|
1880
|
+
fill: "none",
|
|
1881
|
+
viewBox: "0 0 24 24",
|
|
1865
1882
|
stroke: "currentColor",
|
|
1866
1883
|
strokeWidth: 1.5,
|
|
1867
1884
|
strokeLinecap: "round",
|
|
1868
1885
|
strokeLinejoin: "round",
|
|
1869
1886
|
children: [
|
|
1870
|
-
/* @__PURE__ */ d("circle", { cx: "
|
|
1871
|
-
/* @__PURE__ */ d("path", { d: "
|
|
1872
|
-
/* @__PURE__ */ d("line", { x1: "22", y1: "4", x2: "22", y2: "10", strokeWidth: 2 }),
|
|
1873
|
-
/* @__PURE__ */ d("line", { x1: "19", y1: "7", x2: "25", y2: "7", strokeWidth: 2 })
|
|
1887
|
+
/* @__PURE__ */ d("circle", { cx: "12", cy: "8", r: "4" }),
|
|
1888
|
+
/* @__PURE__ */ d("path", { d: "M4 21c0-4 4-6 8-6s8 2 8 6" })
|
|
1874
1889
|
]
|
|
1875
1890
|
}
|
|
1876
1891
|
),
|
|
1877
|
-
/* @__PURE__ */ d("span", { className: "text-[10px] sm:text-xs", children: n === "de" ?
|
|
1892
|
+
/* @__PURE__ */ d("span", { className: "text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line", children: n === "de" ? `Foto
|
|
1893
|
+
hochladen` : `Upload
|
|
1894
|
+
photo` })
|
|
1878
1895
|
]
|
|
1879
1896
|
}
|
|
1880
1897
|
)
|
|
@@ -2309,16 +2326,16 @@ async function vn(e) {
|
|
|
2309
2326
|
Oe(n)
|
|
2310
2327
|
]);
|
|
2311
2328
|
let k = null;
|
|
2312
|
-
return s && (k = await Oe(s)), new Promise((P,
|
|
2329
|
+
return s && (k = await Oe(s)), new Promise((P, L) => {
|
|
2313
2330
|
const S = yn(), B = (D) => {
|
|
2314
2331
|
if (S.removeEventListener("message", B), S.removeEventListener("error", H), URL.revokeObjectURL(u), URL.revokeObjectURL(I), k && URL.revokeObjectURL(k), D.data.type === "success")
|
|
2315
2332
|
try {
|
|
2316
|
-
const { frontImageData:
|
|
2317
|
-
if (!
|
|
2318
|
-
|
|
2333
|
+
const { frontImageData: E, backImageData: N, width: Y, height: J } = D.data;
|
|
2334
|
+
if (!E || !N || !Y || !J) {
|
|
2335
|
+
L(new Error("Invalid response from worker"));
|
|
2319
2336
|
return;
|
|
2320
2337
|
}
|
|
2321
|
-
const ne = it(
|
|
2338
|
+
const ne = it(E, "image/jpeg"), ee = it(N, "image/jpeg"), X = Y / 96 * 25.4, _ = J / 96 * 25.4, q = new Dt({
|
|
2322
2339
|
orientation: X > _ ? "landscape" : "portrait",
|
|
2323
2340
|
unit: "mm",
|
|
2324
2341
|
format: [X, _]
|
|
@@ -2326,13 +2343,13 @@ async function vn(e) {
|
|
|
2326
2343
|
q.addImage(ne, "JPEG", 0, 0, X, _), q.addPage([X, _]), q.addImage(ee, "JPEG", 0, 0, X, _);
|
|
2327
2344
|
const ae = q.output("blob");
|
|
2328
2345
|
P(ae);
|
|
2329
|
-
} catch (
|
|
2330
|
-
E
|
|
2346
|
+
} catch (E) {
|
|
2347
|
+
L(E);
|
|
2331
2348
|
}
|
|
2332
2349
|
else
|
|
2333
|
-
|
|
2350
|
+
L(new Error(D.data.error));
|
|
2334
2351
|
}, H = (D) => {
|
|
2335
|
-
S.removeEventListener("message", B), S.removeEventListener("error", H), URL.revokeObjectURL(u), URL.revokeObjectURL(I), k && URL.revokeObjectURL(k),
|
|
2352
|
+
S.removeEventListener("message", B), S.removeEventListener("error", H), URL.revokeObjectURL(u), URL.revokeObjectURL(I), k && URL.revokeObjectURL(k), L(new Error(D.message));
|
|
2336
2353
|
};
|
|
2337
2354
|
S.addEventListener("message", B), S.addEventListener("error", H), S.postMessage({
|
|
2338
2355
|
type: "generate",
|
|
@@ -2601,7 +2618,7 @@ const Be = "/", Pn = {
|
|
|
2601
2618
|
}, st = [
|
|
2602
2619
|
Pn,
|
|
2603
2620
|
Tn
|
|
2604
|
-
],
|
|
2621
|
+
], Ln = {
|
|
2605
2622
|
async listTemplates(e) {
|
|
2606
2623
|
let t = [...st];
|
|
2607
2624
|
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;
|
|
@@ -2616,7 +2633,7 @@ const Be = "/", Pn = {
|
|
|
2616
2633
|
function qn(e) {
|
|
2617
2634
|
return e === "de" ? "time-voucher-classic-de" : "time-voucher-classic-en";
|
|
2618
2635
|
}
|
|
2619
|
-
let Re =
|
|
2636
|
+
let Re = Ln;
|
|
2620
2637
|
function Gn(e) {
|
|
2621
2638
|
Re = e;
|
|
2622
2639
|
}
|
|
@@ -2644,7 +2661,7 @@ export {
|
|
|
2644
2661
|
ce as TEMPLATE_HEIGHT,
|
|
2645
2662
|
Ge as TEMPLATE_LAYOUT,
|
|
2646
2663
|
le as TEMPLATE_WIDTH,
|
|
2647
|
-
|
|
2664
|
+
Ee as TouchSlider,
|
|
2648
2665
|
Yn as VoucherConfig,
|
|
2649
2666
|
Xt as applyEngravingEffect,
|
|
2650
2667
|
Kt as applyHueShift,
|
|
@@ -2683,7 +2700,7 @@ export {
|
|
|
2683
2700
|
en as setApiKey,
|
|
2684
2701
|
Hn as setRemoveBackgroundEndpoint,
|
|
2685
2702
|
Gn as setTemplateProvider,
|
|
2686
|
-
|
|
2703
|
+
Ln as staticTemplateProvider,
|
|
2687
2704
|
se as t,
|
|
2688
2705
|
jn as useBillCanvasRefs,
|
|
2689
2706
|
x as useBillStore
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antontranelis/money-printer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.51",
|
|
4
4
|
"description": "Create personalized time vouchers that look like real currency. React components for voucher generation with PDF export.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|