@antontranelis/money-printer 1.0.39 → 1.0.41
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 +2 -2
- package/dist/index.d.ts +6 -1
- package/dist/index.js +999 -965
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),Yt=require("zustand"),zt=require("zustand/middleware"),b=require("react"),Wt=require("jspdf");var he=typeof document<"u"?document.currentScript:null;function _t(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const me=_t(),it={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:me,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:me},x=Yt.create()(zt.persist(e=>({...it,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(it)}),{name:"money-generator-storage",migrate:e=>{const t=e;return t!=null&&t.voucherConfig&&(t.voucherConfig.templateHue=29,t.voucherConfig.hours=1,t.voucherConfig.language=me),t&&(t.appLanguage=me),t},version:1,partialize:e=>({personalInfo:e.personalInfo,voucherConfig:{...e.voucherConfig,hours:1,language:me,templateHue:29},appLanguage:me,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})})),Ot={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?",billLanguage:"Schein-Sprache",billLanguageGerman:"Deutsch",billLanguageEnglish:"Englisch"},billColor:{title:"Scheinfarbe",label:"Farbton"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},$t={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},Xt={de:Ot,en:$t};function Q(e){return Xt[e]}function tt(e,t,n){if(n&&n.trim())return n;const a=Q(e),r=t===1?a.form.voucher.hourLabel:a.form.voucher.hoursLabel;return a.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",r)}function Kt(){const e=x(r=>r.appLanguage),t=x(r=>r.personalInfo),n=x(r=>r.setPersonalInfo),a=Q(e);return s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{className:"form-control",children:[s.jsx("label",{className:"label",children:s.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.name})}),s.jsx("input",{type:"text",placeholder:a.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:r=>n({name:r.target.value})})]}),s.jsxs("div",{className:"form-control",children:[s.jsx("label",{className:"label",children:s.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.email})}),s.jsx("input",{type:"email",placeholder:a.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:r=>n({email:r.target.value})})]}),s.jsxs("div",{className:"form-control",children:[s.jsx("label",{className:"label",children:s.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.phone})}),s.jsx("input",{type:"tel",placeholder:a.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:r=>n({phone:r.target.value})})]})]})}const qt=1024,ue=new Map;let G=null,st=null;function nt(e,t){return G||(G=document.createElement("canvas"),st=G.getContext("2d",{willReadFrequently:!0})),(G.width!==e||G.height!==t)&&(G.width=e,G.height=t),st}function Te(e){const t=ue.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(ue.size>10){const l=ue.keys().next().value;l&&ue.delete(l)}ue.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function Gt(){ue.clear()}async function Vt(e,t=qt){const n=await Te(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,l=Math.round(n.width*r),o=Math.round(n.height*r),i=document.createElement("canvas"),c=i.getContext("2d");if(!c)throw new Error("Failed to get canvas context");return i.width=l,i.height=o,c.drawImage(n,0,0,l,o),i.toDataURL("image/jpeg",.9)}async function Oe(e,t,n,a=0){const[r,l]=await Promise.all([Te(e),Te(t)]),o=nt(r.width,r.height);if(o.clearRect(0,0,r.width,r.height),n>0){const i=a*20;o.save(),o.globalAlpha=n,i>0&&(o.filter=`blur(${i}px)`),o.drawImage(l,0,0,r.width,r.height),o.restore()}return o.drawImage(r,0,0),G.toDataURL("image/png")}async function gt(e,t=.5,n=40){const a=await Te(e),r=nt(a.width,a.height);r.clearRect(0,0,a.width,a.height),r.drawImage(a,0,0);const l=r.getImageData(0,0,a.width,a.height),o=l.data,i=new Uint32Array(o.buffer),c=1+t*.8,d=1-t,g=n%360/360;for(let f=0;f<i.length;f++){const h=i[f],p=h&255,y=h>>8&255,k=h>>16&255,m=h>>24&255;if(m===0)continue;let P=(((77*p+150*y+29*k>>8)/255-.5)*c+.5)*255;P<0?P=0:P>255&&(P=255);const S=P/255,T=.12,[E,j,U]=mt(g,T,S),N=p*d+E*t|0,X=y*d+j*t|0,H=k*d+U*t|0;i[f]=m<<24|H<<16|X<<8|N}return r.putImageData(l,0,0),G.toDataURL("image/png")}function Zt(e,t,n){e/=255,t/=255,n/=255;const a=Math.max(e,t,n),r=Math.min(e,t,n),l=(a+r)/2;let o=0,i=0;if(a!==r){const c=a-r;switch(i=l>.5?c/(2-a-r):c/(a+r),a){case e:o=((t-n)/c+(t<n?6:0))/6;break;case t:o=((n-e)/c+2)/6;break;case n:o=((e-t)/c+4)/6;break}}return[o,i,l]}function mt(e,t,n){if(t===0){const o=Math.round(n*255);return[o,o,o]}const a=(o,i,c)=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?o+(i-o)*6*c:c<1/2?i:c<2/3?o+(i-o)*(2/3-c)*6:o),r=n<.5?n*(1+t):n+t-n*t,l=2*n-r;return[Math.round(a(l,r,e+1/3)*255),Math.round(a(l,r,e)*255),Math.round(a(l,r,e-1/3)*255)]}const Jt=29,Qt=5;async function ht(e,t){if(Math.abs(t-Jt)<=Qt)return e;const n=await Te(e),a=nt(n.width,n.height);a.clearRect(0,0,n.width,n.height),a.drawImage(n,0,0);const r=a.getImageData(0,0,n.width,n.height),l=r.data,o=new Uint32Array(l.buffer),i=t%360/360,c=20/360,d=45/360,g=o.length;for(let f=0;f<g;f++){const h=o[f],p=h&255,y=h>>8&255,k=h>>16&255,m=h>>24&255;if(m===0)continue;const[I,P,S]=Zt(p,y,k);if(P<.08||I<c||I>d)continue;const T=i,E=Math.min(P,.05),[j,U,N]=mt(T,E,S);o[f]=m<<24|N<<16|U<<8|j}return a.putImageData(r,0,0),G.toDataURL("image/png")}const $e={},en="https://api.stability.ai/v1/generation",tn="https://api.stability.ai/v2beta/stable-image/edit/remove-background",pt="stability_api_key";let be=null;function nn(e){be=e}function an(){return be}function rn(){return be!==null}const on={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"},lt=[{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 sn(e,t){const n=e/t;let a=lt[0],r=1/0;for(const l of lt){const o=l.width/l.height,i=Math.abs(n-o);i<r&&(r=i,a=l)}return a}function ln(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=sn(a.width,a.height),l=document.createElement("canvas");l.width=r.width,l.height=r.height;const o=l.getContext("2d");if(!o){n(new Error("Failed to get canvas context"));return}const i=a.width/a.height,c=r.width/r.height;let d=0,g=0,f=a.width,h=a.height;i>c?(f=a.height*c,d=(a.width-f)/2):(h=a.width/c,g=(a.height-h)/2),o.drawImage(a,d,g,f,h,0,0,r.width,r.height),t(l.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function ft(e){var o;const t=e.split(","),n=((o=t[0].match(/:(.*?);/))==null?void 0:o[1])||"image/png",a=atob(t[1]),r=a.length,l=new Uint8Array(r);for(let i=0;i<r;i++)l[i]=a.charCodeAt(i);return new Blob([l],{type:n})}function je(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:he&&he.tagName.toUpperCase()==="SCRIPT"&&he.src||new URL("index.cjs",document.baseURI).href}<"u"&&($e==null?void 0:$e.VITE_STABILITY_API_KEY)||typeof process<"u"&&((t=process.env)==null?void 0:t.NEXT_PUBLIC_STABILITY_API_KEY);return e&&e!=="your-api-key-here"?e:typeof localStorage<"u"?localStorage.getItem(pt):null}function bt(e){localStorage.setItem(pt,e)}function Se(){return be?!0:je()!==null}async function cn(e){const t=je();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,l=await ln(n),o=ft(l),i=new FormData;i.append("init_image",o,"portrait.png"),i.append("init_image_mode","IMAGE_STRENGTH"),i.append("image_strength",String(1-r)),i.append("text_prompts[0][text]",on[a]),i.append("text_prompts[0][weight]","1"),i.append("cfg_scale","7"),i.append("samples","1"),i.append("steps","30");const d=await fetch(`${en}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:i});if(!d.ok){const f=await d.text();throw console.error("Stability AI error:",f),d.status===401?new Error("Invalid API key"):d.status===402?new Error("Insufficient credits"):d.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${d.status}`)}const g=await d.json();if(!g.artifacts||g.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${g.artifacts[0].base64}`}async function xt(e){if(be){const o=await fetch(be,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!o.ok){const c=await o.json().catch(()=>({}));throw new Error(c.error||`API error: ${o.status}`)}return(await o.json()).imageDataUrl}const t=je();if(!t)throw new Error("No Stability AI API key configured");const n=ft(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(tn,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const o=await r.text();throw console.error("Stability AI remove background error:",o),r.status===401?new Error("Invalid API key"):r.status===402?new Error("Insufficient credits"):r.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${r.status}`)}const l=await r.blob();return new Promise((o,i)=>{const c=new FileReader;c.onload=()=>o(c.result),c.onerror=()=>i(new Error("Failed to read result")),c.readAsDataURL(l)})}function un(){const[e,t]=b.useState(!1),[n,a]=b.useState(!1),[r,l]=b.useState(null),[o,i]=b.useState(()=>Se());b.useEffect(()=>{i(Se());const h=setTimeout(()=>{i(Se())},150);return()=>clearTimeout(h)},[]);const c=b.useCallback(()=>l(null),[]),d=b.useCallback(h=>{bt(h),i(!0),l(null)},[]),g=b.useCallback(async(h,p=.5,y=40)=>{t(!0),l(null);try{return await gt(h,p,y)}catch(k){const m=k instanceof Error?k.message:"Enhancement failed";throw l(m),k}finally{t(!1)}},[]),f=b.useCallback(async h=>{a(!0),l(null);try{return await xt(h)}catch(p){const y=p instanceof Error?p.message:"Background removal failed";throw l(y),p}finally{a(!1)}},[]);return{enhance:g,removeBg:f,isEnhancing:e,isRemovingBg:n,error:r,hasKey:o,setApiKey:d,clearError:c}}function wt({isOpen:e,onClose:t,onSubmit:n}){const a=x(d=>d.appLanguage),[r,l]=b.useState("");if(!e)return null;const o=d=>{d.preventDefault(),r.trim()&&(n(r.trim()),l(""),t())},c={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[a];return s.jsxs("dialog",{className:"modal modal-open",children:[s.jsxs("div",{className:"modal-box",children:[s.jsx("h3",{className:"font-bold text-lg",children:c.title}),s.jsx("p",{className:"py-4 text-sm opacity-80",children:c.description}),s.jsxs("form",{onSubmit:o,children:[s.jsxs("div",{className:"form-control",children:[s.jsx("input",{type:"password",placeholder:c.placeholder,className:"input input-bordered w-full",value:r,onChange:d=>l(d.target.value),autoFocus:!0}),s.jsx("label",{className:"label",children:s.jsx("span",{className:"label-text-alt",children:c.hint})})]}),s.jsxs("div",{className:"modal-action",children:[s.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:c.cancel}),s.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:c.submit})]})]})]}),s.jsx("form",{method:"dialog",className:"modal-backdrop",children:s.jsx("button",{onClick:t,children:"close"})})]})}function dn(){const e=x(u=>u.appLanguage),t=x(u=>u.portrait),n=x(u=>u.setPortrait),a=x(u=>u.setPortraitZoom),r=x(u=>u.setPortraitPan),l=x(u=>u.setPortraitRawImage),o=x(u=>u.setPortraitBgRemoved),i=x(u=>u.setPortraitBgOpacity),c=x(u=>u.setPortraitBgBlur),d=x(u=>u.setPortraitEngravingIntensity),{enhance:g,removeBg:f,isEnhancing:h,isRemovingBg:p,error:y,hasKey:k,setApiKey:m}=un(),I=Q(e),P=b.useRef(null),S=b.useRef(null),[T,E]=b.useState(!1),[j,U]=b.useState(!1),[N,X]=b.useState(!1),H=b.useRef(null),F=b.useRef(null),D=b.useRef(null),B=t.rawImage,Z=t.bgRemovedImage,z=t.bgRemoved,W=t.bgOpacity,V=t.bgBlur,J=t.engravingIntensity;b.useEffect(()=>{t.original&&!t.rawImage&&l(t.original)},[t.original,t.rawImage,l]),b.useEffect(()=>()=>{F.current&&clearTimeout(F.current),D.current&&clearTimeout(D.current)},[]);const ie=x(u=>u.voucherConfig.templateHue),xe=b.useRef(ie),se=b.useCallback(async u=>{if(!u.type.startsWith("image/"))return;const v=new FileReader;v.onload=async R=>{var _;const L=(_=R.target)==null?void 0:_.result,q=await Vt(L);l(q),n(q),o(!1,null),d(0)},v.readAsDataURL(u)},[n,l,o,d]),we=b.useCallback(u=>{u.preventDefault(),E(!1);const v=u.dataTransfer.files[0];v&&se(v)},[se]),le=b.useCallback(u=>{u.preventDefault(),E(!0)},[]),Ce=b.useCallback(u=>{u.preventDefault(),E(!1)},[]),Ee=()=>{var u;(u=P.current)==null||u.click()},ye=u=>{var R;const v=(R=u.target.files)==null?void 0:R[0];v&&se(v)},ne=b.useCallback(async(u,v,R)=>{try{return await g(u,v,R)}catch(L){return console.error("Enhancement failed:",L),u}},[g]),Le=b.useCallback(async u=>{try{const v=await f(u);return o(!0,v),v}catch(v){return console.error("Background removal failed:",v),u}},[f,o]),ae=b.useCallback(async()=>{const u=x.getState(),v=u.portrait,R=u.voucherConfig.templateHue;if(!v.rawImage)return;let L;v.bgRemoved&&v.bgRemovedImage?L=await Oe(v.bgRemovedImage,v.rawImage,v.bgOpacity,v.bgBlur):L=v.rawImage,v.engravingIntensity>0&&(L=await ne(L,v.engravingIntensity,R)),n(L)},[ne,n]);b.useEffect(()=>{if(xe.current===ie)return;xe.current=ie;const u=x.getState().portrait;u.engravingIntensity>0&&u.rawImage&&(F.current&&clearTimeout(F.current),F.current=setTimeout(ae,150))},[ie,ae]);const De=async()=>{if(!B)return;if(!z&&!k){U(!0);return}if(!z){const v=await Le(B),R=x.getState(),L=R.portrait,q=R.voucherConfig.templateHue;let _=await Oe(v,B,L.bgOpacity,L.bgBlur);L.engravingIntensity>0&&(_=await ne(_,L.engravingIntensity,q)),n(_)}else{o(!1,null);const v=x.getState(),R=v.portrait.engravingIntensity,L=v.voucherConfig.templateHue;if(R>0){const q=await ne(B,R,L);n(q)}else n(B)}},Ae=u=>{d(u),F.current&&clearTimeout(F.current),B&&(F.current=setTimeout(ae,150))},Ue=async u=>{if(m(u),!B)return;const v=await Le(B),R=x.getState(),L=R.portrait,q=R.voucherConfig.templateHue;let _=await Oe(v,B,L.bgOpacity,L.bgBlur);L.engravingIntensity>0&&(_=await ne(_,L.engravingIntensity,q)),n(_)},Fe=u=>{i(u),D.current&&clearTimeout(D.current),!(!B||!Z)&&(D.current=setTimeout(ae,150))},Ye=u=>{c(u),D.current&&clearTimeout(D.current),!(!B||!Z)&&(D.current=setTimeout(ae,150))},ze=()=>{n(null),l(null),o(!1,null),i(0),c(0),d(0),Gt()},w=(u,v)=>{t.zoom<=1||(X(!0),H.current={x:u,y:v,panX:t.panX,panY:t.panY})},M=(u,v)=>{if(!N||!H.current||!S.current)return;const R=S.current.getBoundingClientRect(),L=2/Math.max(R.width,R.height),q=(u-H.current.x)*L,_=(v-H.current.y)*L,Ut=Math.max(-1,Math.min(1,H.current.panX+q)),Ft=Math.max(-1,Math.min(1,H.current.panY+_));r(Ut,Ft)},A=()=>{X(!1),H.current=null},K=u=>{u.preventDefault(),w(u.clientX,u.clientY)},ve=u=>{M(u.clientX,u.clientY)},ke=()=>{A()},Ie=()=>{A()},Pe=u=>{u.touches.length===1&&w(u.touches[0].clientX,u.touches[0].clientY)},We=u=>{u.touches.length===1&&M(u.touches[0].clientX,u.touches[0].clientY)},_e=()=>{A()};return s.jsxs("div",{className:"space-y-4",children:[t.original?s.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[s.jsxs("div",{className:"relative",children:[s.jsx("div",{ref:S,className:`w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg ${t.zoom>1?"cursor-grab":""} ${N?"cursor-grabbing":""}`,onMouseDown:K,onMouseMove:ve,onMouseUp:ke,onMouseLeave:Ie,onTouchStart:Pe,onTouchMove:We,onTouchEnd:_e,children:s.jsx("img",{src:t.original||"",alt:"Portrait",className:"w-full h-full object-cover pointer-events-none select-none",style:{transform:`scale(${t.zoom}) translate(${t.panX*50*(t.zoom-1)}%, ${t.panY*50*(t.zoom-1)}%)`},draggable:!1})}),s.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:ze,children:s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),s.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[s.jsxs("div",{className:"form-control w-full",children:[s.jsxs("label",{className:"label",children:[s.jsx("span",{className:"label-text",children:I.form.portrait.zoom}),s.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),s.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:u=>{const v=parseFloat(u.target.value);a(v),v<=1&&(t.panX!==0||t.panY!==0)&&r(0,0)},className:"range range-primary range-sm"})]}),s.jsxs("div",{className:"form-control w-full",children:[s.jsxs("label",{className:"label",children:[s.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",h&&s.jsx("span",{className:"loading loading-spinner loading-xs"})]}),s.jsxs("span",{className:"label-text-alt",children:[Math.round(J*100),"%"]})]}),s.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:J,onChange:u=>Ae(parseFloat(u.target.value)),className:"range range-secondary range-sm",disabled:h||!B})]})]}),z?s.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[s.jsxs("div",{className:"form-control w-full",children:[s.jsxs("label",{className:"label",children:[s.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),s.jsxs("span",{className:"label-text-alt",children:[Math.round(W*100),"%"]})]}),s.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:W,onChange:u=>Fe(parseFloat(u.target.value)),className:"range range-primary range-sm"})]}),s.jsxs("div",{className:"form-control w-full",children:[s.jsxs("label",{className:"label",children:[s.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),s.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),s.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:V,onChange:u=>Ye(parseFloat(u.target.value)),className:"range range-primary range-sm"})]})]}):s.jsx("div",{className:"form-control",children:s.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[s.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${p?"opacity-50":""}`,checked:z,onChange:De,disabled:p||!B}),s.jsxs("span",{className:"label-text flex items-center gap-2",children:[p?s.jsxs(s.Fragment,{children:[s.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!k&&s.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),y&&s.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[s.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:s.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"})}),s.jsx("span",{children:y})]})]}):s.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${p?"border-primary bg-primary/10 pointer-events-none":T?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:we,onDragOver:le,onDragLeave:Ce,onClick:Ee,children:[s.jsx("input",{ref:P,type:"file",accept:"image/*",className:"hidden",onChange:ye}),p?s.jsxs("div",{className:"flex flex-col items-center gap-2",children:[s.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),s.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):s.jsxs("div",{className:"flex flex-col items-center gap-2",children:[s.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:s.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"})}),s.jsx("p",{className:"font-medium",children:I.form.portrait.upload}),s.jsx("p",{className:"text-sm text-base-content/60",children:I.form.portrait.dragDrop})]})]}),s.jsx(wt,{isOpen:j,onClose:()=>U(!1),onSubmit:Ue})]})}function gn(){const e=x(i=>i.appLanguage),t=x(i=>i.voucherConfig.language),n=x(i=>i.voucherConfig.hours);x(i=>i.voucherConfig.templateHue);const a=x(i=>i.setBillLanguage),r=x(i=>i.setHours);x(i=>i.setTemplateHue);const l=Q(e),o=[1,5,10];return s.jsxs("div",{className:"space-y-4",children:[s.jsx("div",{className:"form-control",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("span",{className:"label-text font-medium",children:l.form.voucher.billLanguage}),s.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[s.jsx("button",{className:`join-item btn btn-sm ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:l.form.voucher.billLanguageGerman}),s.jsx("button",{className:`join-item btn btn-sm ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:l.form.voucher.billLanguageEnglish})]})]})}),s.jsx("div",{className:"form-control",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("span",{className:"label-text font-medium",children:l.form.voucher.hours}),s.jsx("div",{className:"join border border-base-300 rounded-lg",children:o.map(i=>s.jsxs("button",{className:`join-item btn btn-sm ${n===i?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(i),children:[i," ",i===1?l.form.voucher.hourLabel:l.form.voucher.hoursLabel]},i))})]})}),!1]})}const Xe=new Map,ce=new Map;async function C(e){return Xe.has(e)?Xe.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{Xe.set(e,a),t(a)},a.onerror=n,a.src=e})}function oe(e,t,n,a){e.drawImage(t,0,0,n,a)}async function yt(e,t,n,a){if(t>=155&&t<=165)return C(e);const r=`${e}:${t}:${n}x${a}`;if(ce.has(r))return C(ce.get(r));const l=await C(e),o=document.createElement("canvas");o.width=n,o.height=a;const i=o.getContext("2d");if(!i)throw new Error("Failed to get canvas context");i.drawImage(l,0,0,n,a);const c=o.toDataURL("image/png"),d=await ht(c,t);if(ce.size>20){const g=ce.keys().next().value;g&&ce.delete(g)}return ce.set(r,d),C(d)}function vt(e,t,n,a,r,l,o=1,i=0,c=0){e.save(),e.beginPath(),e.ellipse(n,a,r,l,0,0,Math.PI*2),e.closePath(),e.clip();const d=t.width/t.height,g=r/l,f=r*2,h=l*2;let p,y;d>g?(y=h,p=h*d):(p=f,y=f/d),p*=o,y*=o;const k=Math.max(0,(p-f)/2),m=Math.max(0,(y-h)/2),I=n-p/2+i*k,P=a-y/2+c*m;e.drawImage(t,I,P,p,y),e.restore()}function at(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=a,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function kt(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=a;const r=n.maxWidth||400,l=n.lineHeight||n.fontSize*1.4,o=t.split(" "),i=[];let c="";for(const f of o){const h=c?`${c} ${f}`:f;e.measureText(h).width>r&&c?(i.push(c),c=f):c=h}c&&i.push(c);const d=i.length*l;let g=n.y-d/2;for(const f of i)e.fillText(f,n.x,g),g+=l;e.restore()}function It(e,t,n,a,r,l="#2a3a2a"){e.save(),e.font=`${r.fontSize}px "Times New Roman", serif`,e.textAlign=r.align||"center",e.textBaseline="middle",e.fillStyle=l;const o=r.lineHeight||r.fontSize*1.8,i=[t,n,a].filter(Boolean),c=(i.length-1)*o;let d=r.y-c/2;for(const g of i)g&&(e.fillText(g,r.x,d),d+=o);e.restore()}function mn(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 Pt(e,t,n,a,r,l,o,i,c,d=1,g=0,f=0,h=0,p=1,y="de"){const k=e.getContext("2d");if(!k)return;const m=document.createElement("canvas");m.width=i,m.height=c;const I=m.getContext("2d");if(!I)return;I.clearRect(0,0,i,c);const P=await yt(t,h,i,c);oe(I,P,i,c);const S=await C(n);if(oe(I,S,i,c),r)try{const j=await C(r);vt(I,j,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,d,g,f)}catch(j){console.error("Failed to load portrait:",j)}const T=await C(a);oe(I,T,i,c);const E=i/3633;Rt(I,p,y,E),l&&at(I,l,o.namePlate),e.width=i,e.height=c,k.drawImage(m,0,0)}async function Tt(e,t,n,a,r,l,o,i,c,d,g,f=0,h=1,p="de"){const y=e.getContext("2d");if(!y)return;const k=document.createElement("canvas");k.width=d,k.height=g;const m=k.getContext("2d");if(!m)return;m.clearRect(0,0,d,g);const I=await yt(t,f,d,g);oe(m,I,d,g);const P=await C(n);oe(m,P,d,g);const S=await C(a);oe(m,S,d,g);const T=d/3633;if(Rt(m,h,p,T),c.contactInfo&&(r||l||o)&&It(m,r,l,o,c.contactInfo),c.description&&i&&kt(m,i,c.description),r&&at(m,r,c.namePlate),c.signature){const E=p==="de"?"Unterschrift":"Signature";mn(m,c.signature,E)}e.width=d,e.height=g,y.drawImage(k,0,0)}const pe=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:he&&he.tagName.toUpperCase()==="SCRIPT"&&he.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",$={background:`${pe}templates/background.webp`,frontFrame:`${pe}templates/front_frame.webp`,backFrame:`${pe}templates/back_frame.webp`},fe={1:`${pe}templates/1.png`,5:`${pe}templates/5.png`,10:`${pe}templates/10.png`},Ct={de:{banner:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"}},en:{banner:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}}},ee=3633,te=1920,Ne=.5,hn=Math.round(ee*Ne),pn=Math.round(te*Ne),Et=320,Lt=335,O={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"}},Re=new Map,re=new Map,Ge=new Map,Ve=new Map,Ze=new Map;function St(e,t,n,a,r,l,o){e.save(),e.font=`900 ${l}px "Times New Roman", Georgia, serif`,e.fillStyle=o,e.textAlign="center",e.textBaseline="middle";const c=e.measureText(t).width/r,d=-Math.PI/2-c/2,g=t.split(""),f=[];for(const p of g)f.push(e.measureText(p).width);let h=d;for(let p=0;p<g.length;p++){const y=g[p],k=f[p],m=h+k/2/r,I=n+r*Math.cos(m),P=a+r*Math.sin(m);e.save(),e.translate(I,P),e.rotate(m+Math.PI/2),e.fillText(y,0,0),e.restore(),h+=k/r}e.restore()}let Y={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function fn(){const[e,t,n,a,r,l]=await Promise.all([C($.background),C($.frontFrame),C($.backFrame),C(fe[1]),C(fe[5]),C(fe[10])]);Y={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:l}}}function bn(e,t){const n=Math.round(ee*e),a=Math.round(te*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");l.drawImage(t,0,0,n,a);const o=e<1?.8:.95;return r.toDataURL("image/jpeg",o)}function xn(e,t){const n=Math.round(ee*e),a=Math.round(te*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");const o=Et*e,i=Lt*e,c=O.badges,d=(g,f)=>{const h=f/2,p=g.x*e-h,y=g.y*e-h;l.drawImage(t,p,y,f,f)};return d(c.topLeft,o),d(c.topRight,o),d(c.bottomLeft,i),d(c.bottomRight,i),r.toDataURL("image/png")}function Rt(e,t,n,a=1){const r=Ct[n].banner[t];St(e,r,O.banner.centerX*a,O.banner.centerY*a,O.banner.radius*a,O.banner.fontSize*a,O.banner.color)}function Bt(e,t,n,a,r,l,o){const i=Math.round(ee*a),c=Math.round(te*a),d=document.createElement("canvas");d.width=i,d.height=c;const g=d.getContext("2d");if(!g)throw new Error("Failed to get canvas context");g.drawImage(r,0,0,i,c);{const h=Et*a,p=Lt*a,y=O.badges,k=(m,I)=>{const P=I/2,S=m.x*a-P,T=m.y*a-P;g.drawImage(o,S,T,I,I)};k(y.topLeft,h),k(y.topRight,h),k(y.bottomLeft,p),k(y.bottomRight,p)}if(g.drawImage(l,0,0,i,c),n==="front"){const h=Ct[t].banner[e];St(g,h,O.banner.centerX*a,O.banner.centerY*a,O.banner.radius*a,O.banner.fontSize*a,O.banner.color)}const f=a<1?.8:.95;return d.toDataURL("image/jpeg",f)}async function jt(e,t,n){const a=`${e}-${t}-${n}`;if(Re.has(a))return Re.get(a);const r=Y.background||await C($.background),l=n==="front"?Y.frontFrame||await C($.frontFrame):Y.backFrame||await C($.backFrame),o=Y.badges[e]||await C(fe[e]),i=Bt(e,t,n,Ne,r,l,o);return Re.set(a,i),i}async function Je(e,t,n){const a=`${e}-${t}-${n}`;if(re.has(a))return re.get(a);const r=Y.background||await C($.background),l=n==="front"?Y.frontFrame||await C($.frontFrame):Y.backFrame||await C($.backFrame),o=Y.badges[e]||await C(fe[e]),i=Bt(e,t,n,1,r,l,o);if(re.size>4){const c=re.keys().next().value;c&&re.delete(c)}return re.set(a,i),i}function wn(){return{width:ee,height:te}}function yn(){Re.clear(),re.clear(),Ge.clear(),Ve.clear(),Ze.clear()}async function Qe(e,t,n="front",a=Ne){const r=`bg-${a}`;let l=Ge.get(r);if(!l){const g=Y.background||await C($.background);l=bn(a,g),Ge.set(r,l)}const o=`badges-${e}-${a}`;let i=Ve.get(o);if(!i){const g=Y.badges[e]||await C(fe[e]);i=xn(a,g),Ve.set(o,i)}const c=`${n}-${a}`;let d=Ze.get(c);if(!d){const g=n==="front"?Y.frontFrame||await C($.frontFrame):Y.backFrame||await C($.backFrame),f=Math.round(ee*a),h=Math.round(te*a),p=document.createElement("canvas");p.width=f,p.height=h;const y=p.getContext("2d");if(!y)throw new Error("Failed to get canvas context");y.drawImage(g,0,0,f,h),d=p.toDataURL("image/png"),Ze.set(c,d)}return{background:l,badges:i,frame:d}}async function vn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const l of t)for(const o of n)a.push(jt(r,l,o));await Promise.all(a)}function rt(e,t){return{front:"",back:"",width:ee,height:te}}const He={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},de=He,ge=He;function ot(e){return He}const et=.75;function kn(e){const t=ot(),n=et,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 In(e,t){const n=rt();return{...n,width:Math.round(n.width*et),height:Math.round(n.height*et)}}function Pn(e,t){const[n,a]=b.useState(e);return b.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Tn(){const e=x(w=>w.appLanguage),t=x(w=>w.voucherConfig.language),n=x(w=>w.voucherConfig.hours),a=x(w=>w.voucherConfig.description),r=x(w=>w.voucherConfig.templateHue),l=x(w=>w.personalInfo),o=x(w=>w.portrait),i=x(w=>w.currentSide),c=x(w=>w.flipSide),d=x(w=>w.setPortraitPan),g=Pn(r,150),f=Q(e),h=b.useRef(null),p=b.useRef(null),y=b.useRef(null),[k,m]=b.useState(!1),[I,P]=b.useState(!1),S=b.useRef(null),T=In(),E=kn(),j=o.useEnhanced&&o.enhanced?o.enhanced:o.original,U=tt(t,n,a),[N,X]=b.useState(""),[H,F]=b.useState(""),[D,B]=b.useState(""),[Z,z]=b.useState(""),[W,V]=b.useState(""),[J,ie]=b.useState(""),[xe,se]=b.useState(!0);b.useEffect(()=>{let w=!0;se(!0);async function M(){const[A,K]=await Promise.all([Qe(n,t,"front"),Qe(n,t,"back")]);w&&(X(A.background),F(A.badges),B(A.frame),z(K.background),V(K.badges),ie(K.frame),se(!1))}return M(),()=>{w=!1}},[n,t]),b.useEffect(()=>{!h.current||!N||!H||!D||Pt(h.current,N,H,D,j,l.name,E.front,T.width,T.height,o.zoom,o.panX,o.panY,g,n,t)},[T,N,H,D,j,l.name,E,o.zoom,o.panX,o.panY,g,n,t]),b.useEffect(()=>{!p.current||!Z||!W||!J||Tt(p.current,Z,W,J,l.name,l.email,l.phone,U,E.back,T.width,T.height,g,n,t)},[T,Z,W,J,l,U,E,g,n,t]);const we=()=>{m(!k),c()},le=b.useCallback((w,M)=>{if(!y.current||i!=="front"||!o.original)return!1;const A=y.current.getBoundingClientRect(),K=A.width/T.width,ve=A.height/T.height,ke=(w-A.left)/K,Ie=(M-A.top)/ve,{x:Pe,y:We,radiusX:_e,radiusY:u}=E.front.portrait,v=(ke-Pe)/_e,R=(Ie-We)/u;return v*v+R*R<=1},[i,o.original,T.width,T.height,E.front.portrait]),Ce=b.useCallback((w,M)=>{o.zoom<=1||!le(w,M)||(P(!0),S.current={x:w,y:M,panX:o.panX,panY:o.panY})},[o.zoom,o.panX,o.panY,le]),Ee=b.useCallback((w,M)=>{if(!I||!S.current||!y.current)return;const A=y.current.getBoundingClientRect(),K=3/Math.max(A.width,A.height),ve=(w-S.current.x)*K,ke=(M-S.current.y)*K,Ie=Math.max(-1,Math.min(1,S.current.panX+ve)),Pe=Math.max(-1,Math.min(1,S.current.panY+ke));d(Ie,Pe)},[I,d]),ye=b.useCallback(()=>{P(!1),S.current=null},[]),ne=w=>{o.zoom>1&&le(w.clientX,w.clientY)&&(w.preventDefault(),Ce(w.clientX,w.clientY))},Le=w=>{Ee(w.clientX,w.clientY)},ae=()=>ye(),De=()=>ye(),Ae=w=>{if(w.touches.length===1){const M=w.touches[0];o.zoom>1&&le(M.clientX,M.clientY)&&Ce(M.clientX,M.clientY)}},Ue=w=>{w.touches.length===1&&Ee(w.touches[0].clientX,w.touches[0].clientY)},Fe=()=>ye(),Ye=i==="front"&&o.original&&o.zoom>1,ze=T.width/T.height;return s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{className:"flex justify-between items-center",children:[s.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[s.jsx("button",{className:`tab ${i==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>i!=="front"&&we(),children:f.preview.front}),s.jsx("button",{className:`tab ${i==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>i!=="back"&&we(),children:f.preview.back})]}),s.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:we,children:[s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.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"})}),f.preview.flip]})]}),s.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:ze,perspective:"1500px"},children:[xe&&s.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:s.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),s.jsxs("div",{ref:y,className:`relative w-full h-full shadow-lg ${Ye?I?"cursor-grabbing":"cursor-grab":""} ${xe?"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:k?"rotateY(180deg)":"rotateY(0deg)"},onMouseDown:ne,onMouseMove:Le,onMouseUp:ae,onMouseLeave:De,onTouchStart:Ae,onTouchMove:Ue,onTouchEnd:Fe,children:[s.jsx("canvas",{ref:h,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),s.jsx("canvas",{ref:p,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}})]})]})]})}function Cn(){const e=b.useRef(null),t=b.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const En=`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),Ot=require("zustand"),_t=require("zustand/middleware"),b=require("react"),$t=require("jspdf");var me=typeof document<"u"?document.currentScript:null;function Xt(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const ge=Xt(),at={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:ge,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:ge},w=Ot.create()(_t.persist(e=>({...at,setPersonalInfo:t=>e(a=>({personalInfo:{...a.personalInfo,...t}})),setVoucherConfig:t=>e(a=>({voucherConfig:{...a.voucherConfig,...t}})),setPortrait:(t,a=null)=>e(n=>({portrait:{...n.portrait,original:t,enhanced:a,useEnhanced:!1,zoom:n.portrait.original&&t?n.portrait.zoom:1,panX:n.portrait.original&&t?n.portrait.panX:0,panY:n.portrait.original&&t?n.portrait.panY:0}})),setEnhancedPortrait:t=>e(a=>({portrait:{...a.portrait,enhanced:t,useEnhanced:t!==null}})),toggleUseEnhanced:()=>e(t=>({portrait:{...t.portrait,useEnhanced:t.portrait.enhanced?!t.portrait.useEnhanced:!1}})),setPortraitZoom:t=>e(a=>({portrait:{...a.portrait,zoom:t}})),setPortraitPan:(t,a)=>e(n=>({portrait:{...n.portrait,panX:t,panY:a}})),setPortraitRawImage:t=>e(a=>({portrait:{...a.portrait,rawImage:t}})),setPortraitBgRemoved:(t,a)=>e(n=>({portrait:{...n.portrait,bgRemoved:t,bgRemovedImage:a!==void 0?a:n.portrait.bgRemovedImage}})),setPortraitBgOpacity:t=>e(a=>({portrait:{...a.portrait,bgOpacity:t}})),setPortraitBgBlur:t=>e(a=>({portrait:{...a.portrait,bgBlur:t}})),setPortraitEngravingIntensity:t=>e(a=>({portrait:{...a.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(a=>({voucherConfig:{...a.voucherConfig,language:t}})),setHours:t=>e(a=>({voucherConfig:{...a.voucherConfig,hours:t}})),setTemplateHue:t=>e(a=>({voucherConfig:{...a.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=ge),t&&(t.appLanguage=ge),t},version:1,partialize:e=>({personalInfo:e.personalInfo,voucherConfig:{...e.voucherConfig,hours:1,language:ge,templateHue:29},appLanguage:ge,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})})),Kt={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?",billLanguage:"Schein-Sprache",billLanguageGerman:"Deutsch",billLanguageEnglish:"Englisch"},billColor:{title:"Scheinfarbe",label:"Farbton"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},qt={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},Vt={de:Kt,en:qt};function J(e){return Vt[e]}function Ve(e,t,a){if(a&&a.trim())return a;const n=J(e),r=t===1?n.form.voucher.hourLabel:n.form.voucher.hoursLabel;return n.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",r)}function Gt(){const e=w(r=>r.appLanguage),t=w(r=>r.personalInfo),a=w(r=>r.setPersonalInfo),n=J(e);return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.name})}),i.jsx("input",{type:"text",placeholder:n.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:r=>a({name:r.target.value})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.email})}),i.jsx("input",{type:"email",placeholder:n.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:r=>a({email:r.target.value})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.phone})}),i.jsx("input",{type:"tel",placeholder:n.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:r=>a({phone:r.target.value})})]})]})}const Zt=1024,ce=new Map;let K=null,nt=null;function Ge(e,t){return K||(K=document.createElement("canvas"),nt=K.getContext("2d",{willReadFrequently:!0})),(K.width!==e||K.height!==t)&&(K.width=e,K.height=t),nt}function ye(e){const t=ce.get(e);return t?Promise.resolve(t):new Promise((a,n)=>{const r=new Image;r.onload=()=>{if(ce.size>10){const c=ce.keys().next().value;c&&ce.delete(c)}ce.set(e,r),a(r)},r.onerror=()=>n(new Error("Failed to load image")),r.src=e})}function Jt(){ce.clear()}async function Qt(e,t=Zt){const a=await ye(e),n=Math.max(a.width,a.height);if(n<=t)return e;const r=t/n,c=Math.round(a.width*r),l=Math.round(a.height*r),o=document.createElement("canvas"),s=o.getContext("2d");if(!s)throw new Error("Failed to get canvas context");return o.width=c,o.height=l,s.drawImage(a,0,0,c,l),o.toDataURL("image/jpeg",.9)}async function Ue(e,t,a,n=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),a>0){const o=n*20;l.save(),l.globalAlpha=a,o>0&&(l.filter=`blur(${o}px)`),l.drawImage(c,0,0,r.width,r.height),l.restore()}return l.drawImage(r,0,0),K.toDataURL("image/png")}async function lt(e,t=.5,a=40){const n=await ye(e),r=Ge(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const c=r.getImageData(0,0,n.width,n.height),l=c.data,o=new Uint32Array(l.buffer),s=1+t*.8,d=1-t,p=a%360/360;for(let x=0;x<o.length;x++){const h=o[x],f=h&255,y=h>>8&255,v=h>>16&255,g=h>>24&255;if(g===0)continue;let P=(((77*f+150*y+29*v>>8)/255-.5)*s+.5)*255;P<0?P=0:P>255&&(P=255);const D=P/255,j=.12,[B,M,A]=ct(p,j,D),S=f*d+B*t|0,T=y*d+M*t|0,L=v*d+A*t|0;o[x]=g<<24|L<<16|T<<8|S}return r.putImageData(c,0,0),K.toDataURL("image/png")}function ea(e,t,a){e/=255,t/=255,a/=255;const n=Math.max(e,t,a),r=Math.min(e,t,a),c=(n+r)/2;let l=0,o=0;if(n!==r){const s=n-r;switch(o=c>.5?s/(2-n-r):s/(n+r),n){case e:l=((t-a)/s+(t<a?6:0))/6;break;case t:l=((a-e)/s+2)/6;break;case a:l=((e-t)/s+4)/6;break}}return[l,o,c]}function ct(e,t,a){if(t===0){const l=Math.round(a*255);return[l,l,l]}const n=(l,o,s)=>(s<0&&(s+=1),s>1&&(s-=1),s<1/6?l+(o-l)*6*s:s<1/2?o:s<2/3?l+(o-l)*(2/3-s)*6:l),r=a<.5?a*(1+t):a+t-a*t,c=2*a-r;return[Math.round(n(c,r,e+1/3)*255),Math.round(n(c,r,e)*255),Math.round(n(c,r,e-1/3)*255)]}const ta=29,aa=5;async function dt(e,t){if(Math.abs(t-ta)<=aa)return e;const a=await ye(e),n=Ge(a.width,a.height);n.clearRect(0,0,a.width,a.height),n.drawImage(a,0,0);const r=n.getImageData(0,0,a.width,a.height),c=r.data,l=new Uint32Array(c.buffer),o=t%360/360,s=20/360,d=45/360,p=l.length;for(let x=0;x<p;x++){const h=l[x],f=h&255,y=h>>8&255,v=h>>16&255,g=h>>24&255;if(g===0)continue;const[I,P,D]=ea(f,y,v);if(P<.08||I<s||I>d)continue;const j=o,B=Math.min(P,.05),[M,A,S]=ct(j,B,D);l[x]=g<<24|S<<16|A<<8|M}return n.putImageData(r,0,0),K.toDataURL("image/png")}const Fe={},na="https://api.stability.ai/v1/generation",ra="https://api.stability.ai/v2beta/stable-image/edit/remove-background",ut="stability_api_key";let fe=null;function oa(e){fe=e}function ia(){return fe}function sa(){return fe!==null}const la={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"},rt=[{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 ca(e,t){const a=e/t;let n=rt[0],r=1/0;for(const c of rt){const l=c.width/c.height,o=Math.abs(a-l);o<r&&(r=o,n=c)}return n}function da(e){return new Promise((t,a)=>{const n=new Image;n.onload=()=>{const r=ca(n.width,n.height),c=document.createElement("canvas");c.width=r.width,c.height=r.height;const l=c.getContext("2d");if(!l){a(new Error("Failed to get canvas context"));return}const o=n.width/n.height,s=r.width/r.height;let d=0,p=0,x=n.width,h=n.height;o>s?(x=n.height*s,d=(n.width-x)/2):(h=n.width/s,p=(n.height-h)/2),l.drawImage(n,d,p,x,h,0,0,r.width,r.height),t(c.toDataURL("image/png"))},n.onerror=()=>a(new Error("Failed to load image")),n.src=e})}function gt(e){var l;const t=e.split(","),a=((l=t[0].match(/:(.*?);/))==null?void 0:l[1])||"image/png",n=atob(t[1]),r=n.length,c=new Uint8Array(r);for(let o=0;o<r;o++)c[o]=n.charCodeAt(o);return new Blob([c],{type:a})}function Ce(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:me&&me.tagName.toUpperCase()==="SCRIPT"&&me.src||new URL("index.cjs",document.baseURI).href}<"u"&&(Fe==null?void 0:Fe.VITE_STABILITY_API_KEY)||typeof process<"u"&&((t=process.env)==null?void 0:t.NEXT_PUBLIC_STABILITY_API_KEY);return e&&e!=="your-api-key-here"?e:typeof localStorage<"u"?localStorage.getItem(ut):null}function mt(e){localStorage.setItem(ut,e)}function Te(){return fe?!0:Ce()!==null}async function ua(e){const t=Ce();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:a,style:n,strength:r=.35}=e,c=await da(a),l=gt(c),o=new FormData;o.append("init_image",l,"portrait.png"),o.append("init_image_mode","IMAGE_STRENGTH"),o.append("image_strength",String(1-r)),o.append("text_prompts[0][text]",la[n]),o.append("text_prompts[0][weight]","1"),o.append("cfg_scale","7"),o.append("samples","1"),o.append("steps","30");const d=await fetch(`${na}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:o});if(!d.ok){const x=await d.text();throw console.error("Stability AI error:",x),d.status===401?new Error("Invalid API key"):d.status===402?new Error("Insufficient credits"):d.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${d.status}`)}const p=await d.json();if(!p.artifacts||p.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${p.artifacts[0].base64}`}async function pt(e){if(fe){const l=await fetch(fe,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!l.ok){const s=await l.json().catch(()=>({}));throw new Error(s.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 a=gt(e),n=new FormData;n.append("image",a,"image.png"),n.append("output_format","png");const r=await fetch(ra,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:n});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,o)=>{const s=new FileReader;s.onload=()=>l(s.result),s.onerror=()=>o(new Error("Failed to read result")),s.readAsDataURL(c)})}function ga(){const[e,t]=b.useState(!1),[a,n]=b.useState(!1),[r,c]=b.useState(null),[l,o]=b.useState(()=>Te());b.useEffect(()=>{o(Te());const h=setTimeout(()=>{o(Te())},150);return()=>clearTimeout(h)},[]);const s=b.useCallback(()=>c(null),[]),d=b.useCallback(h=>{mt(h),o(!0),c(null)},[]),p=b.useCallback(async(h,f=.5,y=40)=>{t(!0),c(null);try{return await lt(h,f,y)}catch(v){const g=v instanceof Error?v.message:"Enhancement failed";throw c(g),v}finally{t(!1)}},[]),x=b.useCallback(async h=>{n(!0),c(null);try{return await pt(h)}catch(f){const y=f instanceof Error?f.message:"Background removal failed";throw c(y),f}finally{n(!1)}},[]);return{enhance:p,removeBg:x,isEnhancing:e,isRemovingBg:a,error:r,hasKey:l,setApiKey:d,clearError:s}}function ht({isOpen:e,onClose:t,onSubmit:a}){const n=w(d=>d.appLanguage),[r,c]=b.useState("");if(!e)return null;const l=d=>{d.preventDefault(),r.trim()&&(a(r.trim()),c(""),t())},s={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."}}[n];return i.jsxs("dialog",{className:"modal modal-open",children:[i.jsxs("div",{className:"modal-box",children:[i.jsx("h3",{className:"font-bold text-lg",children:s.title}),i.jsx("p",{className:"py-4 text-sm opacity-80",children:s.description}),i.jsxs("form",{onSubmit:l,children:[i.jsxs("div",{className:"form-control",children:[i.jsx("input",{type:"password",placeholder:s.placeholder,className:"input input-bordered w-full",value:r,onChange:d=>c(d.target.value),autoFocus:!0}),i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text-alt",children:s.hint})})]}),i.jsxs("div",{className:"modal-action",children:[i.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:s.cancel}),i.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:s.submit})]})]})]}),i.jsx("form",{method:"dialog",className:"modal-backdrop",children:i.jsx("button",{onClick:t,children:"close"})})]})}function ma(){const e=w(u=>u.appLanguage),t=w(u=>u.portrait),a=w(u=>u.setPortrait),n=w(u=>u.setPortraitZoom),r=w(u=>u.setPortraitPan),c=w(u=>u.setPortraitRawImage),l=w(u=>u.setPortraitBgRemoved),o=w(u=>u.setPortraitBgOpacity),s=w(u=>u.setPortraitBgBlur),d=w(u=>u.setPortraitEngravingIntensity),{enhance:p,removeBg:x,isEnhancing:h,isRemovingBg:f,error:y,hasKey:v,setApiKey:g}=ga(),I=J(e),P=b.useRef(null),[D,j]=b.useState(!1),[B,M]=b.useState(!1),A=b.useRef(null),S=b.useRef(null),T=t.rawImage,L=t.bgRemovedImage,R=t.bgRemoved,V=t.bgOpacity,te=t.bgBlur,G=t.engravingIntensity;b.useEffect(()=>{t.original&&!t.rawImage&&c(t.original)},[t.original,t.rawImage,c]),b.useEffect(()=>()=>{A.current&&clearTimeout(A.current),S.current&&clearTimeout(S.current)},[]);const F=w(u=>u.voucherConfig.templateHue),W=b.useRef(F),$=b.useCallback(async u=>{if(!u.type.startsWith("image/"))return;const k=new FileReader;k.onload=async N=>{var Y;const C=(Y=N.target)==null?void 0:Y.result,X=await Qt(C);c(X),a(X),l(!1,null),d(0)},k.readAsDataURL(u)},[a,c,l,d]),ae=b.useCallback(u=>{u.preventDefault(),j(!1);const k=u.dataTransfer.files[0];k&&$(k)},[$]),Be=b.useCallback(u=>{u.preventDefault(),j(!0)},[]),be=b.useCallback(u=>{u.preventDefault(),j(!1)},[]),Ne=()=>{var u;(u=P.current)==null||u.click()},xe=u=>{var N;const k=(N=u.target.files)==null?void 0:N[0];k&&$(k)},ne=b.useCallback(async(u,k,N)=>{try{return await p(u,k,N)}catch(C){return console.error("Enhancement failed:",C),u}},[p]),se=b.useCallback(async u=>{try{const k=await x(u);return l(!0,k),k}catch(k){return console.error("Background removal failed:",k),u}},[x,l]),re=b.useCallback(async()=>{const u=w.getState(),k=u.portrait,N=u.voucherConfig.templateHue;if(!k.rawImage)return;let C;k.bgRemoved&&k.bgRemovedImage?C=await Ue(k.bgRemovedImage,k.rawImage,k.bgOpacity,k.bgBlur):C=k.rawImage,k.engravingIntensity>0&&(C=await ne(C,k.engravingIntensity,N)),a(C)},[ne,a]);b.useEffect(()=>{if(W.current===F)return;W.current=F;const u=w.getState().portrait;u.engravingIntensity>0&&u.rawImage&&(A.current&&clearTimeout(A.current),A.current=setTimeout(re,150))},[F,re]);const ve=async()=>{if(!T)return;if(!R&&!v){M(!0);return}if(!R){const k=await se(T),N=w.getState(),C=N.portrait,X=N.voucherConfig.templateHue;let Y=await Ue(k,T,C.bgOpacity,C.bgBlur);C.engravingIntensity>0&&(Y=await ne(Y,C.engravingIntensity,X)),a(Y)}else{l(!1,null);const k=w.getState(),N=k.portrait.engravingIntensity,C=k.voucherConfig.templateHue;if(N>0){const X=await ne(T,N,C);a(X)}else a(T)}},ke=u=>{d(u),A.current&&clearTimeout(A.current),T&&(A.current=setTimeout(re,150))},we=async u=>{if(g(u),!T)return;const k=await se(T),N=w.getState(),C=N.portrait,X=N.voucherConfig.templateHue;let Y=await Ue(k,T,C.bgOpacity,C.bgBlur);C.engravingIntensity>0&&(Y=await ne(Y,C.engravingIntensity,X)),a(Y)},q=u=>{o(u),S.current&&clearTimeout(S.current),!(!T||!L)&&(S.current=setTimeout(re,150))},Ie=u=>{s(u),S.current&&clearTimeout(S.current),!(!T||!L)&&(S.current=setTimeout(re,150))},Pe=()=>{a(null),c(null),l(!1,null),o(0),s(0),d(0),Jt()};return i.jsxs("div",{className:"space-y-4",children:[t.original?i.jsxs("div",{className:"flex flex-col space-y-4",children:[i.jsxs("div",{className:"flex justify-between items-center w-full",children:[i.jsx("span",{className:"text-sm font-medium text-base-content/70",children:e==="de"?"Portrait-Einstellungen":"Portrait settings"}),i.jsxs("button",{className:"btn btn-xs btn-ghost text-error",onClick:Pe,children:[i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"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"?"Entfernen":"Remove"]})]}),i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:I.form.portrait.zoom}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),i.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:u=>{const k=parseFloat(u.target.value);n(k),k<=1&&(t.panX!==0||t.panY!==0)&&r(0,0)},className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",h&&i.jsx("span",{className:"loading loading-spinner loading-xs"})]}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(G*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:G,onChange:u=>ke(parseFloat(u.target.value)),className:"range range-secondary range-sm",disabled:h||!T})]})]}),R?i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:V,onChange:u=>q(parseFloat(u.target.value)),className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(te*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:te,onChange:u=>Ie(parseFloat(u.target.value)),className:"range range-primary range-sm"})]})]}):i.jsx("div",{className:"form-control w-fit",children:i.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[i.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${f?"opacity-50":""}`,checked:R,onChange:ve,disabled:f||!T}),i.jsxs("span",{className:"label-text flex items-center gap-2",children:[f?i.jsxs(i.Fragment,{children:[i.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!v&&i.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),y&&i.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"stroke-current shrink-0 h-5 w-5",fill:"none",viewBox:"0 0 24 24",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),i.jsx("span",{children:y})]})]}):i.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${f?"border-primary bg-primary/10 pointer-events-none":D?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:ae,onDragOver:Be,onDragLeave:be,onClick:Ne,children:[i.jsx("input",{ref:P,type:"file",accept:"image/*",className:"hidden",onChange:xe}),f?i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),i.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),i.jsx("p",{className:"font-medium",children:I.form.portrait.upload}),i.jsx("p",{className:"text-sm text-base-content/60",children:I.form.portrait.dragDrop})]})]}),i.jsx(ht,{isOpen:B,onClose:()=>M(!1),onSubmit:we})]})}function pa(){const e=w(o=>o.appLanguage),t=w(o=>o.voucherConfig.language),a=w(o=>o.voucherConfig.hours);w(o=>o.voucherConfig.templateHue);const n=w(o=>o.setBillLanguage),r=w(o=>o.setHours);w(o=>o.setTemplateHue);const c=J(e),l=[1,5,10];return i.jsxs("div",{className:"space-y-4",children:[i.jsx("div",{className:"form-control",children:i.jsxs("div",{className:"flex items-center justify-between",children:[i.jsx("span",{className:"label-text font-medium",children:c.form.voucher.billLanguage}),i.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[i.jsx("button",{className:`join-item btn btn-sm ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:c.form.voucher.billLanguageGerman}),i.jsx("button",{className:`join-item btn btn-sm ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:c.form.voucher.billLanguageEnglish})]})]})}),i.jsx("div",{className:"form-control",children:i.jsxs("div",{className:"flex items-center justify-between",children:[i.jsx("span",{className:"label-text font-medium",children:c.form.voucher.hours}),i.jsx("div",{className:"join border border-base-300 rounded-lg",children:l.map(o=>i.jsxs("button",{className:`join-item btn btn-sm ${a===o?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(o),children:[o," ",o===1?c.form.voucher.hourLabel:c.form.voucher.hoursLabel]},o))})]})}),!1]})}const We=new Map,le=new Map;async function E(e){return We.has(e)?We.get(e):new Promise((t,a)=>{const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{We.set(e,n),t(n)},n.onerror=a,n.src=e})}function ie(e,t,a,n){e.drawImage(t,0,0,a,n)}async function ft(e,t,a,n){if(t>=155&&t<=165)return E(e);const r=`${e}:${t}:${a}x${n}`;if(le.has(r))return E(le.get(r));const c=await E(e),l=document.createElement("canvas");l.width=a,l.height=n;const o=l.getContext("2d");if(!o)throw new Error("Failed to get canvas context");o.drawImage(c,0,0,a,n);const s=l.toDataURL("image/png"),d=await dt(s,t);if(le.size>20){const p=le.keys().next().value;p&&le.delete(p)}return le.set(r,d),E(d)}function ha(e,t,a,n,r,c="de"){e.save(),e.beginPath(),e.ellipse(t,a,n,r,0,0,Math.PI*2),e.closePath(),e.setLineDash([20,10]),e.strokeStyle="rgba(100, 100, 100, 0.4)",e.lineWidth=3,e.stroke(),e.restore()}function bt(e,t,a,n,r,c,l=1,o=0,s=0){e.save(),e.beginPath(),e.ellipse(a,n,r,c,0,0,Math.PI*2),e.closePath(),e.clip();const d=t.width/t.height,p=r/c,x=r*2,h=c*2;let f,y;d>p?(y=h,f=h*d):(f=x,y=x/d),f*=l,y*=l;const v=Math.max(0,(f-x)/2),g=Math.max(0,(y-h)/2),I=a-f/2+o*v,P=n-y/2+s*g;e.drawImage(t,I,P,f,y),e.restore()}function Ze(e,t,a,n="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=n,a.maxWidth?e.fillText(t,a.x,a.y,a.maxWidth):e.fillText(t,a.x,a.y),e.restore()}function xt(e,t,a,n="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="top",e.fillStyle=n;const r=a.maxWidth||400,c=a.lineHeight||a.fontSize*1.4,l=t.split(" "),o=[];let s="";for(const x of l){const h=s?`${s} ${x}`:x;e.measureText(h).width>r&&s?(o.push(s),s=x):s=h}s&&o.push(s);const d=o.length*c;let p=a.y-d/2;for(const x of o)e.fillText(x,a.x,p),p+=c;e.restore()}function wt(e,t,a,n,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,o=[t,a,n].filter(Boolean),s=(o.length-1)*l;let d=r.y-s/2;for(const p of o)p&&(e.fillText(p,r.x,d),d+=l);e.restore()}function fa(e,t,a,n="#2a3a2a"){e.save(),e.strokeStyle=n,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=n,e.fillText(a,t.x,t.y+t.labelFontSize*.3),e.restore()}async function yt(e,t,a,n,r,c,l,o,s,d=1,p=0,x=0,h=0,f=1,y="de"){const v=e.getContext("2d");if(!v)return;const g=document.createElement("canvas");g.width=o,g.height=s;const I=g.getContext("2d");if(!I)return;I.clearRect(0,0,o,s);const P=await ft(t,h,o,s);ie(I,P,o,s);const D=await E(a);if(ie(I,D,o,s),r)try{const M=await E(r);bt(I,M,l.portrait.x,l.portrait.y,l.portrait.radiusX,l.portrait.radiusY,d,p,x)}catch(M){console.error("Failed to load portrait:",M)}else ha(I,l.portrait.x,l.portrait.y,l.portrait.radiusX,l.portrait.radiusY,y);const j=await E(n);ie(I,j,o,s);const B=o/3633;Et(I,f,y,B),c&&Ze(I,c,l.namePlate),e.width=o,e.height=s,v.drawImage(g,0,0)}async function vt(e,t,a,n,r,c,l,o,s,d,p,x=0,h=1,f="de"){const y=e.getContext("2d");if(!y)return;const v=document.createElement("canvas");v.width=d,v.height=p;const g=v.getContext("2d");if(!g)return;g.clearRect(0,0,d,p);const I=await ft(t,x,d,p);ie(g,I,d,p);const P=await E(a);ie(g,P,d,p);const D=await E(n);ie(g,D,d,p);const j=d/3633;if(Et(g,h,f,j),s.contactInfo&&(r||c||l)&&wt(g,r,c,l,s.contactInfo),s.description&&o&&xt(g,o,s.description),r&&Ze(g,r,s.namePlate),s.signature){const B=f==="de"?"Unterschrift":"Signature";fa(g,s.signature,B)}e.width=d,e.height=p,y.drawImage(v,0,0)}const pe=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:me&&me.tagName.toUpperCase()==="SCRIPT"&&me.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",O={background:`${pe}templates/background.webp`,frontFrame:`${pe}templates/front_frame.webp`,backFrame:`${pe}templates/back_frame.webp`},he={1:`${pe}templates/1.png`,5:`${pe}templates/5.png`,10:`${pe}templates/10.png`},kt={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,Se=.5,ba=Math.round(Q*Se),xa=Math.round(ee*Se),It=320,Pt=335,z={badges:{topLeft:{x:286,y:235},topRight:{x:3340,y:230},bottomLeft:{x:282,y:1665},bottomRight:{x:3345,y:1665}},banner:{centerX:1816,centerY:3820,radius:3610,fontSize:103,color:"#2a3a2a"}},Ee=new Map,oe=new Map,Oe=new Map,_e=new Map,$e=new Map;function Tt(e,t,a,n,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 s=e.measureText(t).width/r,d=-Math.PI/2-s/2,p=t.split(""),x=[];for(const f of p)x.push(e.measureText(f).width);let h=d;for(let f=0;f<p.length;f++){const y=p[f],v=x[f],g=h+v/2/r,I=a+r*Math.cos(g),P=n+r*Math.sin(g);e.save(),e.translate(I,P),e.rotate(g+Math.PI/2),e.fillText(y,0,0),e.restore(),h+=v/r}e.restore()}let U={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function wa(){const[e,t,a,n,r,c]=await Promise.all([E(O.background),E(O.frontFrame),E(O.backFrame),E(he[1]),E(he[5]),E(he[10])]);U={background:e,frontFrame:t,backFrame:a,badges:{1:n,5:r,10:c}}}function ya(e,t){const a=Math.round(Q*e),n=Math.round(ee*e),r=document.createElement("canvas");r.width=a,r.height=n;const c=r.getContext("2d");if(!c)throw new Error("Failed to get canvas context");c.drawImage(t,0,0,a,n);const l=e<1?.8:.95;return r.toDataURL("image/jpeg",l)}function va(e,t){const a=Math.round(Q*e),n=Math.round(ee*e),r=document.createElement("canvas");r.width=a,r.height=n;const c=r.getContext("2d");if(!c)throw new Error("Failed to get canvas context");const l=It*e,o=Pt*e,s=z.badges,d=(p,x)=>{const h=x/2,f=p.x*e-h,y=p.y*e-h;c.drawImage(t,f,y,x,x)};return d(s.topLeft,l),d(s.topRight,l),d(s.bottomLeft,o),d(s.bottomRight,o),r.toDataURL("image/png")}function Et(e,t,a,n=1){const r=kt[a].banner[t];Tt(e,r,z.banner.centerX*n,z.banner.centerY*n,z.banner.radius*n,z.banner.fontSize*n,z.banner.color)}function Lt(e,t,a,n,r,c,l){const o=Math.round(Q*n),s=Math.round(ee*n),d=document.createElement("canvas");d.width=o,d.height=s;const p=d.getContext("2d");if(!p)throw new Error("Failed to get canvas context");p.drawImage(r,0,0,o,s);{const h=It*n,f=Pt*n,y=z.badges,v=(g,I)=>{const P=I/2,D=g.x*n-P,j=g.y*n-P;p.drawImage(l,D,j,I,I)};v(y.topLeft,h),v(y.topRight,h),v(y.bottomLeft,f),v(y.bottomRight,f)}if(p.drawImage(c,0,0,o,s),a==="front"){const h=kt[t].banner[e];Tt(p,h,z.banner.centerX*n,z.banner.centerY*n,z.banner.radius*n,z.banner.fontSize*n,z.banner.color)}const x=n<1?.8:.95;return d.toDataURL("image/jpeg",x)}async function Ct(e,t,a){const n=`${e}-${t}-${a}`;if(Ee.has(n))return Ee.get(n);const r=U.background||await E(O.background),c=a==="front"?U.frontFrame||await E(O.frontFrame):U.backFrame||await E(O.backFrame),l=U.badges[e]||await E(he[e]),o=Lt(e,t,a,Se,r,c,l);return Ee.set(n,o),o}async function Xe(e,t,a){const n=`${e}-${t}-${a}`;if(oe.has(n))return oe.get(n);const r=U.background||await E(O.background),c=a==="front"?U.frontFrame||await E(O.frontFrame):U.backFrame||await E(O.backFrame),l=U.badges[e]||await E(he[e]),o=Lt(e,t,a,1,r,c,l);if(oe.size>4){const s=oe.keys().next().value;s&&oe.delete(s)}return oe.set(n,o),o}function ka(){return{width:Q,height:ee}}function Ia(){Ee.clear(),oe.clear(),Oe.clear(),_e.clear(),$e.clear()}async function Ke(e,t,a="front",n=Se){const r=`bg-${n}`;let c=Oe.get(r);if(!c){const p=U.background||await E(O.background);c=ya(n,p),Oe.set(r,c)}const l=`badges-${e}-${n}`;let o=_e.get(l);if(!o){const p=U.badges[e]||await E(he[e]);o=va(n,p),_e.set(l,o)}const s=`${a}-${n}`;let d=$e.get(s);if(!d){const p=a==="front"?U.frontFrame||await E(O.frontFrame):U.backFrame||await E(O.backFrame),x=Math.round(Q*n),h=Math.round(ee*n),f=document.createElement("canvas");f.width=x,f.height=h;const y=f.getContext("2d");if(!y)throw new Error("Failed to get canvas context");y.drawImage(p,0,0,x,h),d=f.toDataURL("image/png"),$e.set(s,d)}return{background:c,badges:o,frame:d}}async function Pa(){const e=[1,5,10],t=["de","en"],a=["front","back"],n=[];for(const r of e)for(const c of t)for(const l of a)n.push(Ct(r,c,l));await Promise.all(n)}function Je(e,t){return{front:"",back:"",width:Q,height:ee}}const je={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}}},de=je,ue=je;function Qe(e){return je}const qe=.75;function Ta(e){const t=Qe(),a=qe,n=r=>({portrait:{x:r.portrait.x*a,y:r.portrait.y*a,radiusX:r.portrait.radiusX*a,radiusY:r.portrait.radiusY*a},namePlate:{x:r.namePlate.x*a,y:r.namePlate.y*a,fontSize:r.namePlate.fontSize*a,maxWidth:r.namePlate.maxWidth?r.namePlate.maxWidth*a:void 0,lineHeight:r.namePlate.lineHeight?r.namePlate.lineHeight*a:void 0,align:r.namePlate.align},contactInfo:r.contactInfo?{x:r.contactInfo.x*a,y:r.contactInfo.y*a,fontSize:r.contactInfo.fontSize*a,maxWidth:r.contactInfo.maxWidth?r.contactInfo.maxWidth*a:void 0,lineHeight:r.contactInfo.lineHeight?r.contactInfo.lineHeight*a:void 0,align:r.contactInfo.align}:void 0,description:r.description?{x:r.description.x*a,y:r.description.y*a,fontSize:r.description.fontSize*a,maxWidth:r.description.maxWidth?r.description.maxWidth*a:void 0,lineHeight:r.description.lineHeight?r.description.lineHeight*a:void 0,align:r.description.align}:void 0,signature:r.signature?{x:r.signature.x*a,y:r.signature.y*a,width:r.signature.width*a,height:r.signature.height*a,labelFontSize:r.signature.labelFontSize*a}:void 0});return{front:n(t.front),back:n(t.back)}}function Ea(e,t){const a=Je();return{...a,width:Math.round(a.width*qe),height:Math.round(a.height*qe)}}function La(e,t){const[a,n]=b.useState(e);return b.useEffect(()=>{const r=setTimeout(()=>n(e),t);return()=>clearTimeout(r)},[e,t]),a}function Ca({onPortraitClick:e,onFileDrop:t}={}){const a=w(m=>m.appLanguage),n=w(m=>m.voucherConfig.language),r=w(m=>m.voucherConfig.hours),c=w(m=>m.voucherConfig.description),l=w(m=>m.voucherConfig.templateHue),o=w(m=>m.personalInfo),s=w(m=>m.portrait),d=w(m=>m.currentSide),p=w(m=>m.flipSide),x=w(m=>m.setPortraitPan),h=La(l,150),f=J(a),y=b.useRef(null),v=b.useRef(null),g=b.useRef(null),[I,P]=b.useState(!1),[D,j]=b.useState(!1),[B,M]=b.useState(!1),[A,S]=b.useState(!1),T=b.useRef(null),L=Ea(),R=Ta(),V=s.useEnhanced&&s.enhanced?s.enhanced:s.original,te=Ve(n,r,c),[G,F]=b.useState(""),[W,$]=b.useState(""),[ae,Be]=b.useState(""),[be,Ne]=b.useState(""),[xe,ne]=b.useState(""),[se,re]=b.useState(""),[ve,ke]=b.useState(!0);b.useEffect(()=>{let m=!0;ke(!0);async function H(){const[_,Z]=await Promise.all([Ke(r,n,"front"),Ke(r,n,"back")]);m&&(F(_.background),$(_.badges),Be(_.frame),Ne(Z.background),ne(Z.badges),re(Z.frame),ke(!1))}return H(),()=>{m=!1}},[r,n]),b.useEffect(()=>{!y.current||!G||!W||!ae||yt(y.current,G,W,ae,V,o.name,R.front,L.width,L.height,s.zoom,s.panX,s.panY,h,r,n)},[L,G,W,ae,V,o.name,R,s.zoom,s.panX,s.panY,h,r,n]),b.useEffect(()=>{!v.current||!be||!xe||!se||vt(v.current,be,xe,se,o.name,o.email,o.phone,te,R.back,L.width,L.height,h,r,n)},[L,be,xe,se,o,te,R,h,r,n]);const we=()=>{P(!I),p()};b.useEffect(()=>{P(d==="back")},[d]);const q=b.useCallback((m,H)=>{if(!g.current||d!=="front")return!1;const _=g.current.getBoundingClientRect(),Z=_.width/L.width,He=_.height/L.height,De=(m-_.left)/Z,Ae=(H-_.top)/He,{x:Me,y:Wt,radiusX:Yt,radiusY:zt}=R.front.portrait,et=(De-Me)/Yt,tt=(Ae-Wt)/zt;return et*et+tt*tt<=1},[d,L.width,L.height,R.front.portrait]),Ie=b.useCallback((m,H)=>{!s.original||s.zoom<=1||!q(m,H)||(j(!0),T.current={x:m,y:H,panX:s.panX,panY:s.panY})},[s.original,s.zoom,s.panX,s.panY,q]),Pe=b.useCallback((m,H)=>{if(!D||!T.current||!g.current)return;const _=g.current.getBoundingClientRect(),Z=3/Math.max(_.width,_.height),He=(m-T.current.x)*Z,De=(H-T.current.y)*Z,Ae=Math.max(-1,Math.min(1,T.current.panX+He)),Me=Math.max(-1,Math.min(1,T.current.panY+De));x(Ae,Me)},[D,x]),u=b.useCallback(()=>{j(!1),T.current=null},[]),k=b.useCallback((m,H)=>{!s.original&&q(m,H)&&e&&e()},[s.original,q,e]),N=m=>{q(m.clientX,m.clientY)&&(m.preventDefault(),s.original&&s.zoom>1&&Ie(m.clientX,m.clientY))},C=m=>{D||k(m.clientX,m.clientY)},X=m=>{Pe(m.clientX,m.clientY),M(q(m.clientX,m.clientY))},Y=()=>u(),Ht=()=>{u(),M(!1)},Dt=m=>{if(m.touches.length===1){const H=m.touches[0];s.zoom>1&&q(H.clientX,H.clientY)&&Ie(H.clientX,H.clientY)}},At=m=>{m.touches.length===1&&Pe(m.touches[0].clientX,m.touches[0].clientY)},Mt=()=>u(),Ut=d==="front"&&s.original&&s.zoom>1,Ft=L.width/L.height;return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"flex justify-between items-center",children:[i.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[i.jsx("button",{className:`tab ${d==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>d!=="front"&&we(),children:f.preview.front}),i.jsx("button",{className:`tab ${d==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>d!=="back"&&we(),children:f.preview.back})]}),i.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:we,children:[i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),f.preview.flip]})]}),i.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:Ft,perspective:"1500px"},children:[ve&&i.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:i.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),i.jsxs("div",{ref:g,className:`relative w-full h-full shadow-lg ${B&&Ut?D?"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:C,onMouseDown:N,onMouseMove:X,onMouseUp:Y,onMouseLeave:Ht,onTouchStart:Dt,onTouchMove:At,onTouchEnd:Mt,children:[i.jsx("canvas",{ref:y,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),i.jsx("canvas",{ref:v,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),!s.original&&d==="front"&&(e||t)&&i.jsx("div",{className:`absolute flex flex-col items-center justify-center cursor-pointer transition-colors duration-300 ease-in-out ${A?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(R.front.portrait.x-R.front.portrait.radiusX)/L.width*100}%`,top:`${(R.front.portrait.y-R.front.portrait.radiusY)/L.height*100}%`,width:`${R.front.portrait.radiusX*2/L.width*100}%`,height:`${R.front.portrait.radiusY*2/L.height*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},onClick:m=>{m.stopPropagation(),e==null||e()},onDragOver:m=>{m.preventDefault(),m.stopPropagation(),S(!0)},onDragLeave:m=>{m.preventDefault(),m.stopPropagation(),S(!1)},onDrop:m=>{m.preventDefault(),m.stopPropagation(),S(!1);const H=m.dataTransfer.files[0];H&&H.type.startsWith("image/")&&t&&t(H)},children:i.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 flex flex-col items-center gap-1 h-auto py-3 px-4 bg-base-100/20 hover:bg-base-100/30",onClick:m=>{m.stopPropagation(),e==null||e()},children:[i.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-11 h-10 text-base-content/50",fill:"none",viewBox:"0 0 26 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[i.jsx("circle",{cx:"11",cy:"8",r:"4"}),i.jsx("path",{d:"M3 21c0-4 4-6 8-6s8 2 8 6"}),i.jsx("line",{x1:"22",y1:"4",x2:"22",y2:"10",strokeWidth:2}),i.jsx("line",{x1:"19",y1:"7",x2:"25",y2:"7",strokeWidth:2})]}),i.jsx("span",{className:"text-xs",children:a==="de"?"Foto hochladen":"Upload photo"})]})})]})]})]})}function Sa(){const e=b.useRef(null),t=b.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const ja=`
|
|
2
2
|
// RGB to HSL conversion
|
|
3
3
|
function rgbToHsl(r, g, b) {
|
|
4
4
|
r /= 255;
|
|
@@ -373,4 +373,4 @@ self.onmessage = async (e) => {
|
|
|
373
373
|
});
|
|
374
374
|
}
|
|
375
375
|
};
|
|
376
|
-
`;let
|
|
376
|
+
`;let Ye=null,ot=null;function Ra(){if(!Ye){const e=new Blob([ja],{type:"application/javascript"});ot=URL.createObjectURL(e),Ye=new Worker(ot,{type:"module"})}return Ye}async function ze(e){const a=await(await fetch(e)).blob();return URL.createObjectURL(a)}function it(e,t){const a=new Uint8Array(e);let n="";for(let r=0;r<a.length;r++)n+=String.fromCharCode(a[r]);return`data:${t};base64,${btoa(n)}`}async function St(e){const{frontTemplateSrc:t,backTemplateSrc:a,templateWidth:n,templateHeight:r,layout:c,portrait:l,portraitZoom:o=1,portraitPanX:s=0,portraitPanY:d=0,templateHue:p=160,name:x,email:h,phone:f,description:y,language:v="de"}=e,[g,I]=await Promise.all([ze(t),ze(a)]);let P=null;return l&&(P=await ze(l)),new Promise((D,j)=>{const B=Ra(),M=S=>{if(B.removeEventListener("message",M),B.removeEventListener("error",A),URL.revokeObjectURL(g),URL.revokeObjectURL(I),P&&URL.revokeObjectURL(P),S.data.type==="success")try{const{frontImageData:T,backImageData:L,width:R,height:V}=S.data;if(!T||!L||!R||!V){j(new Error("Invalid response from worker"));return}const te=it(T,"image/jpeg"),G=it(L,"image/jpeg"),F=R/96*25.4,W=V/96*25.4,$=new $t.jsPDF({orientation:F>W?"landscape":"portrait",unit:"mm",format:[F,W]});$.addImage(te,"JPEG",0,0,F,W),$.addPage([F,W]),$.addImage(G,"JPEG",0,0,F,W);const ae=$.output("blob");D(ae)}catch(T){j(T)}else j(new Error(S.data.error))},A=S=>{B.removeEventListener("message",M),B.removeEventListener("error",A),URL.revokeObjectURL(g),URL.revokeObjectURL(I),P&&URL.revokeObjectURL(P),j(new Error(S.message))};B.addEventListener("message",M),B.addEventListener("error",A),B.postMessage({type:"generate",frontTemplateUrl:g,backTemplateUrl:I,portraitUrl:P,templateWidth:n,templateHeight:r,templateHue:p,portraitZoom:o,portraitPanX:s,portraitPanY:d,layout:{front:{portrait:c.front.portrait,namePlate:c.front.namePlate},back:{namePlate:c.back.namePlate,contactInfo:c.back.contactInfo,description:c.back.description,signature:c.back.signature}},name:x,email:h,phone:f,description:y,language:v})})}function jt(e,t){const a=URL.createObjectURL(e),n=document.createElement("a");n.href=a,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(a)}async function Rt(e){const t=await St(e);jt(t,e.filename)}function Ba(){const e=w(g=>g.appLanguage),t=w(g=>g.voucherConfig.language),a=w(g=>g.voucherConfig.hours),n=w(g=>g.voucherConfig.description),r=w(g=>g.voucherConfig.templateHue),c=w(g=>g.personalInfo),l=w(g=>g.portrait),o=w(g=>g.isExporting),s=w(g=>g.setIsExporting),d=J(e),p=Je(),x=Qe(),h=l.useEnhanced&&l.enhanced?l.enhanced:l.original,f=Ve(t,a,n),y=c.name.trim().length>0&&c.email.trim().length>0&&c.phone.trim().length>0&&l.original!==null,v=async()=>{if(!(!y||o)){s(!0);try{const[g,I]=await Promise.all([Xe(a,t,"front"),Xe(a,t,"back")]),P=`zeitgutschein-${a}h-${c.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await Rt({frontTemplateSrc:g,backTemplateSrc:I,templateWidth:p.width,templateHeight:p.height,layout:x,portrait:h,portraitZoom:l.zoom,portraitPanX:l.panX,portraitPanY:l.panY,templateHue:r,name:c.name,email:c.email,phone:c.phone,description:f,filename:P,language:t})}catch(g){console.error("PDF export failed:",g)}finally{s(!1)}}};return i.jsxs("button",{className:`btn btn-primary flex-1 ${y?"":"btn-disabled"}`,onClick:v,disabled:!y,"aria-busy":o,children:[o?i.jsx("span",{className:"loading loading-spinner loading-sm"}):i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),d.export.button]})}function Bt(){const e=w(n=>n.appLanguage),t=w(n=>n.setAppLanguage),a=n=>{t(n)};return i.jsxs("div",{className:"join",children:[i.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:"DE"}),i.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:"EN"})]})}function Na(){const e=w(a=>a.appLanguage),t=J(e);return i.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[i.jsx("div",{className:"navbar-start",children:i.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),i.jsx("div",{className:"navbar-center hidden sm:flex",children:i.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),i.jsx("div",{className:"navbar-end",children:i.jsx(Bt,{})})]})}const Le="/",Ha={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${Le}templates/front_hdpi_de.jpg`,back:`${Le}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:de.front.portrait,name:de.front.namePlate},back:{name:de.back.namePlate,contactInfo:de.back.contactInfo,description:de.back.description}},languages:["de"]},Da={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${Le}templates/front_ldpi_en.png`,back:`${Le}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:ue.front.portrait,name:ue.front.namePlate},back:{name:ue.back.namePlate,contactInfo:ue.back.contactInfo,description:ue.back.description}},languages:["en"]},st=[Ha,Da],Nt={async listTemplates(e){let t=[...st];return e!=null&&e.type&&(t=t.filter(a=>a.type===e.type)),e!=null&&e.category&&(t=t.filter(a=>a.category===e.category)),e!=null&&e.language&&(t=t.filter(a=>a.languages.includes(e.language))),t},async getTemplate(e){const t=st.find(a=>a.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Aa(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let Re=Nt;function Ma(e){Re=e}function Ua(){return Re}async function Fa(e){return Re.listTemplates(e)}async function Wa(e){return Re.getTemplate(e)}exports.ApiKeyModal=ht;exports.BillPreview=Ca;exports.ExportButton=Ba;exports.Header=Na;exports.LAYOUT_HDPI=de;exports.LAYOUT_LDPI=ue;exports.LanguageToggle=Bt;exports.PREVIEW_HEIGHT=xa;exports.PREVIEW_WIDTH=ba;exports.PersonalInfoForm=Gt;exports.PortraitUpload=ma;exports.TEMPLATE_HEIGHT=ee;exports.TEMPLATE_LAYOUT=je;exports.TEMPLATE_WIDTH=Q;exports.VoucherConfig=pa;exports.applyEngravingEffect=lt;exports.applyHueShift=dt;exports.clearCompositorCache=Ia;exports.composeTemplate=Ct;exports.composeTemplateFullRes=Xe;exports.downloadBlob=jt;exports.drawContactInfo=wt;exports.drawMultilineText=xt;exports.drawOvalPortrait=bt;exports.drawTemplate=ie;exports.drawText=Ze;exports.enhancePortrait=ua;exports.exportBillAsPDF=Rt;exports.formatDescription=Ve;exports.generateBillPDF=St;exports.getApiKey=Ce;exports.getDefaultTemplateId=Aa;exports.getLayout=Qe;exports.getRemoveBackgroundEndpoint=ia;exports.getTemplate=Je;exports.getTemplateById=Wa;exports.getTemplateDimensions=ka;exports.getTemplateLayers=Ke;exports.getTemplateProvider=Ua;exports.hasApiKey=Te;exports.hasCustomEndpoint=sa;exports.listTemplates=Fa;exports.loadImage=E;exports.preloadAllTemplates=Pa;exports.preloadBaseImages=wa;exports.removeBackground=pt;exports.renderBackSide=vt;exports.renderFrontSide=yt;exports.setApiKey=mt;exports.setRemoveBackgroundEndpoint=oa;exports.setTemplateProvider=Ma;exports.staticTemplateProvider=Nt;exports.t=J;exports.useBillCanvasRefs=Sa;exports.useBillStore=w;
|
package/dist/index.d.ts
CHANGED
|
@@ -55,7 +55,12 @@ declare interface BillActions {
|
|
|
55
55
|
reset: () => void;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export declare function BillPreview(): JSX.Element;
|
|
58
|
+
export declare function BillPreview({ onPortraitClick, onFileDrop }?: BillPreviewProps): JSX.Element;
|
|
59
|
+
|
|
60
|
+
declare interface BillPreviewProps {
|
|
61
|
+
onPortraitClick?: () => void;
|
|
62
|
+
onFileDrop?: (file: File) => void;
|
|
63
|
+
}
|
|
59
64
|
|
|
60
65
|
export declare type BillSide = 'front' | 'back';
|
|
61
66
|
|