@antontranelis/money-printer 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),Ne=require("zustand"),Se=require("zustand/middleware"),b=require("react"),Ee=require("jspdf");var R=typeof document<"u"?document.currentScript:null;const J={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1},currentSide:"front",isEnhancing:!1,isExporting:!1},y=Ne.create()(Se.persist(e=>({...J,setPersonalInfo:t=>e(a=>({personalInfo:{...a.personalInfo,...t}})),setVoucherConfig:t=>e(a=>({voucherConfig:{...a.voucherConfig,...t}})),setPortrait:(t,a=null)=>e({portrait:{original:t,enhanced:a,useEnhanced:!1,zoom:1}}),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}})),setCurrentSide:t=>e({currentSide:t}),flipSide:()=>e(t=>({currentSide:t.currentSide==="front"?"back":"front"})),setIsEnhancing:t=>e({isEnhancing:t}),setIsExporting:t=>e({isExporting:t}),setLanguage:t=>e(a=>({voucherConfig:{...a.voucherConfig,language:t}})),setHours:t=>e(a=>({voucherConfig:{...a.voucherConfig,hours:t}})),reset:()=>e(J)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig})})),Te={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?"}},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"}},Ce={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?"}},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"}},Ae={de:Te,en:Ce};function A(e){return Ae[e]}function W(e,t,a){if(a&&a.trim())return a;const n=A(e),o=t===1?n.form.voucher.hourLabel:n.form.voucher.hoursLabel;return n.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",o)}function Le(){const e=y(o=>o.voucherConfig.language),t=y(o=>o.personalInfo),a=y(o=>o.setPersonalInfo),n=A(e);return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.name})}),r.jsx("input",{type:"text",placeholder:n.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:o=>a({name:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.email})}),r.jsx("input",{type:"email",placeholder:n.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:o=>a({email:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.phone})}),r.jsx("input",{type:"tel",placeholder:n.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:o=>a({phone:o.target.value})})]})]})}const K={},De="https://api.stability.ai/v1/generation",_e="https://api.stability.ai/v2beta/stable-image/edit/remove-background",te="stability_api_key",Re={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"},Q=[{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 Be(e,t){const a=e/t;let n=Q[0],o=1/0;for(const l of Q){const d=l.width/l.height,i=Math.abs(a-d);i<o&&(o=i,n=l)}return n}function $e(e){return new Promise((t,a)=>{const n=new Image;n.onload=()=>{const o=Be(n.width,n.height),l=document.createElement("canvas");l.width=o.width,l.height=o.height;const d=l.getContext("2d");if(!d){a(new Error("Failed to get canvas context"));return}const i=n.width/n.height,s=o.width/o.height;let c=0,p=0,m=n.width,g=n.height;i>s?(m=n.height*s,c=(n.width-m)/2):(g=n.width/s,p=(n.height-g)/2),d.drawImage(n,c,p,m,g,0,0,o.width,o.height),t(l.toDataURL("image/png"))},n.onerror=()=>a(new Error("Failed to load image")),n.src=e})}function ne(e){var d;const t=e.split(","),a=((d=t[0].match(/:(.*?);/))==null?void 0:d[1])||"image/png",n=atob(t[1]),o=n.length,l=new Uint8Array(o);for(let i=0;i<o;i++)l[i]=n.charCodeAt(i);return new Blob([l],{type:a})}function F(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:R&&R.tagName.toUpperCase()==="SCRIPT"&&R.src||new URL("index.cjs",document.baseURI).href}<"u"&&(K==null?void 0:K.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(te):null}function ae(e){localStorage.setItem(te,e)}function re(){return F()!==null}async function Ue(e){const t=F();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:a,style:n,strength:o=.35}=e,l=await $e(a),d=ne(l),i=new FormData;i.append("init_image",d,"portrait.png"),i.append("init_image_mode","IMAGE_STRENGTH"),i.append("image_strength",String(1-o)),i.append("text_prompts[0][text]",Re[n]),i.append("text_prompts[0][weight]","1"),i.append("cfg_scale","7"),i.append("samples","1"),i.append("steps","30");const c=await fetch(`${De}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:i});if(!c.ok){const m=await c.text();throw console.error("Stability AI error:",m),c.status===401?new Error("Invalid API key"):c.status===402?new Error("Insufficient credits"):c.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${c.status}`)}const p=await c.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 oe(e){const t=F();if(!t)throw new Error("No Stability AI API key configured");const a=ne(e),n=new FormData;n.append("image",a,"image.png"),n.append("output_format","png");const o=await fetch(_e,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:n});if(!o.ok){const d=await o.text();throw console.error("Stability AI remove background error:",d),o.status===401?new Error("Invalid API key"):o.status===402?new Error("Insufficient credits"):o.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${o.status}`)}const l=await o.blob();return new Promise((d,i)=>{const s=new FileReader;s.onload=()=>d(s.result),s.onerror=()=>i(new Error("Failed to read result")),s.readAsDataURL(l)})}async function ie(e){return new Promise((t,a)=>{const n=new Image;n.onload=()=>{const o=document.createElement("canvas"),l=o.getContext("2d");if(!l){a(new Error("Failed to get canvas context"));return}o.width=n.width,o.height=n.height,l.drawImage(n,0,0);const d=l.getImageData(0,0,o.width,o.height),i=d.data;for(let s=0;s<i.length;s+=4){const c=i[s],p=i[s+1],m=i[s+2];if(i[s+3]===0)continue;const f=.299*c+.587*p+.114*m,h=1.4;let v=259*(h*255+255)/(255*(259-h*255))*(f-128)+128;v=Math.max(0,Math.min(255,v));const w=Math.min(255,v*1.1+20),N=Math.min(255,v*.95+10),x=Math.min(255,v*.8);i[s]=w,i[s+1]=N,i[s+2]=x}l.putImageData(d,0,0),t(o.toDataURL("image/png"))},n.onerror=()=>a(new Error("Failed to load image")),n.src=e})}function Fe(){const[e,t]=b.useState(!1),[a,n]=b.useState(!1),[o,l]=b.useState(null),[d,i]=b.useState(re()),s=b.useCallback(()=>l(null),[]),c=b.useCallback(g=>{ae(g),i(!0),l(null)},[]),p=b.useCallback(async(g,f="vintage")=>{t(!0),l(null);try{return await ie(g)}catch(h){const j=h instanceof Error?h.message:"Enhancement failed";throw l(j),h}finally{t(!1)}},[]),m=b.useCallback(async g=>{n(!0),l(null);try{return await oe(g)}catch(f){const h=f instanceof Error?f.message:"Background removal failed";throw l(h),f}finally{n(!1)}},[]);return{enhance:p,removeBg:m,isEnhancing:e,isRemovingBg:a,error:o,hasKey:d,setApiKey:c,clearError:s}}function se({isOpen:e,onClose:t,onSubmit:a}){const n=y(c=>c.voucherConfig.language),[o,l]=b.useState("");if(!e)return null;const d=c=>{c.preventDefault(),o.trim()&&(a(o.trim()),l(""),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 r.jsxs("dialog",{className:"modal modal-open",children:[r.jsxs("div",{className:"modal-box",children:[r.jsx("h3",{className:"font-bold text-lg",children:s.title}),r.jsx("p",{className:"py-4 text-sm opacity-80",children:s.description}),r.jsxs("form",{onSubmit:d,children:[r.jsxs("div",{className:"form-control",children:[r.jsx("input",{type:"password",placeholder:s.placeholder,className:"input input-bordered w-full",value:o,onChange:c=>l(c.target.value),autoFocus:!0}),r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text-alt",children:s.hint})})]}),r.jsxs("div",{className:"modal-action",children:[r.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:s.cancel}),r.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!o.trim(),children:s.submit})]})]})]}),r.jsx("form",{method:"dialog",className:"modal-backdrop",children:r.jsx("button",{onClick:t,children:"close"})})]})}function Me(){const e=y(u=>u.voucherConfig.language),t=y(u=>u.portrait),a=y(u=>u.setPortrait),n=y(u=>u.setPortraitZoom),{enhance:o,removeBg:l,isEnhancing:d,isRemovingBg:i,error:s,hasKey:c,setApiKey:p}=Fe(),m=A(e),g=b.useRef(null),[f,h]=b.useState(!1),[j,v]=b.useState(!1),[w,N]=b.useState(null),[x,k]=b.useState(!1),[E,L]=b.useState(!1),B=b.useCallback(async u=>{if(!u.type.startsWith("image/"))return;const P=new FileReader;P.onload=async D=>{var _;const S=(_=D.target)==null?void 0:_.result;N(S),a(S),k(!1),L(!1)},P.readAsDataURL(u)},[a]),z=b.useCallback(u=>{u.preventDefault(),h(!1);const P=u.dataTransfer.files[0];P&&B(P)},[B]),be=b.useCallback(u=>{u.preventDefault(),h(!0)},[]),xe=b.useCallback(u=>{u.preventDefault(),h(!1)},[]),ye=()=>{var u;(u=g.current)==null||u.click()},we=u=>{var D;const P=(D=u.target.files)==null?void 0:D[0];P&&B(P)},H=b.useCallback(async(u,P,D)=>{let S=u;if(P&&c)try{S=await l(S)}catch(_){console.error("Background removal failed:",_)}if(D)try{S=await o(S,"vintage")}catch(_){console.error("Enhancement failed:",_)}a(S)},[c,l,o,a]),ve=async()=>{if(!w)return;if(!x&&!c){v(!0);return}const u=!x;k(u),await H(w,u,E)},Ie=async()=>{if(!w)return;const u=!E;L(u),await H(w,x,u)},ke=async u=>{p(u),w&&(k(!0),await H(w,!0,E))},je=()=>{a(null),N(null),k(!1),L(!1)},Pe=t.original;return r.jsxs("div",{className:"space-y-4",children:[t.original?r.jsxs("div",{className:"space-y-4",children:[r.jsx("div",{className:"flex justify-center",children:r.jsxs("div",{className:"relative",children:[r.jsx("div",{className:"w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg",children:r.jsx("img",{src:Pe||"",alt:"Portrait",className:"w-full h-full object-cover",style:{transform:`scale(${t.zoom})`}})}),r.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:je,children:r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),r.jsxs("div",{className:"form-control",children:[r.jsxs("label",{className:"label",children:[r.jsx("span",{className:"label-text",children:m.form.portrait.zoom}),r.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),r.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:u=>n(parseFloat(u.target.value)),className:"range range-primary range-sm"})]}),r.jsxs("div",{className:"flex flex-col gap-3",children:[r.jsx("div",{className:"form-control",children:r.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[r.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${i?"opacity-50":""}`,checked:x,onChange:ve,disabled:i}),r.jsxs("span",{className:"label-text flex items-center gap-2",children:[i?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!c&&r.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),r.jsx("div",{className:"form-control",children:r.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[r.jsx("input",{type:"checkbox",className:`toggle toggle-secondary ${d?"opacity-50":""}`,checked:E,onChange:Ie,disabled:d}),r.jsx("span",{className:"label-text flex items-center gap-2",children:d?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Gravur-Effekt wird angewendet...":"Applying engraving effect..."]}):e==="de"?"Gravur-Effekt":"Engraving effect"})]})}),s&&r.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[r.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:r.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"})}),r.jsx("span",{children:s})]})]})]}):r.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${i?"border-primary bg-primary/10 pointer-events-none":f?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:z,onDragOver:be,onDragLeave:xe,onClick:ye,children:[r.jsx("input",{ref:g,type:"file",accept:"image/*",className:"hidden",onChange:we}),i?r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),r.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.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:r.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"})}),r.jsx("p",{className:"font-medium",children:m.form.portrait.upload}),r.jsx("p",{className:"text-sm text-base-content/60",children:m.form.portrait.dragDrop})]})]}),r.jsx(se,{isOpen:j,onClose:()=>v(!1),onSubmit:ke})]})}function ze(){return null}const I=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:R&&R.tagName.toUpperCase()==="SCRIPT"&&R.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",le={en:{1:{front:`${I}templates/front_ldpi_en.png`,back:`${I}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${I}templates/front_ldpi_en.png`,back:`${I}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${I}templates/front_ldpi_en.png`,back:`${I}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${I}templates/front_hdpi_de.webp`,back:`${I}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${I}templates/front_hdpi_de.webp`,back:`${I}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${I}templates/front_hdpi_de.webp`,back:`${I}templates/back_hdpi_de.webp`,width:6144,height:3200}}},T={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},C={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function q(e){return e==="de"?C:T}function Y(e,t){return le[e][t]}const O=new Map;async function $(e){return O.has(e)?O.get(e):new Promise((t,a)=>{const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{O.set(e,n),t(n)},n.onerror=a,n.src=e})}function V(e,t,a,n){e.drawImage(t,0,0,a,n)}function ce(e,t,a,n,o,l,d=1){e.save(),e.beginPath(),e.ellipse(a,n,o,l,0,0,Math.PI*2),e.closePath(),e.clip();const i=t.width/t.height,s=o/l,c=o*2,p=l*2;let m,g;i>s?(g=p,m=p*i):(m=c,g=c/i),m*=d,g*=d;const f=a-m/2,h=n-g/2;e.drawImage(t,f,h,m,g),e.restore()}function G(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 de(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 o=a.maxWidth||400,l=a.lineHeight||a.fontSize*1.4,d=t.split(" "),i=[];let s="";for(const m of d){const g=s?`${s} ${m}`:m;e.measureText(g).width>o&&s?(i.push(s),s=m):s=g}s&&i.push(s);const c=i.length*l;let p=a.y-c/2;for(const m of i)e.fillText(m,a.x,p),p+=l;e.restore()}function he(e,t,a,n,o,l="#2a3a2a"){e.save(),e.font=`${o.fontSize}px "Times New Roman", serif`,e.textAlign=o.align||"center",e.textBaseline="middle",e.fillStyle=l;const d=o.lineHeight||o.fontSize*1.8,i=[t,a,n].filter(Boolean),s=(i.length-1)*d;let c=o.y-s/2;for(const p of i)p&&(e.fillText(p,o.x,c),c+=d);e.restore()}async function Z(e,t,a,n,o,l,d,i=1){const s=e.getContext("2d");if(!s)return;e.width=l,e.height=d,s.clearRect(0,0,l,d);const c=await $(t);if(V(s,c,l,d),a)try{const p=await $(a);ce(s,p,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,i)}catch(p){console.error("Failed to load portrait:",p)}n&&G(s,n,o.namePlate)}async function X(e,t,a,n,o,l,d,i,s){const c=e.getContext("2d");if(!c)return;e.width=i,e.height=s,c.clearRect(0,0,i,s);const p=await $(t);V(c,p,i,s),d.contactInfo&&(a||n||o)&&he(c,a,n,o,d.contactInfo),d.description&&l&&de(c,l,d.description),a&&G(c,a,d.namePlate)}function He(){const e=y(x=>x.voucherConfig.language),t=y(x=>x.voucherConfig.hours),a=y(x=>x.voucherConfig.description),n=y(x=>x.personalInfo),o=y(x=>x.portrait),l=y(x=>x.currentSide),d=y(x=>x.flipSide),i=A(e),s=b.useRef(null),c=b.useRef(null),p=b.useRef(null),[m,g]=b.useState(!1),f=Y(e,t),h=q(e),j=o.useEnhanced&&o.enhanced?o.enhanced:o.original,v=W(e,t,a);b.useEffect(()=>{s.current&&Z(s.current,f.front,j,n.name,h.front,f.width,f.height,o.zoom)},[f,j,n.name,h,o.zoom]),b.useEffect(()=>{c.current&&X(c.current,f.back,n.name,n.email,n.phone,v,h.back,f.width,f.height)},[f,n,v,h]);const w=()=>{g(!0),setTimeout(()=>{d(),g(!1)},150)},N=f.width/f.height;return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[r.jsx("button",{className:`tab ${l==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="front"&&w(),children:i.preview.front}),r.jsx("button",{className:`tab ${l==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="back"&&w(),children:i.preview.back})]}),r.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:w,children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),i.preview.flip]})]}),r.jsxs("div",{ref:p,className:"relative w-full overflow-hidden shadow-lg",style:{aspectRatio:N},children:[r.jsx("canvas",{ref:s,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="front"?m?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),r.jsx("canvas",{ref:c,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="back"?m?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Ke(){const e=b.useRef(null),t=b.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}async function ue(e){const{frontTemplateSrc:t,backTemplateSrc:a,templateWidth:n,templateHeight:o,layout:l,portrait:d,portraitZoom:i=1,name:s,email:c,phone:p,description:m}=e,g=document.createElement("canvas"),f=document.createElement("canvas");await Promise.all([Z(g,t,d,s,l.front,n,o,i),X(f,a,s,c,p,m,l.back,n,o)]);const h=new Ee({orientation:"landscape",unit:"mm",format:"a4"}),j=297,v=210,w=10,N=n/o;let x=j-w*2,k=x/N;k>v-w*2&&(k=v-w*2,x=k*N);const E=(j-x)/2,L=(v-k)/2,B=g.toDataURL("image/jpeg",.95);h.addImage(B,"JPEG",E,L,x,k),h.addPage();const z=f.toDataURL("image/jpeg",.95);return h.addImage(z,"JPEG",E,L,x,k),h.output("blob")}function pe(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 me(e){const t=await ue(e);pe(t,e.filename)}function Oe(){const e=y(h=>h.voucherConfig.language),t=y(h=>h.voucherConfig.hours),a=y(h=>h.voucherConfig.description),n=y(h=>h.personalInfo),o=y(h=>h.portrait),l=y(h=>h.isExporting),d=y(h=>h.setIsExporting),i=A(e),s=Y(e,t),c=q(e),p=o.useEnhanced&&o.enhanced?o.enhanced:o.original,m=W(e,t,a),g=n.name.trim().length>0&&n.email.trim().length>0&&n.phone.trim().length>0&&o.original!==null,f=async()=>{if(!(!g||l)){d(!0);try{const h=`zeitgutschein-${t}h-${n.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await me({frontTemplateSrc:s.front,backTemplateSrc:s.back,templateWidth:s.width,templateHeight:s.height,layout:c,portrait:p,portraitZoom:o.zoom,name:n.name,email:n.email,phone:n.phone,description:m,filename:h})}catch(h){console.error("PDF export failed:",h)}finally{d(!1)}}};return r.jsx("button",{className:`btn btn-primary flex-1 ${l?"loading":""}`,onClick:f,disabled:!g||l,children:l?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-sm"}),i.export.exporting]}):r.jsxs(r.Fragment,{children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),i.export.button]})})}function ge(){const e=y(n=>n.voucherConfig.language),t=y(n=>n.setLanguage),a=n=>{t(n)};return r.jsxs("div",{className:"join",children:[r.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:"DE"}),r.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:"EN"})]})}function We(){const e=y(a=>a.voucherConfig.language),t=A(e);return r.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[r.jsx("div",{className:"navbar-start",children:r.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),r.jsx("div",{className:"navbar-center hidden sm:flex",children:r.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),r.jsx("div",{className:"navbar-end",children:r.jsx(ge,{})})]})}const U="/",qe={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${U}templates/front_hdpi_de.jpg`,back:`${U}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:C.front.portrait,name:C.front.namePlate},back:{name:C.back.namePlate,contactInfo:C.back.contactInfo,description:C.back.description}},languages:["de"]},Ye={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${U}templates/front_ldpi_en.png`,back:`${U}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:T.front.portrait,name:T.front.namePlate},back:{name:T.back.namePlate,contactInfo:T.back.contactInfo,description:T.back.description}},languages:["en"]},ee=[qe,Ye],fe={async listTemplates(e){let t=[...ee];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=ee.find(a=>a.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Ve(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let M=fe;function Ge(e){M=e}function Ze(){return M}async function Xe(e){return M.listTemplates(e)}async function Je(e){return M.getTemplate(e)}exports.ApiKeyModal=se;exports.BillPreview=He;exports.ExportButton=Oe;exports.Header=We;exports.LAYOUT_HDPI=C;exports.LAYOUT_LDPI=T;exports.LanguageToggle=ge;exports.PersonalInfoForm=Le;exports.PortraitUpload=Me;exports.TEMPLATES=le;exports.VoucherConfig=ze;exports.downloadBlob=pe;exports.drawContactInfo=he;exports.drawMultilineText=de;exports.drawOvalPortrait=ce;exports.drawTemplate=V;exports.drawText=G;exports.enhancePortrait=Ue;exports.enhancePortraitFallback=ie;exports.exportBillAsPDF=me;exports.formatDescription=W;exports.generateBillPDF=ue;exports.getApiKey=F;exports.getDefaultTemplateId=Ve;exports.getLayout=q;exports.getTemplate=Y;exports.getTemplateById=Je;exports.getTemplateProvider=Ze;exports.hasApiKey=re;exports.listTemplates=Xe;exports.loadImage=$;exports.removeBackground=oe;exports.renderBackSide=X;exports.renderFrontSide=Z;exports.setApiKey=ae;exports.setTemplateProvider=Ge;exports.staticTemplateProvider=fe;exports.t=A;exports.useBillCanvasRefs=Ke;exports.useBillStore=y;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),Ne=require("zustand"),Se=require("zustand/middleware"),f=require("react"),Ee=require("jspdf");var R=typeof document<"u"?document.currentScript:null;const J={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1},currentSide:"front",isEnhancing:!1,isExporting:!1},x=Ne.create()(Se.persist(e=>({...J,setPersonalInfo:t=>e(a=>({personalInfo:{...a.personalInfo,...t}})),setVoucherConfig:t=>e(a=>({voucherConfig:{...a.voucherConfig,...t}})),setPortrait:(t,a=null)=>e({portrait:{original:t,enhanced:a,useEnhanced:!1,zoom:1}}),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}})),setCurrentSide:t=>e({currentSide:t}),flipSide:()=>e(t=>({currentSide:t.currentSide==="front"?"back":"front"})),setIsEnhancing:t=>e({isEnhancing:t}),setIsExporting:t=>e({isExporting:t}),setLanguage:t=>e(a=>({voucherConfig:{...a.voucherConfig,language:t}})),setHours:t=>e(a=>({voucherConfig:{...a.voucherConfig,hours:t}})),reset:()=>e(J)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig})})),Te={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?"}},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"}},Ce={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?"}},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"}},Ae={de:Te,en:Ce};function A(e){return Ae[e]}function W(e,t,a){if(a&&a.trim())return a;const n=A(e),o=t===1?n.form.voucher.hourLabel:n.form.voucher.hoursLabel;return n.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",o)}function Le(){const e=x(o=>o.voucherConfig.language),t=x(o=>o.personalInfo),a=x(o=>o.setPersonalInfo),n=A(e);return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.name})}),r.jsx("input",{type:"text",placeholder:n.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:o=>a({name:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.email})}),r.jsx("input",{type:"email",placeholder:n.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:o=>a({email:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:n.form.personalInfo.phone})}),r.jsx("input",{type:"tel",placeholder:n.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:o=>a({phone:o.target.value})})]})]})}const K={},De="https://api.stability.ai/v1/generation",_e="https://api.stability.ai/v2beta/stable-image/edit/remove-background",te="stability_api_key",Re={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"},Q=[{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 Be(e,t){const a=e/t;let n=Q[0],o=1/0;for(const l of Q){const d=l.width/l.height,i=Math.abs(a-d);i<o&&(o=i,n=l)}return n}function $e(e){return new Promise((t,a)=>{const n=new Image;n.onload=()=>{const o=Be(n.width,n.height),l=document.createElement("canvas");l.width=o.width,l.height=o.height;const d=l.getContext("2d");if(!d){a(new Error("Failed to get canvas context"));return}const i=n.width/n.height,s=o.width/o.height;let c=0,p=0,m=n.width,g=n.height;i>s?(m=n.height*s,c=(n.width-m)/2):(g=n.width/s,p=(n.height-g)/2),d.drawImage(n,c,p,m,g,0,0,o.width,o.height),t(l.toDataURL("image/png"))},n.onerror=()=>a(new Error("Failed to load image")),n.src=e})}function ne(e){var d;const t=e.split(","),a=((d=t[0].match(/:(.*?);/))==null?void 0:d[1])||"image/png",n=atob(t[1]),o=n.length,l=new Uint8Array(o);for(let i=0;i<o;i++)l[i]=n.charCodeAt(i);return new Blob([l],{type:a})}function F(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:R&&R.tagName.toUpperCase()==="SCRIPT"&&R.src||new URL("index.cjs",document.baseURI).href}<"u"&&(K==null?void 0:K.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(te):null}function ae(e){localStorage.setItem(te,e)}function re(){return F()!==null}async function Ue(e){const t=F();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:a,style:n,strength:o=.35}=e,l=await $e(a),d=ne(l),i=new FormData;i.append("init_image",d,"portrait.png"),i.append("init_image_mode","IMAGE_STRENGTH"),i.append("image_strength",String(1-o)),i.append("text_prompts[0][text]",Re[n]),i.append("text_prompts[0][weight]","1"),i.append("cfg_scale","7"),i.append("samples","1"),i.append("steps","30");const c=await fetch(`${De}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:i});if(!c.ok){const m=await c.text();throw console.error("Stability AI error:",m),c.status===401?new Error("Invalid API key"):c.status===402?new Error("Insufficient credits"):c.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${c.status}`)}const p=await c.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 oe(e){const t=F();if(!t)throw new Error("No Stability AI API key configured");const a=ne(e),n=new FormData;n.append("image",a,"image.png"),n.append("output_format","png");const o=await fetch(_e,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:n});if(!o.ok){const d=await o.text();throw console.error("Stability AI remove background error:",d),o.status===401?new Error("Invalid API key"):o.status===402?new Error("Insufficient credits"):o.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${o.status}`)}const l=await o.blob();return new Promise((d,i)=>{const s=new FileReader;s.onload=()=>d(s.result),s.onerror=()=>i(new Error("Failed to read result")),s.readAsDataURL(l)})}async function ie(e){return new Promise((t,a)=>{const n=new Image;n.onload=()=>{const o=document.createElement("canvas"),l=o.getContext("2d");if(!l){a(new Error("Failed to get canvas context"));return}o.width=n.width,o.height=n.height,l.drawImage(n,0,0);const d=l.getImageData(0,0,o.width,o.height),i=d.data;for(let s=0;s<i.length;s+=4){const c=i[s],p=i[s+1],m=i[s+2];if(i[s+3]===0)continue;let v=(((.299*c+.587*p+.114*m)/255-.5)*1.15+.5)*255;v=Math.max(0,Math.min(255,v));const k=Math.min(255,v*.95+30),w=Math.min(255,v*.85+20),N=Math.min(255,v*.65+10);i[s]=k,i[s+1]=w,i[s+2]=N}l.putImageData(d,0,0),t(o.toDataURL("image/png"))},n.onerror=()=>a(new Error("Failed to load image")),n.src=e})}function Fe(){const[e,t]=f.useState(!1),[a,n]=f.useState(!1),[o,l]=f.useState(null),[d,i]=f.useState(re()),s=f.useCallback(()=>l(null),[]),c=f.useCallback(g=>{ae(g),i(!0),l(null)},[]),p=f.useCallback(async(g,b="vintage")=>{t(!0),l(null);try{return await ie(g)}catch(h){const v=h instanceof Error?h.message:"Enhancement failed";throw l(v),h}finally{t(!1)}},[]),m=f.useCallback(async g=>{n(!0),l(null);try{return await oe(g)}catch(b){const h=b instanceof Error?b.message:"Background removal failed";throw l(h),b}finally{n(!1)}},[]);return{enhance:p,removeBg:m,isEnhancing:e,isRemovingBg:a,error:o,hasKey:d,setApiKey:c,clearError:s}}function se({isOpen:e,onClose:t,onSubmit:a}){const n=x(c=>c.voucherConfig.language),[o,l]=f.useState("");if(!e)return null;const d=c=>{c.preventDefault(),o.trim()&&(a(o.trim()),l(""),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 r.jsxs("dialog",{className:"modal modal-open",children:[r.jsxs("div",{className:"modal-box",children:[r.jsx("h3",{className:"font-bold text-lg",children:s.title}),r.jsx("p",{className:"py-4 text-sm opacity-80",children:s.description}),r.jsxs("form",{onSubmit:d,children:[r.jsxs("div",{className:"form-control",children:[r.jsx("input",{type:"password",placeholder:s.placeholder,className:"input input-bordered w-full",value:o,onChange:c=>l(c.target.value),autoFocus:!0}),r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text-alt",children:s.hint})})]}),r.jsxs("div",{className:"modal-action",children:[r.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:s.cancel}),r.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!o.trim(),children:s.submit})]})]})]}),r.jsx("form",{method:"dialog",className:"modal-backdrop",children:r.jsx("button",{onClick:t,children:"close"})})]})}function Me(){const e=x(u=>u.voucherConfig.language),t=x(u=>u.portrait),a=x(u=>u.setPortrait),n=x(u=>u.setPortraitZoom),{enhance:o,removeBg:l,isEnhancing:d,isRemovingBg:i,error:s,hasKey:c,setApiKey:p}=Fe(),m=A(e),g=f.useRef(null),[b,h]=f.useState(!1),[v,k]=f.useState(!1),[w,N]=f.useState(null),[y,j]=f.useState(!1),[E,L]=f.useState(!1),B=f.useCallback(async u=>{if(!u.type.startsWith("image/"))return;const P=new FileReader;P.onload=async D=>{var _;const S=(_=D.target)==null?void 0:_.result;N(S),a(S),j(!1),L(!1)},P.readAsDataURL(u)},[a]),z=f.useCallback(u=>{u.preventDefault(),h(!1);const P=u.dataTransfer.files[0];P&&B(P)},[B]),be=f.useCallback(u=>{u.preventDefault(),h(!0)},[]),xe=f.useCallback(u=>{u.preventDefault(),h(!1)},[]),ye=()=>{var u;(u=g.current)==null||u.click()},we=u=>{var D;const P=(D=u.target.files)==null?void 0:D[0];P&&B(P)},H=f.useCallback(async(u,P,D)=>{let S=u;if(P&&c)try{S=await l(S)}catch(_){console.error("Background removal failed:",_)}if(D)try{S=await o(S,"vintage")}catch(_){console.error("Enhancement failed:",_)}a(S)},[c,l,o,a]),ve=async()=>{if(!w)return;if(!y&&!c){k(!0);return}const u=!y;j(u),await H(w,u,E)},Ie=async()=>{if(!w)return;const u=!E;L(u),await H(w,y,u)},ke=async u=>{p(u),w&&(j(!0),await H(w,!0,E))},je=()=>{a(null),N(null),j(!1),L(!1)},Pe=t.original;return r.jsxs("div",{className:"space-y-4",children:[t.original?r.jsxs("div",{className:"space-y-4",children:[r.jsx("div",{className:"flex justify-center",children:r.jsxs("div",{className:"relative",children:[r.jsx("div",{className:"w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg",children:r.jsx("img",{src:Pe||"",alt:"Portrait",className:"w-full h-full object-cover",style:{transform:`scale(${t.zoom})`}})}),r.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:je,children:r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),r.jsxs("div",{className:"form-control",children:[r.jsxs("label",{className:"label",children:[r.jsx("span",{className:"label-text",children:m.form.portrait.zoom}),r.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),r.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:u=>n(parseFloat(u.target.value)),className:"range range-primary range-sm"})]}),r.jsxs("div",{className:"flex flex-col gap-3",children:[r.jsx("div",{className:"form-control",children:r.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[r.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${i?"opacity-50":""}`,checked:y,onChange:ve,disabled:i}),r.jsxs("span",{className:"label-text flex items-center gap-2",children:[i?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!c&&r.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),r.jsx("div",{className:"form-control",children:r.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[r.jsx("input",{type:"checkbox",className:`toggle toggle-secondary ${d?"opacity-50":""}`,checked:E,onChange:Ie,disabled:d}),r.jsx("span",{className:"label-text flex items-center gap-2",children:d?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Gravur-Effekt wird angewendet...":"Applying engraving effect..."]}):e==="de"?"Gravur-Effekt":"Engraving effect"})]})}),s&&r.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[r.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:r.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"})}),r.jsx("span",{children:s})]})]})]}):r.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${i?"border-primary bg-primary/10 pointer-events-none":b?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:z,onDragOver:be,onDragLeave:xe,onClick:ye,children:[r.jsx("input",{ref:g,type:"file",accept:"image/*",className:"hidden",onChange:we}),i?r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),r.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.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:r.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"})}),r.jsx("p",{className:"font-medium",children:m.form.portrait.upload}),r.jsx("p",{className:"text-sm text-base-content/60",children:m.form.portrait.dragDrop})]})]}),r.jsx(se,{isOpen:v,onClose:()=>k(!1),onSubmit:ke})]})}function ze(){return null}const I=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:R&&R.tagName.toUpperCase()==="SCRIPT"&&R.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",le={en:{1:{front:`${I}templates/front_ldpi_en.png`,back:`${I}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${I}templates/front_ldpi_en.png`,back:`${I}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${I}templates/front_ldpi_en.png`,back:`${I}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${I}templates/front_hdpi_de.webp`,back:`${I}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${I}templates/front_hdpi_de.webp`,back:`${I}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${I}templates/front_hdpi_de.webp`,back:`${I}templates/back_hdpi_de.webp`,width:6144,height:3200}}},T={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},C={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function q(e){return e==="de"?C:T}function Y(e,t){return le[e][t]}const O=new Map;async function $(e){return O.has(e)?O.get(e):new Promise((t,a)=>{const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{O.set(e,n),t(n)},n.onerror=a,n.src=e})}function V(e,t,a,n){e.drawImage(t,0,0,a,n)}function ce(e,t,a,n,o,l,d=1){e.save(),e.beginPath(),e.ellipse(a,n,o,l,0,0,Math.PI*2),e.closePath(),e.clip();const i=t.width/t.height,s=o/l,c=o*2,p=l*2;let m,g;i>s?(g=p,m=p*i):(m=c,g=c/i),m*=d,g*=d;const b=a-m/2,h=n-g/2;e.drawImage(t,b,h,m,g),e.restore()}function G(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 de(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 o=a.maxWidth||400,l=a.lineHeight||a.fontSize*1.4,d=t.split(" "),i=[];let s="";for(const m of d){const g=s?`${s} ${m}`:m;e.measureText(g).width>o&&s?(i.push(s),s=m):s=g}s&&i.push(s);const c=i.length*l;let p=a.y-c/2;for(const m of i)e.fillText(m,a.x,p),p+=l;e.restore()}function he(e,t,a,n,o,l="#2a3a2a"){e.save(),e.font=`${o.fontSize}px "Times New Roman", serif`,e.textAlign=o.align||"center",e.textBaseline="middle",e.fillStyle=l;const d=o.lineHeight||o.fontSize*1.8,i=[t,a,n].filter(Boolean),s=(i.length-1)*d;let c=o.y-s/2;for(const p of i)p&&(e.fillText(p,o.x,c),c+=d);e.restore()}async function Z(e,t,a,n,o,l,d,i=1){const s=e.getContext("2d");if(!s)return;e.width=l,e.height=d,s.clearRect(0,0,l,d);const c=await $(t);if(V(s,c,l,d),a)try{const p=await $(a);ce(s,p,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,i)}catch(p){console.error("Failed to load portrait:",p)}n&&G(s,n,o.namePlate)}async function X(e,t,a,n,o,l,d,i,s){const c=e.getContext("2d");if(!c)return;e.width=i,e.height=s,c.clearRect(0,0,i,s);const p=await $(t);V(c,p,i,s),d.contactInfo&&(a||n||o)&&he(c,a,n,o,d.contactInfo),d.description&&l&&de(c,l,d.description),a&&G(c,a,d.namePlate)}function He(){const e=x(y=>y.voucherConfig.language),t=x(y=>y.voucherConfig.hours),a=x(y=>y.voucherConfig.description),n=x(y=>y.personalInfo),o=x(y=>y.portrait),l=x(y=>y.currentSide),d=x(y=>y.flipSide),i=A(e),s=f.useRef(null),c=f.useRef(null),p=f.useRef(null),[m,g]=f.useState(!1),b=Y(e,t),h=q(e),v=o.useEnhanced&&o.enhanced?o.enhanced:o.original,k=W(e,t,a);f.useEffect(()=>{s.current&&Z(s.current,b.front,v,n.name,h.front,b.width,b.height,o.zoom)},[b,v,n.name,h,o.zoom]),f.useEffect(()=>{c.current&&X(c.current,b.back,n.name,n.email,n.phone,k,h.back,b.width,b.height)},[b,n,k,h]);const w=()=>{g(!0),setTimeout(()=>{d(),g(!1)},150)},N=b.width/b.height;return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[r.jsx("button",{className:`tab ${l==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="front"&&w(),children:i.preview.front}),r.jsx("button",{className:`tab ${l==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="back"&&w(),children:i.preview.back})]}),r.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:w,children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),i.preview.flip]})]}),r.jsxs("div",{ref:p,className:"relative w-full overflow-hidden shadow-lg",style:{aspectRatio:N},children:[r.jsx("canvas",{ref:s,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="front"?m?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),r.jsx("canvas",{ref:c,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="back"?m?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Ke(){const e=f.useRef(null),t=f.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}async function ue(e){const{frontTemplateSrc:t,backTemplateSrc:a,templateWidth:n,templateHeight:o,layout:l,portrait:d,portraitZoom:i=1,name:s,email:c,phone:p,description:m}=e,g=document.createElement("canvas"),b=document.createElement("canvas");await Promise.all([Z(g,t,d,s,l.front,n,o,i),X(b,a,s,c,p,m,l.back,n,o)]);const h=new Ee({orientation:"landscape",unit:"mm",format:"a4"}),v=297,k=210,w=10,N=n/o;let y=v-w*2,j=y/N;j>k-w*2&&(j=k-w*2,y=j*N);const E=(v-y)/2,L=(k-j)/2,B=g.toDataURL("image/jpeg",.95);h.addImage(B,"JPEG",E,L,y,j),h.addPage();const z=b.toDataURL("image/jpeg",.95);return h.addImage(z,"JPEG",E,L,y,j),h.output("blob")}function pe(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 me(e){const t=await ue(e);pe(t,e.filename)}function Oe(){const e=x(h=>h.voucherConfig.language),t=x(h=>h.voucherConfig.hours),a=x(h=>h.voucherConfig.description),n=x(h=>h.personalInfo),o=x(h=>h.portrait),l=x(h=>h.isExporting),d=x(h=>h.setIsExporting),i=A(e),s=Y(e,t),c=q(e),p=o.useEnhanced&&o.enhanced?o.enhanced:o.original,m=W(e,t,a),g=n.name.trim().length>0&&n.email.trim().length>0&&n.phone.trim().length>0&&o.original!==null,b=async()=>{if(!(!g||l)){d(!0);try{const h=`zeitgutschein-${t}h-${n.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await me({frontTemplateSrc:s.front,backTemplateSrc:s.back,templateWidth:s.width,templateHeight:s.height,layout:c,portrait:p,portraitZoom:o.zoom,name:n.name,email:n.email,phone:n.phone,description:m,filename:h})}catch(h){console.error("PDF export failed:",h)}finally{d(!1)}}};return r.jsx("button",{className:`btn btn-primary flex-1 ${l?"loading":""}`,onClick:b,disabled:!g||l,children:l?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-sm"}),i.export.exporting]}):r.jsxs(r.Fragment,{children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),i.export.button]})})}function ge(){const e=x(n=>n.voucherConfig.language),t=x(n=>n.setLanguage),a=n=>{t(n)};return r.jsxs("div",{className:"join",children:[r.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:"DE"}),r.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:"EN"})]})}function We(){const e=x(a=>a.voucherConfig.language),t=A(e);return r.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[r.jsx("div",{className:"navbar-start",children:r.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),r.jsx("div",{className:"navbar-center hidden sm:flex",children:r.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),r.jsx("div",{className:"navbar-end",children:r.jsx(ge,{})})]})}const U="/",qe={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${U}templates/front_hdpi_de.jpg`,back:`${U}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:C.front.portrait,name:C.front.namePlate},back:{name:C.back.namePlate,contactInfo:C.back.contactInfo,description:C.back.description}},languages:["de"]},Ye={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${U}templates/front_ldpi_en.png`,back:`${U}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:T.front.portrait,name:T.front.namePlate},back:{name:T.back.namePlate,contactInfo:T.back.contactInfo,description:T.back.description}},languages:["en"]},ee=[qe,Ye],fe={async listTemplates(e){let t=[...ee];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=ee.find(a=>a.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Ve(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let M=fe;function Ge(e){M=e}function Ze(){return M}async function Xe(e){return M.listTemplates(e)}async function Je(e){return M.getTemplate(e)}exports.ApiKeyModal=se;exports.BillPreview=He;exports.ExportButton=Oe;exports.Header=We;exports.LAYOUT_HDPI=C;exports.LAYOUT_LDPI=T;exports.LanguageToggle=ge;exports.PersonalInfoForm=Le;exports.PortraitUpload=Me;exports.TEMPLATES=le;exports.VoucherConfig=ze;exports.downloadBlob=pe;exports.drawContactInfo=he;exports.drawMultilineText=de;exports.drawOvalPortrait=ce;exports.drawTemplate=V;exports.drawText=G;exports.enhancePortrait=Ue;exports.enhancePortraitFallback=ie;exports.exportBillAsPDF=me;exports.formatDescription=W;exports.generateBillPDF=ue;exports.getApiKey=F;exports.getDefaultTemplateId=Ve;exports.getLayout=q;exports.getTemplate=Y;exports.getTemplateById=Je;exports.getTemplateProvider=Ze;exports.hasApiKey=re;exports.listTemplates=Xe;exports.loadImage=$;exports.removeBackground=oe;exports.renderBackSide=X;exports.renderFrontSide=Z;exports.setApiKey=ae;exports.setTemplateProvider=Ge;exports.staticTemplateProvider=fe;exports.t=A;exports.useBillCanvasRefs=Ke;exports.useBillStore=x;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsxs as m, jsx as l, Fragment as M } from "react/jsx-runtime";
2
2
  import { create as fe } from "zustand";
3
3
  import { persist as be } from "zustand/middleware";
4
- import { useState as N, useCallback as C, useRef as $, useEffect as G } from "react";
4
+ import { useState as E, useCallback as C, useRef as $, useEffect as G } from "react";
5
5
  import ye from "jspdf";
6
6
  const V = {
7
7
  personalInfo: {
@@ -23,7 +23,7 @@ const V = {
23
23
  currentSide: "front",
24
24
  isEnhancing: !1,
25
25
  isExporting: !1
26
- }, w = fe()(
26
+ }, y = fe()(
27
27
  be(
28
28
  (e) => ({
29
29
  ...V,
@@ -187,7 +187,7 @@ function J(e, t, a) {
187
187
  return n.bill.descriptionText.replace("{hours}", t.toString()).replace("{hourLabel}", r);
188
188
  }
189
189
  function Ve() {
190
- const e = w((r) => r.voucherConfig.language), t = w((r) => r.personalInfo), a = w((r) => r.setPersonalInfo), n = z(e);
190
+ const e = y((r) => r.voucherConfig.language), t = y((r) => r.personalInfo), a = y((r) => r.setPersonalInfo), n = z(e);
191
191
  return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
192
192
  /* @__PURE__ */ m("div", { className: "form-control", children: [
193
193
  /* @__PURE__ */ l("label", { className: "label", children: /* @__PURE__ */ l("span", { className: "label-text font-medium", children: n.form.personalInfo.name }) }),
@@ -350,18 +350,17 @@ async function Te(e) {
350
350
  for (let i = 0; i < o.length; i += 4) {
351
351
  const c = o[i], u = o[i + 1], g = o[i + 2];
352
352
  if (o[i + 3] === 0) continue;
353
- const b = 0.299 * c + 0.587 * u + 0.114 * g, h = 1.4;
354
- let x = 259 * (h * 255 + 255) / (255 * (259 - h * 255)) * (b - 128) + 128;
353
+ let x = (((0.299 * c + 0.587 * u + 0.114 * g) / 255 - 0.5) * 1.15 + 0.5) * 255;
355
354
  x = Math.max(0, Math.min(255, x));
356
- const v = Math.min(255, x * 1.1 + 20), S = Math.min(255, x * 0.95 + 10), y = Math.min(255, x * 0.8);
357
- o[i] = v, o[i + 1] = S, o[i + 2] = y;
355
+ const k = Math.min(255, x * 0.95 + 30), v = Math.min(255, x * 0.85 + 20), S = Math.min(255, x * 0.65 + 10);
356
+ o[i] = k, o[i + 1] = v, o[i + 2] = S;
358
357
  }
359
358
  s.putImageData(d, 0, 0), t(r.toDataURL("image/png"));
360
359
  }, n.onerror = () => a(new Error("Failed to load image")), n.src = e;
361
360
  });
362
361
  }
363
362
  function Le() {
364
- const [e, t] = N(!1), [a, n] = N(!1), [r, s] = N(null), [d, o] = N(Ce()), i = C(() => s(null), []), c = C((f) => {
363
+ const [e, t] = E(!1), [a, n] = E(!1), [r, s] = E(null), [d, o] = E(Ce()), i = C(() => s(null), []), c = C((f) => {
365
364
  Se(f), o(!0), s(null);
366
365
  }, []), u = C(
367
366
  async (f, b = "vintage") => {
@@ -369,8 +368,8 @@ function Le() {
369
368
  try {
370
369
  return await Te(f);
371
370
  } catch (h) {
372
- const E = h instanceof Error ? h.message : "Enhancement failed";
373
- throw s(E), h;
371
+ const x = h instanceof Error ? h.message : "Enhancement failed";
372
+ throw s(x), h;
374
373
  } finally {
375
374
  t(!1);
376
375
  }
@@ -402,7 +401,7 @@ function Le() {
402
401
  };
403
402
  }
404
403
  function De({ isOpen: e, onClose: t, onSubmit: a }) {
405
- const n = w((c) => c.voucherConfig.language), [r, s] = N("");
404
+ const n = y((c) => c.voucherConfig.language), [r, s] = E("");
406
405
  if (!e) return null;
407
406
  const d = (c) => {
408
407
  c.preventDefault(), r.trim() && (a(r.trim()), s(""), t());
@@ -453,7 +452,7 @@ function De({ isOpen: e, onClose: t, onSubmit: a }) {
453
452
  ] });
454
453
  }
455
454
  function Xe() {
456
- const e = w((p) => p.voucherConfig.language), t = w((p) => p.portrait), a = w((p) => p.setPortrait), n = w((p) => p.setPortraitZoom), { enhance: r, removeBg: s, isEnhancing: d, isRemovingBg: o, error: i, hasKey: c, setApiKey: u } = Le(), g = z(e), f = $(null), [b, h] = N(!1), [E, x] = N(!1), [v, S] = N(null), [y, k] = N(!1), [T, L] = N(!1), H = C(
455
+ const e = y((p) => p.voucherConfig.language), t = y((p) => p.portrait), a = y((p) => p.setPortrait), n = y((p) => p.setPortraitZoom), { enhance: r, removeBg: s, isEnhancing: d, isRemovingBg: o, error: i, hasKey: c, setApiKey: u } = Le(), g = z(e), f = $(null), [b, h] = E(!1), [x, k] = E(!1), [v, S] = E(null), [w, N] = E(!1), [T, L] = E(!1), H = C(
457
456
  async (p) => {
458
457
  if (!p.type.startsWith("image/"))
459
458
  return;
@@ -461,7 +460,7 @@ function Xe() {
461
460
  P.onload = async (D) => {
462
461
  var _;
463
462
  const A = (_ = D.target) == null ? void 0 : _.result;
464
- S(A), a(A), k(!1), L(!1);
463
+ S(A), a(A), N(!1), L(!1);
465
464
  }, P.readAsDataURL(p);
466
465
  },
467
466
  [a]
@@ -500,20 +499,20 @@ function Xe() {
500
499
  a(A);
501
500
  }, [c, s, r, a]), he = async () => {
502
501
  if (!v) return;
503
- if (!y && !c) {
504
- x(!0);
502
+ if (!w && !c) {
503
+ k(!0);
505
504
  return;
506
505
  }
507
- const p = !y;
508
- k(p), await K(v, p, T);
506
+ const p = !w;
507
+ N(p), await K(v, p, T);
509
508
  }, pe = async () => {
510
509
  if (!v) return;
511
510
  const p = !T;
512
- L(p), await K(v, y, p);
511
+ L(p), await K(v, w, p);
513
512
  }, me = async (p) => {
514
- u(p), v && (k(!0), await K(v, !0, T));
513
+ u(p), v && (N(!0), await K(v, !0, T));
515
514
  }, ue = () => {
516
- a(null), S(null), k(!1), L(!1);
515
+ a(null), S(null), N(!1), L(!1);
517
516
  }, ge = t.original;
518
517
  return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
519
518
  t.original ? /* @__PURE__ */ m("div", { className: "space-y-4", children: [
@@ -582,7 +581,7 @@ function Xe() {
582
581
  {
583
582
  type: "checkbox",
584
583
  className: `toggle toggle-primary ${o ? "opacity-50" : ""}`,
585
- checked: y,
584
+ checked: w,
586
585
  onChange: he,
587
586
  disabled: o
588
587
  }
@@ -667,8 +666,8 @@ function Xe() {
667
666
  /* @__PURE__ */ l(
668
667
  De,
669
668
  {
670
- isOpen: E,
671
- onClose: () => x(!1),
669
+ isOpen: x,
670
+ onClose: () => k(!1),
672
671
  onSubmit: me
673
672
  }
674
673
  )
@@ -893,31 +892,31 @@ async function ie(e, t, a, n, r, s, d, o, i) {
893
892
  ae(c, u, o, i), d.contactInfo && (a || n || r) && $e(c, a, n, r, d.contactInfo), d.description && s && Re(c, s, d.description), a && re(c, a, d.namePlate);
894
893
  }
895
894
  function Qe() {
896
- const e = w((y) => y.voucherConfig.language), t = w((y) => y.voucherConfig.hours), a = w((y) => y.voucherConfig.description), n = w((y) => y.personalInfo), r = w((y) => y.portrait), s = w((y) => y.currentSide), d = w((y) => y.flipSide), o = z(e), i = $(null), c = $(null), u = $(null), [g, f] = N(!1), b = ne(e, t), h = te(e), E = r.useEnhanced && r.enhanced ? r.enhanced : r.original, x = J(e, t, a);
895
+ const e = y((w) => w.voucherConfig.language), t = y((w) => w.voucherConfig.hours), a = y((w) => w.voucherConfig.description), n = y((w) => w.personalInfo), r = y((w) => w.portrait), s = y((w) => w.currentSide), d = y((w) => w.flipSide), o = z(e), i = $(null), c = $(null), u = $(null), [g, f] = E(!1), b = ne(e, t), h = te(e), x = r.useEnhanced && r.enhanced ? r.enhanced : r.original, k = J(e, t, a);
897
896
  G(() => {
898
897
  i.current && oe(
899
898
  i.current,
900
899
  b.front,
901
- E,
900
+ x,
902
901
  n.name,
903
902
  h.front,
904
903
  b.width,
905
904
  b.height,
906
905
  r.zoom
907
906
  );
908
- }, [b, E, n.name, h, r.zoom]), G(() => {
907
+ }, [b, x, n.name, h, r.zoom]), G(() => {
909
908
  c.current && ie(
910
909
  c.current,
911
910
  b.back,
912
911
  n.name,
913
912
  n.email,
914
913
  n.phone,
915
- x,
914
+ k,
916
915
  h.back,
917
916
  b.width,
918
917
  b.height
919
918
  );
920
- }, [b, n, x, h]);
919
+ }, [b, n, k, h]);
921
920
  const v = () => {
922
921
  f(!0), setTimeout(() => {
923
922
  d(), f(!1);
@@ -1018,13 +1017,13 @@ async function ze(e) {
1018
1017
  orientation: "landscape",
1019
1018
  unit: "mm",
1020
1019
  format: "a4"
1021
- }), E = 297, x = 210, v = 10, S = n / r;
1022
- let y = E - v * 2, k = y / S;
1023
- k > x - v * 2 && (k = x - v * 2, y = k * S);
1024
- const T = (E - y) / 2, L = (x - k) / 2, H = f.toDataURL("image/jpeg", 0.95);
1025
- h.addImage(H, "JPEG", T, L, y, k), h.addPage();
1020
+ }), x = 297, k = 210, v = 10, S = n / r;
1021
+ let w = x - v * 2, N = w / S;
1022
+ N > k - v * 2 && (N = k - v * 2, w = N * S);
1023
+ const T = (x - w) / 2, L = (k - N) / 2, H = f.toDataURL("image/jpeg", 0.95);
1024
+ h.addImage(H, "JPEG", T, L, w, N), h.addPage();
1026
1025
  const W = b.toDataURL("image/jpeg", 0.95);
1027
- return h.addImage(W, "JPEG", T, L, y, k), h.output("blob");
1026
+ return h.addImage(W, "JPEG", T, L, w, N), h.output("blob");
1028
1027
  }
1029
1028
  function He(e, t) {
1030
1029
  const a = URL.createObjectURL(e), n = document.createElement("a");
@@ -1035,7 +1034,7 @@ async function Me(e) {
1035
1034
  He(t, e.filename);
1036
1035
  }
1037
1036
  function tt() {
1038
- const e = w((h) => h.voucherConfig.language), t = w((h) => h.voucherConfig.hours), a = w((h) => h.voucherConfig.description), n = w((h) => h.personalInfo), r = w((h) => h.portrait), s = w((h) => h.isExporting), d = w((h) => h.setIsExporting), o = z(e), i = ne(e, t), c = te(e), u = r.useEnhanced && r.enhanced ? r.enhanced : r.original, g = J(e, t, a), f = n.name.trim().length > 0 && n.email.trim().length > 0 && n.phone.trim().length > 0 && r.original !== null;
1037
+ const e = y((h) => h.voucherConfig.language), t = y((h) => h.voucherConfig.hours), a = y((h) => h.voucherConfig.description), n = y((h) => h.personalInfo), r = y((h) => h.portrait), s = y((h) => h.isExporting), d = y((h) => h.setIsExporting), o = z(e), i = ne(e, t), c = te(e), u = r.useEnhanced && r.enhanced ? r.enhanced : r.original, g = J(e, t, a), f = n.name.trim().length > 0 && n.email.trim().length > 0 && n.phone.trim().length > 0 && r.original !== null;
1039
1038
  return /* @__PURE__ */ l(
1040
1039
  "button",
1041
1040
  {
@@ -1096,7 +1095,7 @@ function tt() {
1096
1095
  );
1097
1096
  }
1098
1097
  function Ue() {
1099
- const e = w((n) => n.voucherConfig.language), t = w((n) => n.setLanguage), a = (n) => {
1098
+ const e = y((n) => n.voucherConfig.language), t = y((n) => n.setLanguage), a = (n) => {
1100
1099
  t(n);
1101
1100
  };
1102
1101
  return /* @__PURE__ */ m("div", { className: "join", children: [
@@ -1119,7 +1118,7 @@ function Ue() {
1119
1118
  ] });
1120
1119
  }
1121
1120
  function nt() {
1122
- const e = w((a) => a.voucherConfig.language), t = z(e);
1121
+ const e = y((a) => a.voucherConfig.language), t = z(e);
1123
1122
  return /* @__PURE__ */ m("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
1124
1123
  /* @__PURE__ */ l("div", { className: "navbar-start", children: /* @__PURE__ */ l("a", { className: "btn btn-ghost text-xl font-currency font-bold", children: t.header.title }) }),
1125
1124
  /* @__PURE__ */ l("div", { className: "navbar-center hidden sm:flex", children: /* @__PURE__ */ l("span", { className: "text-sm opacity-80", children: t.header.subtitle }) }),
@@ -1325,5 +1324,5 @@ export {
1325
1324
  Ke as staticTemplateProvider,
1326
1325
  z as t,
1327
1326
  et as useBillCanvasRefs,
1328
- w as useBillStore
1327
+ y as useBillStore
1329
1328
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antontranelis/money-printer",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Create personalized time vouchers that look like real currency. React components for voucher generation with PDF export.",
5
5
  "type": "module",
6
6
  "license": "MIT",