@antontranelis/money-printer 1.1.0 → 1.7.0

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,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),g=require("react"),Dt=require("zustand"),Fe=require("zustand/middleware"),Bt=require("jspdf");var ge=typeof document<"u"?document.currentScript:null;const At=1024,Je=1200,de=new Map;let X=null,Qe=null;function Ve(t,e){return X||(X=document.createElement("canvas"),Qe=X.getContext("2d",{willReadFrequently:!0})),(X.width!==t||X.height!==e)&&(X.width=t,X.height=e),Qe}function he(t){const e=de.get(t);return e?Promise.resolve(e):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(de.size>10){const s=de.keys().next().value;s&&de.delete(s)}de.set(t,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=t})}function it(){de.clear()}async function ct(t,e=At){const n=await he(t),a=Math.max(n.width,n.height);if(a<=e)return t;const r=e/a,s=Math.round(n.width*r),o=Math.round(n.height*r),i=document.createElement("canvas"),l=i.getContext("2d");if(!l)throw new Error("Failed to get canvas context");return i.width=s,i.height=o,l.drawImage(n,0,0,s,o),i.toDataURL("image/jpeg",.9)}async function Mt(t){const e=await he(t),n=Math.max(e.width,e.height);if(n<=Je){const l=document.createElement("canvas"),u=l.getContext("2d");if(!u)throw new Error("Failed to get canvas context");return l.width=e.width,l.height=e.height,u.drawImage(e,0,0),l.toDataURL("image/png")}const a=Je/n,r=Math.round(e.width*a),s=Math.round(e.height*a),o=document.createElement("canvas"),i=o.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return o.width=r,o.height=s,i.drawImage(e,0,0,r,s),o.toDataURL("image/png")}async function Te(t,e,n,a=0){const[r,s]=await Promise.all([he(t),he(e)]),o=Ve(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(s,0,0,r.width,r.height),o.restore()}return o.drawImage(r,0,0),X.toDataURL("image/png")}async function lt(t,e=.5,n=40){const a=await he(t),r=Ve(a.width,a.height);r.clearRect(0,0,a.width,a.height),r.drawImage(a,0,0);const s=r.getImageData(0,0,a.width,a.height),o=s.data,i=new Uint32Array(o.buffer),l=1+e*.8,u=1-e,h=n%360/360;for(let p=0;p<i.length;p++){const b=i[p],w=b&255,v=b>>8&255,T=b>>16&255,f=b>>24&255;if(f===0)continue;let m=(((77*w+150*v+29*T>>8)/255-.5)*l+.5)*255;m<0?m=0:m>255&&(m=255);const I=m/255,E=.12,[R,S,P]=ut(h,E,I),B=w*u+R*e|0,H=v*u+S*e|0,re=T*u+P*e|0;i[p]=f<<24|re<<16|H<<8|B}return r.putImageData(s,0,0),X.toDataURL("image/png")}function Ht(t,e,n){t/=255,e/=255,n/=255;const a=Math.max(t,e,n),r=Math.min(t,e,n),s=(a+r)/2;let o=0,i=0;if(a!==r){const l=a-r;switch(i=s>.5?l/(2-a-r):l/(a+r),a){case t:o=((e-n)/l+(e<n?6:0))/6;break;case e:o=((n-t)/l+2)/6;break;case n:o=((t-e)/l+4)/6;break}}return[o,i,s]}function ut(t,e,n){if(e===0){const o=Math.round(n*255);return[o,o,o]}const a=(o,i,l)=>(l<0&&(l+=1),l>1&&(l-=1),l<1/6?o+(i-o)*6*l:l<1/2?i:l<2/3?o+(i-o)*(2/3-l)*6:o),r=n<.5?n*(1+e):n+e-n*e,s=2*n-r;return[Math.round(a(s,r,t+1/3)*255),Math.round(a(s,r,t)*255),Math.round(a(s,r,t-1/3)*255)]}const Ut=29,Yt=5;async function dt(t,e){if(Math.abs(e-Ut)<=Yt)return t;const n=await he(t),a=Ve(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),s=r.data,o=new Uint32Array(s.buffer),i=e%360/360,l=20/360,u=45/360,h=o.length;for(let p=0;p<h;p++){const b=o[p],w=b&255,v=b>>8&255,T=b>>16&255,f=b>>24&255;if(f===0)continue;const[j,m,I]=Ht(w,v,T);if(m<.08||j<l||j>u)continue;const E=i,R=Math.min(m,.05),[S,P,B]=ut(E,R,I);o[p]=f<<24|B<<16|P<<8|S}return a.putImageData(r,0,0),X.toDataURL("image/png")}async function gt(t){return new Promise((e,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>e(a),a.onerror=n,a.src=t})}const Ee=new Map,je=new Map;async function ae(t){if(Ee.has(t))return Ee.get(t);const e=await gt(t);return Ee.set(t,e),e}function $t(t){const e=document.createElement("canvas");e.width=t.width,e.height=t.height;const n=e.getContext("2d");if(!n)throw new Error("Failed to get canvas context");return n.drawImage(t,0,0),e.toDataURL("image/jpeg",.95)}async function Ot(t,e){if(e===0)return ae(t);je.has(t)||je.set(t,new Map);const n=je.get(t);if(n.has(e))return ae(n.get(e));const a=await ae(t),r=$t(a),s=await dt(r,e);return n.set(e,s),gt(s)}function ht(t,e,n,a){const r=t.x*a,s=t.y*a;switch(t.anchor||"topLeft"){case"topLeft":return{x:r,y:s};case"topCenter":return{x:r-e/2,y:s};case"topRight":return{x:r-e,y:s};case"centerLeft":return{x:r,y:s-n/2};case"center":return{x:r-e/2,y:s-n/2};case"centerRight":return{x:r-e,y:s-n/2};case"bottomLeft":return{x:r,y:s-n};case"bottomCenter":return{x:r-e/2,y:s-n};case"bottomRight":return{x:r-e,y:s-n};default:return{x:r,y:s}}}function Ue(t,e){return t?typeof t=="string"?t:t[e]||t.en||t.de||Object.values(t)[0]||"":""}const ue={de:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"},en:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}};function Xt(t,e,n){return t.replace(/\{\{(\w+)\}\}/g,(a,r)=>{if(r==="hours_banner_de"){const o=Number(e.hours)||1;return ue.de[o]||ue.de[1]}if(r==="hours_banner_en"){const o=Number(e.hours)||1;return ue.en[o]||ue.en[1]}if(r==="hours_banner"){const o=Number(e.hours)||1,i=n==="de"?"de":"en";return ue[i][o]||ue[i][1]}const s=e[r];return s==null?"":String(s)})}async function _t(t,e,n,a){const{scale:r=1,hue:s=0}=a,o=n.assets.background,i=e.hueShift?await Ot(o,s):await ae(o),l=n.layout.dimensions.width*r,u=n.layout.dimensions.height*r;e.blendMode&&(t.globalCompositeOperation=mt(e.blendMode)),e.opacity!==void 0&&(t.globalAlpha=e.opacity),t.drawImage(i,0,0,l,u),t.globalCompositeOperation="source-over",t.globalAlpha=1}function mt(t){return{normal:"source-over",multiply:"multiply",screen:"screen",overlay:"overlay",darken:"darken",lighten:"lighten","color-dodge":"color-dodge","color-burn":"color-burn"}[t]||"source-over"}async function Wt(t,e,n,a){const{scale:r=1}=a,s=e.source==="frontFrame"?n.assets.frontFrame:n.assets.backFrame;if(!s)return;const o=await ae(s),i=n.layout.dimensions.width*r,l=n.layout.dimensions.height*r;e.blendMode&&(t.globalCompositeOperation=mt(e.blendMode)),e.opacity!==void 0&&(t.globalAlpha=e.opacity),t.drawImage(o,0,0,i,l),t.globalCompositeOperation="source-over",t.globalAlpha=1}async function Vt(t,e,n,a,r){const{scale:s=1}=r,o=n.assets.badges;if(!o||o.type!=="image"||!o.variants)return;const i=a[e.fieldId],l=o.variants.find(h=>h.value===i);if(!l)return;const u=await ae(l.image);for(const h of e.positions){const p=(h.size||l.size||100)*s,{x:b,y:w}=ht({x:h.x,y:h.y,anchor:h.anchor||"center"},p,p,s);t.drawImage(u,b,w,p,p)}}async function zt(t,e,n,a,r){var f,j;const{scale:s=1,language:o="de",portraitImage:i,portraitTransform:l}=r,u=a[e.fieldId],h=n.schema.fields.find(m=>m.id===e.fieldId);if(!h)return;if(h.type==="image"&&e.clip){await Kt(t,e,i||null,l,s);return}if(u==null||u==="")return;const p=String(u),b=e.style||{fontSize:50,fontFamily:((f=n.layout.global)==null?void 0:f.fontFamily)||"sans-serif",color:((j=n.layout.global)==null?void 0:j.textColor)||"#000000"},w=Ue(e.prefix,o),v=Ue(e.suffix,o),T=`${w}${p}${v}`;Ye(t,T,e,b,s)}async function Kt(t,e,n,a,r){if(!n||!e.size)return;const{radiusX:s=100,radiusY:o=100}=e.size,i=s*r,l=o*r,u=e.position.x*r,h=e.position.y*r;if(t.save(),t.beginPath(),e.clip==="ellipse")t.ellipse(u,h,i,l,0,0,Math.PI*2);else if(e.clip==="circle"){const B=Math.min(i,l);t.arc(u,h,B,0,Math.PI*2)}else e.clip==="rectangle"&&t.rect(u-i,h-l,i*2,l*2);t.clip();const p=(a==null?void 0:a.scale)||1,b=(a==null?void 0:a.offsetX)||0,w=(a==null?void 0:a.offsetY)||0,v=i*2,T=l*2,f=n.width/n.height,j=v/T;let m,I;f>j?(I=T,m=I*f):(m=v,I=m/f),m*=p,I*=p;const E=Math.max(0,(m-v)/2),R=Math.max(0,(I-T)/2),S=u-m/2+b*E,P=h-I/2+w*R;t.drawImage(n,S,P,m,I),t.restore()}function Ye(t,e,n,a,r){t.save();const s=a.fontSize*r,o=a.fontWeight||"normal";t.font=`${o} ${s}px ${a.fontFamily}`,t.fillStyle=a.color;const i="align"in n?n.align:"center";t.textAlign=i||"center",t.textBaseline="middle",a.textShadow&&(t.shadowColor="rgba(0,0,0,0.3)",t.shadowBlur=2*r,t.shadowOffsetX=1*r,t.shadowOffsetY=1*r);const l=n.position.x*r,u=n.position.y*r;if("multiline"in n&&n.multiline&&"maxWidth"in n&&n.maxWidth){const h=n.maxWidth*r,p=("lineHeight"in n&&n.lineHeight?n.lineHeight:a.fontSize*1.2)*r,b=qt(t,e,h),w=b.length*p;let v=u-w/2+p/2;for(const T of b)t.fillText(T,l,v),v+=p}else t.fillText(e,l,u);t.restore()}function qt(t,e,n){const a=e.split(" "),r=[];let s="";for(const o of a){const i=s?`${s} ${o}`:o;t.measureText(i).width>n&&s?(r.push(s),s=o):s=i}return s&&r.push(s),r}function Gt(t,e,n,a){const{scale:r=1,language:s="de"}=a;let o=Ue(e.content,s);if(o=Xt(o,n,s),!!o){if(e.arc){Zt(t,o,e,r);return}if(e.rotation){t.save();const i=e.position.x*r,l=e.position.y*r;t.translate(i,l),t.rotate(e.rotation*Math.PI/180),Ye(t,o,{...e,position:{x:0,y:0}},e.style,1),t.restore();return}Ye(t,o,e,e.style,r)}}function Zt(t,e,n,a){if(!n.arc)return;const{centerX:r,centerY:s,radius:o}=n.arc,i=n.style;t.save();const l=i.fontSize*a,u=i.fontWeight||"normal";t.font=`${u} ${l}px ${i.fontFamily}`,t.fillStyle=i.color,t.textAlign="center",t.textBaseline="middle";const h=r*a,p=s*a,b=o*a,v=t.measureText(e).width/b,T=-Math.PI/2-v/2,f=e.split(""),j=f.map(I=>t.measureText(I).width);let m=T;for(let I=0;I<f.length;I++){const E=f[I],R=j[I],S=m+R/2/b,P=h+b*Math.cos(S),B=p+b*Math.sin(S);t.save(),t.translate(P,B),t.rotate(S+Math.PI/2),t.fillText(E,0,0),t.restore(),m+=R/b}t.restore()}async function Ft(t,e,n,a){var p,b,w;const{scale:r=1}=a,s=(p=n.assets.decorations)==null?void 0:p[e.source];if(!s)return;const o=await ae(s),i=(((b=e.size)==null?void 0:b.width)||o.width)*r,l=(((w=e.size)==null?void 0:w.height)||o.height)*r,{x:u,y:h}=ht(e.position,i,l,r);t.save(),e.opacity!==void 0&&(t.globalAlpha=e.opacity),e.rotation?(t.translate(u+i/2,h+l/2),t.rotate(e.rotation*Math.PI/180),t.drawImage(o,-i/2,-l/2,i,l)):t.drawImage(o,u,h,i,l),t.restore()}function et(t,e,n,a,r,s){t.save();const o=document.createElement("canvas");o.width=r,o.height=r;const i=o.getContext("2d");if(!i){t.restore();return}const l=e.width/e.height;let u,h;l>1?(h=r,u=r*l):(u=r,h=r/l);const p=(s==null?void 0:s.scale)||1,b=(s==null?void 0:s.offsetX)||0,w=(s==null?void 0:s.offsetY)||0;u*=p,h*=p;const v=Math.max(0,(u-r)/2),T=Math.max(0,(h-r)/2),f=(r-u)/2+b*v,j=(r-h)/2+w*T;i.filter="grayscale(70%) brightness(1.4) contrast(0.6)",i.drawImage(e,f,j,u,h),i.filter="none",i.globalCompositeOperation="destination-in";const m=i.createRadialGradient(r/2,r/2,0,r/2,r/2,r/2);m.addColorStop(0,"rgba(0,0,0,1)"),m.addColorStop(.5,"rgba(0,0,0,0.8)"),m.addColorStop(.8,"rgba(0,0,0,0.3)"),m.addColorStop(1,"rgba(0,0,0,0)"),i.fillStyle=m,i.fillRect(0,0,r,r),t.globalAlpha=.18,t.drawImage(o,n-r/2,a-r/2),t.globalAlpha=1,t.restore()}async function Jt(t,e,n,a,r){switch(e.type){case"background":await _t(t,e,n,r);break;case"frame":await Wt(t,e,n,r);break;case"badges":await Vt(t,e,n,a,r);break;case"field":await zt(t,e,n,a,r);break;case"text":Gt(t,e,a,r);break;case"decoration":await Ft(t,e,n,r);break}}async function Le(t,e,n,a,r={}){const{scale:s=1,portraitImage:o,portraitTransform:i}=r,{width:l,height:u}=e.layout.dimensions;t.width=l*s,t.height=u*s;const h=t.getContext("2d");if(!h)throw new Error("Failed to get canvas context");h.clearRect(0,0,t.width,t.height);const p=a==="front"?e.layout.front:e.layout.back;for(let b=0;b<p.layers.length;b++){const w=p.layers[b];if(w.type==="frame"&&o){const v=u*.6*s,T=u*.5*s;if(a==="front"){const f=(l*.78+70)*s;et(h,o,f,T,v,i)}else{const f=l*.5*s;et(h,o,f,T,v,i)}}await Jt(h,w,e,n,r)}}async function $e(t,e,n,a={}){const r=document.createElement("canvas");await Le(r,t,e,n,a);const{scale:s=1}=a,o=s<1?.8:.95;return r.toDataURL("image/jpeg",o)}function Se(){Ee.clear(),je.clear()}const Qt="money-generator-db",F="zustand",en=1;let be=null;function ze(){return be||(be=new Promise((t,e)=>{if(typeof window>"u"||!window.indexedDB){e(new Error("IndexedDB not available"));return}const n=indexedDB.open(Qt,en);n.onerror=()=>{be=null,e(n.error)},n.onsuccess=()=>{t(n.result)},n.onupgradeneeded=()=>{const a=n.result;a.objectStoreNames.contains(F)||a.createObjectStore(F)}}),be)}async function tn(t){try{const e=await ze();return new Promise((n,a)=>{const o=e.transaction(F,"readonly").objectStore(F).get(t);o.onerror=()=>a(o.error),o.onsuccess=()=>n(o.result??null)})}catch(e){return console.error("[IndexedDB] Failed to get item:",e),null}}async function nn(t,e){try{const n=await ze();return new Promise((a,r)=>{const i=n.transaction(F,"readwrite").objectStore(F).put(e,t);i.onerror=()=>r(i.error),i.onsuccess=()=>a()})}catch(n){console.error("[IndexedDB] Failed to set item:",n)}}async function an(t){try{const e=await ze();return new Promise((n,a)=>{const o=e.transaction(F,"readwrite").objectStore(F).delete(t);o.onerror=()=>a(o.error),o.onsuccess=()=>n()})}catch(e){console.error("[IndexedDB] Failed to remove item:",e)}}const rn={getItem:tn,setItem:nn,removeItem:an};function on(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Re=on(),tt={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Re,templateHue:29,templateId:"classic-time-voucher"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,panX:0,panY:0,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1,appLanguage:Re},x=Dt.create()(Fe.persist(t=>({...tt,setPersonalInfo:e=>t(n=>({personalInfo:{...n.personalInfo,...e}})),setVoucherConfig:e=>t(n=>({voucherConfig:{...n.voucherConfig,...e}})),setPortrait:(e,n=null)=>t(a=>{const r=a.portrait.original||a.portrait.rawImage;return{portrait:{...a.portrait,original:e,enhanced:n,useEnhanced:!1,zoom:r&&e?a.portrait.zoom:1,panX:r&&e?a.portrait.panX:0,panY:r&&e?a.portrait.panY:0}}}),setEnhancedPortrait:e=>t(n=>({portrait:{...n.portrait,enhanced:e,useEnhanced:e!==null}})),toggleUseEnhanced:()=>t(e=>({portrait:{...e.portrait,useEnhanced:e.portrait.enhanced?!e.portrait.useEnhanced:!1}})),setPortraitZoom:e=>t(n=>({portrait:{...n.portrait,zoom:e}})),setPortraitPan:(e,n)=>t(a=>({portrait:{...a.portrait,panX:e,panY:n}})),setPortraitRawImage:e=>t(n=>({portrait:{...n.portrait,rawImage:e}})),setPortraitBgRemoved:(e,n)=>t(a=>({portrait:{...a.portrait,bgRemoved:e,bgRemovedImage:n!==void 0?n:a.portrait.bgRemovedImage}})),setPortraitBgOpacity:e=>t(n=>({portrait:{...n.portrait,bgOpacity:e}})),setPortraitBgBlur:e=>t(n=>({portrait:{...n.portrait,bgBlur:e}})),setPortraitEngravingIntensity:e=>t(n=>({portrait:{...n.portrait,engravingIntensity:e}})),setCurrentSide:e=>t({currentSide:e}),flipSide:()=>t(e=>({currentSide:e.currentSide==="front"?"back":"front"})),setIsEnhancing:e=>t({isEnhancing:e}),setIsExporting:e=>t({isExporting:e}),setAppLanguage:e=>t({appLanguage:e}),setBillLanguage:e=>t(n=>({voucherConfig:{...n.voucherConfig,language:e}})),setHours:e=>t(n=>({voucherConfig:{...n.voucherConfig,hours:e}})),setTemplateHue:e=>(Se(),t(n=>({voucherConfig:{...n.voucherConfig,templateHue:e}}))),setTemplateId:e=>(Se(),t(n=>({voucherConfig:{...n.voucherConfig,templateId:e}}))),reset:()=>t(tt)}),{name:"money-generator-storage",storage:Fe.createJSONStorage(()=>rn),skipHydration:!0,migrate:t=>{const e=t;return e!=null&&e.voucherConfig&&(e.voucherConfig.templateHue===void 0&&(e.voucherConfig.templateHue=29),e.voucherConfig.templateId||(e.voucherConfig.templateId="classic-time-voucher"),e.voucherConfig.hours=1,e.voucherConfig.language=Re),e&&(e.appLanguage=Re),e},version:4,partialize:t=>({personalInfo:t.personalInfo,voucherConfig:t.voucherConfig,appLanguage:t.appLanguage,portrait:{original:null,enhanced:null,useEnhanced:t.portrait.useEnhanced,zoom:t.portrait.zoom,panX:t.portrait.panX,panY:t.portrait.panY,rawImage:t.portrait.rawImage,bgRemovedImage:t.portrait.bgRemovedImage,bgRemoved:t.portrait.bgRemoved,bgOpacity:t.portrait.bgOpacity,bgBlur:t.portrait.bgBlur,engravingIntensity:t.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));function sn(){typeof window<"u"&&x.persist.rehydrate()}const cn={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?",billLanguage:"Schein-Sprache",billLanguageGerman:"Deutsch",billLanguageEnglish:"Englisch"},billColor:{title:"Scheinfarbe",label:"Farbton"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {bannerText} meiner Zeit oder ein gleichwertiges Dankeschön.",bannerText:{1:"eine Stunde",5:"fünf Stunden",10:"zehn Stunden"}}},ln={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"For this voucher, you will receive {bannerText} of my time or an equivalent appreciation in return.",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},un={de:cn,en:ln};function J(t){return un[t]}function Ke(t,e,n){if(n&&n.trim())return n;const a=J(t),r=a.bill.bannerText[e]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function dn(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}function gn(t){return t.replace(/\D/g,"").length>=6}function hn({focusField:t,onFocused:e,onFormFocusChange:n}={}){const a=x(f=>f.appLanguage),r=x(f=>f.personalInfo),s=x(f=>f.setPersonalInfo),o=J(a),[i,l]=g.useState(!1),[u,h]=g.useState(!1),p=i&&r.email.trim()&&!dn(r.email),b=u&&r.phone.trim()&&!gn(r.phone),w=g.useRef(null),v=g.useRef(null),T=g.useRef(null);return g.useEffect(()=>{if(t){const f=t==="name"?w:t==="email"?v:T;setTimeout(()=>{var j,m;(j=f.current)==null||j.click(),(m=f.current)==null||m.focus(),setTimeout(()=>{var I;(I=f.current)==null||I.scrollIntoView({behavior:"smooth",block:"center"})},300),e==null||e()},100)}},[t,e]),c.jsxs("div",{className:"space-y-4",children:[c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:o.form.personalInfo.name})}),c.jsx("input",{ref:w,type:"text",name:"name",autoComplete:"name",placeholder:o.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:r.name,onChange:f=>s({name:f.target.value}),onFocus:f=>{n==null||n(!0),setTimeout(()=>f.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>n==null?void 0:n(!1)})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:o.form.personalInfo.email})}),c.jsx("input",{ref:v,type:"email",name:"email",autoComplete:"email",placeholder:o.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${p?"input-error":""}`,value:r.email,onChange:f=>s({email:f.target.value}),onFocus:f=>{n==null||n(!0),setTimeout(()=>f.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{l(!0),n==null||n(!1)}}),p&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige E-Mail-Adresse ein":"Please enter a valid email address"})})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:o.form.personalInfo.phone})}),c.jsx("input",{ref:T,type:"tel",name:"phone",autoComplete:"tel",placeholder:o.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${b?"input-error":""}`,value:r.phone,onChange:f=>s({phone:f.target.value}),onFocus:f=>{n==null||n(!0),setTimeout(()=>f.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{h(!0),n==null||n(!1)}}),b&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige Telefonnummer ein":"Please enter a valid phone number"})})]})]})}const He={},mn="https://api.stability.ai/v1/generation",fn="https://api.stability.ai/v2beta/stable-image/edit/remove-background",ft="stability_api_key";let me=null;function pn(t){me=t}function bn(){return me}function wn(){return me!==null}const vn={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"},nt=[{width:1024,height:1024},{width:1152,height:896},{width:1216,height:832},{width:1344,height:768},{width:1536,height:640},{width:640,height:1536},{width:768,height:1344},{width:832,height:1216},{width:896,height:1152}];function yn(t,e){const n=t/e;let a=nt[0],r=1/0;for(const s of nt){const o=s.width/s.height,i=Math.abs(n-o);i<r&&(r=i,a=s)}return a}function xn(t){return new Promise((e,n)=>{const a=new Image;a.onload=()=>{const r=yn(a.width,a.height),s=document.createElement("canvas");s.width=r.width,s.height=r.height;const o=s.getContext("2d");if(!o){n(new Error("Failed to get canvas context"));return}const i=a.width/a.height,l=r.width/r.height;let u=0,h=0,p=a.width,b=a.height;i>l?(p=a.height*l,u=(a.width-p)/2):(b=a.width/l,h=(a.height-b)/2),o.drawImage(a,u,h,p,b,0,0,r.width,r.height),e(s.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=t})}function pt(t){var o;const e=t.split(","),n=((o=e[0].match(/:(.*?);/))==null?void 0:o[1])||"image/png",a=atob(e[1]),r=a.length,s=new Uint8Array(r);for(let i=0;i<r;i++)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}function Pe(){var e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&(He==null?void 0:He.VITE_STABILITY_API_KEY)||typeof process<"u"&&((e=process.env)==null?void 0:e.NEXT_PUBLIC_STABILITY_API_KEY);return t&&t!=="your-api-key-here"?t:typeof localStorage<"u"?localStorage.getItem(ft):null}function bt(t){localStorage.setItem(ft,t)}function ke(){return me?!0:Pe()!==null}async function In(t){const e=Pe();if(!e)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=t,s=await xn(n),o=pt(s),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]",vn[a]),i.append("text_prompts[0][weight]","1"),i.append("cfg_scale","7"),i.append("samples","1"),i.append("steps","30");const u=await fetch(`${mn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${e}`,Accept:"application/json"},body:i});if(!u.ok){const p=await u.text();throw console.error("Stability AI error:",p),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const h=await u.json();if(!h.artifacts||h.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${h.artifacts[0].base64}`}async function wt(t){if(me){const o=await fetch(me,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:t})});if(!o.ok){const l=await o.json().catch(()=>({}));throw new Error(l.error||`API error: ${o.status}`)}return(await o.json()).imageDataUrl}const e=Pe();if(!e)throw new Error("No Stability AI API key configured");const n=pt(t),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(fn,{method:"POST",headers:{Authorization:`Bearer ${e}`,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 s=await r.blob();return new Promise((o,i)=>{const l=new FileReader;l.onload=()=>o(l.result),l.onerror=()=>i(new Error("Failed to read result")),l.readAsDataURL(s)})}function Tn(){const[t,e]=g.useState(!1),[n,a]=g.useState(!1),[r,s]=g.useState(null),[o,i]=g.useState(()=>ke());g.useEffect(()=>{i(ke());const b=setTimeout(()=>{i(ke())},150);return()=>clearTimeout(b)},[]);const l=g.useCallback(()=>s(null),[]),u=g.useCallback(b=>{bt(b),i(!0),s(null)},[]),h=g.useCallback(async(b,w=.5,v=40)=>{e(!0),s(null);try{return await lt(b,w,v)}catch(T){const f=T instanceof Error?T.message:"Enhancement failed";throw s(f),T}finally{e(!1)}},[]),p=g.useCallback(async b=>{a(!0),s(null);try{return await wt(b)}catch(w){const v=w instanceof Error?w.message:"Background removal failed";throw s(v),w}finally{a(!1)}},[]);return{enhance:h,removeBg:p,isEnhancing:t,isRemovingBg:n,error:r,hasKey:o,setApiKey:u,clearError:l}}function vt({isOpen:t,onClose:e,onSubmit:n}){const a=x(u=>u.appLanguage),[r,s]=g.useState("");if(!t)return null;const o=u=>{u.preventDefault(),r.trim()&&(n(r.trim()),s(""),e())},l={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[a];return c.jsxs("dialog",{className:"modal modal-open",children:[c.jsxs("div",{className:"modal-box",children:[c.jsx("h3",{className:"font-bold text-lg",children:l.title}),c.jsx("p",{className:"py-4 text-sm opacity-80",children:l.description}),c.jsxs("form",{onSubmit:o,children:[c.jsxs("div",{className:"form-control",children:[c.jsx("input",{type:"password",placeholder:l.placeholder,className:"input input-bordered w-full",value:r,onChange:u=>s(u.target.value),autoFocus:!0}),c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt",children:l.hint})})]}),c.jsxs("div",{className:"modal-action",children:[c.jsx("button",{type:"button",className:"btn btn-ghost",onClick:e,children:l.cancel}),c.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:l.submit})]})]})]}),c.jsx("form",{method:"dialog",className:"modal-backdrop",children:c.jsx("button",{onClick:e,children:"close"})})]})}function we({min:t,max:e,step:n,value:a,onChange:r,className:s="",disabled:o=!1}){const i=g.useRef(null),l=g.useRef(null),u=g.useRef(!1),[h,p]=g.useState(!1),b=(a-t)/(e-t)*100,w=g.useCallback(I=>{if(!i.current)return a;const E=i.current.getBoundingClientRect(),R=Math.max(0,Math.min(1,(I-E.left)/E.width)),S=e-t,P=t+R*S,B=Math.round(P/n)*n;return Math.max(t,Math.min(e,B))},[t,e,n,a]),v=g.useCallback(I=>{if(o)return;const E=I.touches[0];l.current={x:E.clientX,y:E.clientY,value:a,decided:!1},u.current=!1},[a,o]),T=g.useCallback(I=>{if(o||!l.current)return;const E=I.touches[0],R=Math.abs(E.clientX-l.current.x),S=Math.abs(E.clientY-l.current.y);if(!l.current.decided){if(R<8&&S<8)return;if(l.current.decided=!0,S>R){l.current=null;return}u.current=!0,p(!0)}if(u.current){const P=w(E.clientX);P!==a&&r(P)}},[o,w,r,a]),f=g.useCallback(I=>{if(l.current&&!l.current.decided){const E=I.changedTouches[0];if(E){const R=w(E.clientX);R!==a&&r(R)}}l.current=null,u.current=!1,p(!1)},[w,r,a]);g.useEffect(()=>{const I=i.current;if(!I)return;const E=R=>{u.current&&R.preventDefault()};return I.addEventListener("touchmove",E,{passive:!1}),()=>{I.removeEventListener("touchmove",E)}},[]);const j=g.useCallback(I=>{if(o)return;const E=w(I.clientX);r(E),p(!0);const R=P=>{const B=w(P.clientX);r(B)},S=()=>{p(!1),document.removeEventListener("mousemove",R),document.removeEventListener("mouseup",S)};document.addEventListener("mousemove",R),document.addEventListener("mouseup",S)},[o,w,r]),m=`calc(10px + (100% - 20px) * ${b/100})`;return c.jsxs("div",{ref:i,className:`relative h-10 flex items-center cursor-pointer overflow-visible ${o?"opacity-50 cursor-not-allowed":""}`,onTouchStart:v,onTouchMove:T,onTouchEnd:f,onMouseDown:j,children:[c.jsx("div",{className:"absolute h-2 bg-base-300 rounded-full inset-x-0"}),c.jsx("div",{className:`absolute h-2 rounded-full transition-colors ${s.includes("range-primary")?"bg-primary":s.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{left:0,width:m}}),c.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transition-transform ${h?"scale-110":""} ${s.includes("range-primary")?"border-primary":s.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:m,transform:"translateX(-50%)"}})]})}function En(){const t=x(y=>y.appLanguage),e=x(y=>y.portrait),n=x(y=>y.setPortrait),a=x(y=>y.setPortraitZoom),r=x(y=>y.setPortraitPan),s=x(y=>y.setPortraitRawImage),o=x(y=>y.setPortraitBgRemoved),i=x(y=>y.setPortraitBgOpacity),l=x(y=>y.setPortraitBgBlur),u=x(y=>y.setPortraitEngravingIntensity),{enhance:h,removeBg:p,isEnhancing:b,isRemovingBg:w,error:v,hasKey:T,setApiKey:f}=Tn(),j=J(t),m=g.useRef(null),[I,E]=g.useState(!1),[R,S]=g.useState(!1),P=g.useRef(null),B=g.useRef(null),H=e.rawImage,re=e.bgRemovedImage,Q=e.bgRemoved,Y=e.bgOpacity,A=e.bgBlur,_=e.engravingIntensity;g.useEffect(()=>{e.original&&!e.rawImage&&s(e.original)},[e.original,e.rawImage,s]),g.useEffect(()=>()=>{P.current&&clearTimeout(P.current),B.current&&clearTimeout(B.current)},[]);const ee=x(y=>y.voucherConfig.templateHue),z=g.useRef(ee),W=g.useCallback(async y=>{if(!y.type.startsWith("image/"))return;const k=new FileReader;k.onload=async M=>{var U;const D=(U=M.target)==null?void 0:U.result,O=await ct(D);it(),s(O),n(O),a(1),r(0,0),o(!1,null),i(0),l(0),u(0)},k.readAsDataURL(y)},[n,s,a,r,o,i,l,u]),K=g.useCallback(y=>{y.preventDefault(),E(!1);const k=y.dataTransfer.files[0];k&&W(k)},[W]),oe=g.useCallback(y=>{y.preventDefault(),E(!0)},[]),ye=g.useCallback(y=>{y.preventDefault(),E(!1)},[]),fe=()=>{var y;(y=m.current)==null||y.click()},se=y=>{var M;const k=(M=y.target.files)==null?void 0:M[0];k&&W(k)},V=g.useCallback(async(y,k,M)=>{try{return await h(y,k,M)}catch(D){return console.error("Enhancement failed:",D),y}},[h]),q=g.useCallback(async y=>{try{const k=await p(y);return o(!0,k),k}catch(k){return console.error("Background removal failed:",k),y}},[p,o]),$=g.useCallback(async()=>{const y=x.getState(),k=y.portrait,M=y.voucherConfig.templateHue;if(!k.rawImage)return;let D;k.bgRemoved&&k.bgRemovedImage?D=await Te(k.bgRemovedImage,k.rawImage,k.bgOpacity,k.bgBlur):D=k.rawImage,k.engravingIntensity>0&&(D=await V(D,k.engravingIntensity,M)),n(D)},[V,n]),ie=g.useRef(!1);g.useEffect(()=>{e.rawImage&&!e.original&&!ie.current&&(ie.current=!0,setTimeout(()=>{$()},0)),e.rawImage||(ie.current=!1)},[e.rawImage,e.original,$]),g.useEffect(()=>{if(z.current===ee)return;z.current=ee;const y=x.getState().portrait;y.engravingIntensity>0&&y.rawImage&&(P.current&&clearTimeout(P.current),P.current=setTimeout($,150))},[ee,$]);const xe=async()=>{if(!H)return;if(!Q&&!T){S(!0);return}if(!Q){const k=await q(H),M=x.getState(),D=M.portrait,O=M.voucherConfig.templateHue;let U=await Te(k,H,D.bgOpacity,D.bgBlur);D.engravingIntensity>0&&(U=await V(U,D.engravingIntensity,O)),n(U)}else{o(!1,null);const k=x.getState(),M=k.portrait.engravingIntensity,D=k.voucherConfig.templateHue;if(M>0){const O=await V(H,M,D);n(O)}else n(H)}},pe=y=>{u(y),P.current&&clearTimeout(P.current),H&&(P.current=setTimeout($,150))},Ie=async y=>{if(f(y),!H)return;const k=await q(H),M=x.getState(),D=M.portrait,O=M.voucherConfig.templateHue;let U=await Te(k,H,D.bgOpacity,D.bgBlur);D.engravingIntensity>0&&(U=await V(U,D.engravingIntensity,O)),n(U)},Ce=y=>{i(y),B.current&&clearTimeout(B.current),!(!H||!re)&&(B.current=setTimeout($,150))},De=y=>{l(y),B.current&&clearTimeout(B.current),!(!H||!re)&&(B.current=setTimeout($,150))};return c.jsxs("div",{className:"space-y-4",children:[c.jsx("style",{children:`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),h=require("react"),Dt=require("zustand"),Ze=require("zustand/middleware"),Bt=require("jspdf");var ge=typeof document<"u"?document.currentScript:null;const At=1024,Je=1200,de=new Map;let z=null,Qe=null;function ze(t,e){return z||(z=document.createElement("canvas"),Qe=z.getContext("2d",{willReadFrequently:!0})),(z.width!==t||z.height!==e)&&(z.width=t,z.height=e),Qe}function he(t){const e=de.get(t);return e?Promise.resolve(e):new Promise((n,r)=>{const a=new Image;a.onload=()=>{if(de.size>10){const o=de.keys().next().value;o&&de.delete(o)}de.set(t,a),n(a)},a.onerror=()=>r(new Error("Failed to load image")),a.src=t})}function it(){de.clear()}async function ct(t,e=At){const n=await he(t),r=Math.max(n.width,n.height);if(r<=e)return t;const a=e/r,o=Math.round(n.width*a),s=Math.round(n.height*a),i=document.createElement("canvas"),l=i.getContext("2d");if(!l)throw new Error("Failed to get canvas context");return i.width=o,i.height=s,l.drawImage(n,0,0,o,s),i.toDataURL("image/jpeg",.9)}async function Mt(t){const e=await he(t),n=Math.max(e.width,e.height);if(n<=Je){const l=document.createElement("canvas"),u=l.getContext("2d");if(!u)throw new Error("Failed to get canvas context");return l.width=e.width,l.height=e.height,u.drawImage(e,0,0),l.toDataURL("image/png")}const r=Je/n,a=Math.round(e.width*r),o=Math.round(e.height*r),s=document.createElement("canvas"),i=s.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return s.width=a,s.height=o,i.drawImage(e,0,0,a,o),s.toDataURL("image/png")}async function Te(t,e,n,r=0){const[a,o]=await Promise.all([he(t),he(e)]),s=ze(a.width,a.height);if(s.clearRect(0,0,a.width,a.height),n>0){const i=r*20;s.save(),s.globalAlpha=n,i>0&&(s.filter=`blur(${i}px)`),s.drawImage(o,0,0,a.width,a.height),s.restore()}return s.drawImage(a,0,0),z.toDataURL("image/png")}async function lt(t,e=.5,n=40){const r=await he(t),a=ze(r.width,r.height);a.clearRect(0,0,r.width,r.height),a.drawImage(r,0,0);const o=a.getImageData(0,0,r.width,r.height),s=o.data,i=new Uint32Array(s.buffer),l=1+e*.8,u=1-e,m=n%360/360;for(let d=0;d<i.length;d++){const w=i[d],p=w&255,b=w>>8&255,T=w>>16&255,f=w>>24&255;if(f===0)continue;let x=(((77*p+150*b+29*T>>8)/255-.5)*l+.5)*255;x<0?x=0:x>255&&(x=255);const I=x/255,L=.12,[N,R,C]=ut(m,L,I),B=p*u+N*e|0,H=b*u+R*e|0,V=T*u+C*e|0;i[d]=f<<24|V<<16|H<<8|B}return a.putImageData(o,0,0),z.toDataURL("image/png")}function Ht(t,e,n){t/=255,e/=255,n/=255;const r=Math.max(t,e,n),a=Math.min(t,e,n),o=(r+a)/2;let s=0,i=0;if(r!==a){const l=r-a;switch(i=o>.5?l/(2-r-a):l/(r+a),r){case t:s=((e-n)/l+(e<n?6:0))/6;break;case e:s=((n-t)/l+2)/6;break;case n:s=((t-e)/l+4)/6;break}}return[s,i,o]}function ut(t,e,n){if(e===0){const s=Math.round(n*255);return[s,s,s]}const r=(s,i,l)=>(l<0&&(l+=1),l>1&&(l-=1),l<1/6?s+(i-s)*6*l:l<1/2?i:l<2/3?s+(i-s)*(2/3-l)*6:s),a=n<.5?n*(1+e):n+e-n*e,o=2*n-a;return[Math.round(r(o,a,t+1/3)*255),Math.round(r(o,a,t)*255),Math.round(r(o,a,t-1/3)*255)]}const Ut=29,Yt=5;async function dt(t,e){if(Math.abs(e-Ut)<=Yt)return t;const n=await he(t),r=ze(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),o=a.data,s=new Uint32Array(o.buffer),i=e%360/360,l=20/360,u=45/360,m=s.length;for(let d=0;d<m;d++){const w=s[d],p=w&255,b=w>>8&255,T=w>>16&255,f=w>>24&255;if(f===0)continue;const[E,x,I]=Ht(p,b,T);if(x<.08||E<l||E>u)continue;const L=i,N=Math.min(x,.05),[R,C,B]=ut(L,N,I);s[d]=f<<24|B<<16|C<<8|R}return r.putImageData(a,0,0),z.toDataURL("image/png")}async function gt(t){return new Promise((e,n)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>e(r),r.onerror=n,r.src=t})}const Ee=new Map,ke=new Map;async function ae(t){if(Ee.has(t))return Ee.get(t);const e=await gt(t);return Ee.set(t,e),e}function $t(t){const e=document.createElement("canvas");e.width=t.width,e.height=t.height;const n=e.getContext("2d");if(!n)throw new Error("Failed to get canvas context");return n.drawImage(t,0,0),e.toDataURL("image/jpeg",.95)}async function Ot(t,e){if(e===0)return ae(t);ke.has(t)||ke.set(t,new Map);const n=ke.get(t);if(n.has(e))return ae(n.get(e));const r=await ae(t),a=$t(r),o=await dt(a,e);return n.set(e,o),gt(o)}function ht(t,e,n,r){const a=t.x*r,o=t.y*r;switch(t.anchor||"topLeft"){case"topLeft":return{x:a,y:o};case"topCenter":return{x:a-e/2,y:o};case"topRight":return{x:a-e,y:o};case"centerLeft":return{x:a,y:o-n/2};case"center":return{x:a-e/2,y:o-n/2};case"centerRight":return{x:a-e,y:o-n/2};case"bottomLeft":return{x:a,y:o-n};case"bottomCenter":return{x:a-e/2,y:o-n};case"bottomRight":return{x:a-e,y:o-n};default:return{x:a,y:o}}}function Ue(t,e){return t?typeof t=="string"?t:t[e]||t.en||t.de||Object.values(t)[0]||"":""}const ue={de:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"},en:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}};function Xt(t,e,n){return t.replace(/\{\{(\w+)\}\}/g,(r,a)=>{if(a==="hours_banner_de"){const s=Number(e.hours)||1;return ue.de[s]||ue.de[1]}if(a==="hours_banner_en"){const s=Number(e.hours)||1;return ue.en[s]||ue.en[1]}if(a==="hours_banner"){const s=Number(e.hours)||1,i=n==="de"?"de":"en";return ue[i][s]||ue[i][1]}const o=e[a];return o==null?"":String(o)})}function _t(t,e,n){const r=t.assets;if(e==="front"&&r.front)return r.front;if(e==="back"&&r.back)return r.back;if(e==="background"&&r.background)return r.background;if(e==="frontFrame"&&r.frontFrame)return r.frontFrame;if(e==="backFrame"&&r.backFrame)return r.backFrame;if(e==="background"){if(n==="front"&&r.front)return r.front;if(n==="back"&&r.back)return r.back}if(r.decorations&&r.decorations[e])return r.decorations[e]}async function Wt(t,e,n,r){const{scale:a=1,hue:o=0,side:s="front"}=r,i=_t(n,e.source,s);if(!i)return;const l=e.hueShift?await Ot(i,o):await ae(i),u=n.layout.dimensions.width*a,m=n.layout.dimensions.height*a;e.blendMode&&(t.globalCompositeOperation=mt(e.blendMode)),e.opacity!==void 0&&(t.globalAlpha=e.opacity),t.drawImage(l,0,0,u,m),t.globalCompositeOperation="source-over",t.globalAlpha=1}function mt(t){return{normal:"source-over",multiply:"multiply",screen:"screen",overlay:"overlay",darken:"darken",lighten:"lighten","color-dodge":"color-dodge","color-burn":"color-burn"}[t]||"source-over"}async function zt(t,e,n,r){const{scale:a=1}=r,o=e.source==="frontFrame"?n.assets.frontFrame:n.assets.backFrame;if(!o)return;const s=await ae(o),i=n.layout.dimensions.width*a,l=n.layout.dimensions.height*a;e.blendMode&&(t.globalCompositeOperation=mt(e.blendMode)),e.opacity!==void 0&&(t.globalAlpha=e.opacity),t.drawImage(s,0,0,i,l),t.globalCompositeOperation="source-over",t.globalAlpha=1}async function Vt(t,e,n,r,a){const{scale:o=1}=a,s=n.assets.badges;if(!s||s.type!=="image"||!s.variants)return;const i=r[e.fieldId],l=s.variants.find(m=>m.value===i);if(!l)return;const u=await ae(l.image);for(const m of e.positions){const d=(m.size||l.size||100)*o,{x:w,y:p}=ht({x:m.x,y:m.y,anchor:m.anchor||"center"},d,d,o);t.drawImage(u,w,p,d,d)}}async function Kt(t,e,n,r,a){var f,E;const{scale:o=1,language:s="de",portraitImage:i,portraitTransform:l}=a,u=r[e.fieldId],m=n.schema.fields.find(x=>x.id===e.fieldId);if(!m)return;if(m.type==="image"&&e.clip){await Gt(t,e,i||null,l,o);return}if(u==null||u==="")return;const d=String(u),w=e.style||{fontSize:50,fontFamily:((f=n.layout.global)==null?void 0:f.fontFamily)||"sans-serif",color:((E=n.layout.global)==null?void 0:E.textColor)||"#000000"},p=Ue(e.prefix,s),b=Ue(e.suffix,s),T=`${p}${d}${b}`;Ye(t,T,e,w,o)}async function Gt(t,e,n,r,a){if(!n||!e.size)return;const{radiusX:o=100,radiusY:s=100}=e.size,i=o*a,l=s*a,u=e.position.x*a,m=e.position.y*a;if(t.save(),t.beginPath(),e.clip==="ellipse")t.ellipse(u,m,i,l,0,0,Math.PI*2);else if(e.clip==="circle"){const B=Math.min(i,l);t.arc(u,m,B,0,Math.PI*2)}else e.clip==="rectangle"&&t.rect(u-i,m-l,i*2,l*2);t.clip();const d=(r==null?void 0:r.scale)||1,w=(r==null?void 0:r.offsetX)||0,p=(r==null?void 0:r.offsetY)||0,b=i*2,T=l*2,f=n.width/n.height,E=b/T;let x,I;f>E?(I=T,x=I*f):(x=b,I=x/f),x*=d,I*=d;const L=Math.max(0,(x-b)/2),N=Math.max(0,(I-T)/2),R=u-x/2+w*L,C=m-I/2+p*N;t.drawImage(n,R,C,x,I),t.restore()}function Ye(t,e,n,r,a){t.save();const o=r.fontSize*a,s=r.fontWeight||"normal";t.font=`${s} ${o}px ${r.fontFamily}`,t.fillStyle=r.color;const i="align"in n?n.align:"center";t.textAlign=i||"center",t.textBaseline="middle",r.textShadow&&(t.shadowColor="rgba(0,0,0,0.3)",t.shadowBlur=2*a,t.shadowOffsetX=1*a,t.shadowOffsetY=1*a);const l=n.position.x*a,u=n.position.y*a;if("multiline"in n&&n.multiline&&"maxWidth"in n&&n.maxWidth){const m=n.maxWidth*a,d=("lineHeight"in n&&n.lineHeight?n.lineHeight:r.fontSize*1.2)*a,w=qt(t,e,m),p=w.length*d;let b=u-p/2+d/2;for(const T of w)t.fillText(T,l,b),b+=d}else t.fillText(e,l,u);t.restore()}function qt(t,e,n){const r=e.split(" "),a=[];let o="";for(const s of r){const i=o?`${o} ${s}`:s;t.measureText(i).width>n&&o?(a.push(o),o=s):o=i}return o&&a.push(o),a}function Ft(t,e,n,r){const{scale:a=1,language:o="de"}=r;let s=Ue(e.content,o);if(s=Xt(s,n,o),!!s){if(e.arc){Zt(t,s,e,a);return}if(e.rotation){t.save();const i=e.position.x*a,l=e.position.y*a;t.translate(i,l),t.rotate(e.rotation*Math.PI/180),Ye(t,s,{...e,position:{x:0,y:0}},e.style,1),t.restore();return}Ye(t,s,e,e.style,a)}}function Zt(t,e,n,r){if(!n.arc)return;const{centerX:a,centerY:o,radius:s}=n.arc,i=n.style;t.save();const l=i.fontSize*r,u=i.fontWeight||"normal";t.font=`${u} ${l}px ${i.fontFamily}`,t.fillStyle=i.color,t.textAlign="center",t.textBaseline="middle";const m=a*r,d=o*r,w=s*r,b=t.measureText(e).width/w,T=-Math.PI/2-b/2,f=e.split(""),E=f.map(I=>t.measureText(I).width);let x=T;for(let I=0;I<f.length;I++){const L=f[I],N=E[I],R=x+N/2/w,C=m+w*Math.cos(R),B=d+w*Math.sin(R);t.save(),t.translate(C,B),t.rotate(R+Math.PI/2),t.fillText(L,0,0),t.restore(),x+=N/w}t.restore()}async function Jt(t,e,n,r){var d,w,p;const{scale:a=1}=r,o=(d=n.assets.decorations)==null?void 0:d[e.source];if(!o)return;const s=await ae(o),i=(((w=e.size)==null?void 0:w.width)||s.width)*a,l=(((p=e.size)==null?void 0:p.height)||s.height)*a,{x:u,y:m}=ht(e.position,i,l,a);t.save(),e.opacity!==void 0&&(t.globalAlpha=e.opacity),e.rotation?(t.translate(u+i/2,m+l/2),t.rotate(e.rotation*Math.PI/180),t.drawImage(s,-i/2,-l/2,i,l)):t.drawImage(s,u,m,i,l),t.restore()}function et(t,e,n,r,a,o){t.save();const s=document.createElement("canvas");s.width=a,s.height=a;const i=s.getContext("2d");if(!i){t.restore();return}const l=e.width/e.height;let u,m;l>1?(m=a,u=a*l):(u=a,m=a/l);const d=(o==null?void 0:o.scale)||1,w=(o==null?void 0:o.offsetX)||0,p=(o==null?void 0:o.offsetY)||0;u*=d,m*=d;const b=Math.max(0,(u-a)/2),T=Math.max(0,(m-a)/2),f=(a-u)/2+w*b,E=(a-m)/2+p*T;i.filter="grayscale(70%) brightness(1.4) contrast(0.6)",i.drawImage(e,f,E,u,m),i.filter="none",i.globalCompositeOperation="destination-in";const x=i.createRadialGradient(a/2,a/2,0,a/2,a/2,a/2);x.addColorStop(0,"rgba(0,0,0,1)"),x.addColorStop(.5,"rgba(0,0,0,0.8)"),x.addColorStop(.8,"rgba(0,0,0,0.3)"),x.addColorStop(1,"rgba(0,0,0,0)"),i.fillStyle=x,i.fillRect(0,0,a,a),t.globalAlpha=.18,t.drawImage(s,n-a/2,r-a/2),t.globalAlpha=1,t.restore()}async function Qt(t,e,n,r,a){switch(e.type){case"background":await Wt(t,e,n,a);break;case"frame":await zt(t,e,n,a);break;case"badges":await Vt(t,e,n,r,a);break;case"field":await Kt(t,e,n,r,a);break;case"text":Ft(t,e,r,a);break;case"decoration":await Jt(t,e,n,a);break}}async function Le(t,e,n,r,a={}){const{scale:o=1,portraitImage:s,portraitTransform:i}=a,{width:l,height:u}=e.layout.dimensions,m={...a,side:r};t.width=l*o,t.height=u*o;const d=t.getContext("2d");if(!d)throw new Error("Failed to get canvas context");d.clearRect(0,0,t.width,t.height);const w=r==="front"?e.layout.front:e.layout.back;for(let p=0;p<w.layers.length;p++){const b=w.layers[p];if(b.type==="frame"&&s){const T=u*.6*o,f=u*.5*o;if(r==="front"){const E=(l*.78+70)*o;et(d,s,E,f,T,i)}else{const E=l*.5*o;et(d,s,E,f,T,i)}}await Qt(d,b,e,n,m)}}async function $e(t,e,n,r={}){const a=document.createElement("canvas");await Le(a,t,e,n,r);const{scale:o=1}=r,s=o<1?.8:.95;return a.toDataURL("image/jpeg",s)}function Se(){Ee.clear(),ke.clear()}const en="money-generator-db",ee="zustand",tn=1;let be=null;function Ve(){return be||(be=new Promise((t,e)=>{if(typeof window>"u"||!window.indexedDB){e(new Error("IndexedDB not available"));return}const n=indexedDB.open(en,tn);n.onerror=()=>{be=null,e(n.error)},n.onsuccess=()=>{t(n.result)},n.onupgradeneeded=()=>{const r=n.result;r.objectStoreNames.contains(ee)||r.createObjectStore(ee)}}),be)}async function nn(t){try{const e=await Ve();return new Promise((n,r)=>{const s=e.transaction(ee,"readonly").objectStore(ee).get(t);s.onerror=()=>r(s.error),s.onsuccess=()=>n(s.result??null)})}catch(e){return console.error("[IndexedDB] Failed to get item:",e),null}}async function rn(t,e){try{const n=await Ve();return new Promise((r,a)=>{const i=n.transaction(ee,"readwrite").objectStore(ee).put(e,t);i.onerror=()=>a(i.error),i.onsuccess=()=>r()})}catch(n){console.error("[IndexedDB] Failed to set item:",n)}}async function an(t){try{const e=await Ve();return new Promise((n,r)=>{const s=e.transaction(ee,"readwrite").objectStore(ee).delete(t);s.onerror=()=>r(s.error),s.onsuccess=()=>n()})}catch(e){console.error("[IndexedDB] Failed to remove item:",e)}}const on={getItem:nn,setItem:rn,removeItem:an};function sn(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Re=sn(),tt={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Re,templateHue:29,templateId:"classic-time-voucher"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,panX:0,panY:0,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1,appLanguage:Re},y=Dt.create()(Ze.persist(t=>({...tt,setPersonalInfo:e=>t(n=>({personalInfo:{...n.personalInfo,...e}})),setVoucherConfig:e=>t(n=>({voucherConfig:{...n.voucherConfig,...e}})),setPortrait:(e,n=null)=>t(r=>{const a=r.portrait.original||r.portrait.rawImage;return{portrait:{...r.portrait,original:e,enhanced:n,useEnhanced:!1,zoom:a&&e?r.portrait.zoom:1,panX:a&&e?r.portrait.panX:0,panY:a&&e?r.portrait.panY:0}}}),setEnhancedPortrait:e=>t(n=>({portrait:{...n.portrait,enhanced:e,useEnhanced:e!==null}})),toggleUseEnhanced:()=>t(e=>({portrait:{...e.portrait,useEnhanced:e.portrait.enhanced?!e.portrait.useEnhanced:!1}})),setPortraitZoom:e=>t(n=>({portrait:{...n.portrait,zoom:e}})),setPortraitPan:(e,n)=>t(r=>({portrait:{...r.portrait,panX:e,panY:n}})),setPortraitRawImage:e=>t(n=>({portrait:{...n.portrait,rawImage:e}})),setPortraitBgRemoved:(e,n)=>t(r=>({portrait:{...r.portrait,bgRemoved:e,bgRemovedImage:n!==void 0?n:r.portrait.bgRemovedImage}})),setPortraitBgOpacity:e=>t(n=>({portrait:{...n.portrait,bgOpacity:e}})),setPortraitBgBlur:e=>t(n=>({portrait:{...n.portrait,bgBlur:e}})),setPortraitEngravingIntensity:e=>t(n=>({portrait:{...n.portrait,engravingIntensity:e}})),setCurrentSide:e=>t({currentSide:e}),flipSide:()=>t(e=>({currentSide:e.currentSide==="front"?"back":"front"})),setIsEnhancing:e=>t({isEnhancing:e}),setIsExporting:e=>t({isExporting:e}),setAppLanguage:e=>t({appLanguage:e}),setBillLanguage:e=>t(n=>({voucherConfig:{...n.voucherConfig,language:e}})),setHours:e=>t(n=>({voucherConfig:{...n.voucherConfig,hours:e}})),setTemplateHue:e=>(Se(),t(n=>({voucherConfig:{...n.voucherConfig,templateHue:e}}))),setTemplateId:e=>(Se(),t(n=>({voucherConfig:{...n.voucherConfig,templateId:e}}))),reset:()=>t(tt)}),{name:"money-generator-storage",storage:Ze.createJSONStorage(()=>on),skipHydration:!0,migrate:t=>{const e=t;return e!=null&&e.voucherConfig&&(e.voucherConfig.templateHue===void 0&&(e.voucherConfig.templateHue=29),e.voucherConfig.templateId||(e.voucherConfig.templateId="classic-time-voucher"),e.voucherConfig.hours=1,e.voucherConfig.language=Re),e&&(e.appLanguage=Re),e},version:4,partialize:t=>({personalInfo:t.personalInfo,voucherConfig:t.voucherConfig,appLanguage:t.appLanguage,portrait:{original:null,enhanced:null,useEnhanced:t.portrait.useEnhanced,zoom:t.portrait.zoom,panX:t.portrait.panX,panY:t.portrait.panY,rawImage:t.portrait.rawImage,bgRemovedImage:t.portrait.bgRemovedImage,bgRemoved:t.portrait.bgRemoved,bgOpacity:t.portrait.bgOpacity,bgBlur:t.portrait.bgBlur,engravingIntensity:t.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));function cn(){typeof window<"u"&&y.persist.rehydrate()}const ln={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?",billLanguage:"Schein-Sprache",billLanguageGerman:"Deutsch",billLanguageEnglish:"Englisch"},billColor:{title:"Scheinfarbe",label:"Farbton"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {bannerText} meiner Zeit oder ein gleichwertiges Dankeschön.",bannerText:{1:"eine Stunde",5:"fünf Stunden",10:"zehn Stunden"}}},un={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"For this voucher, you will receive {bannerText} of my time or an equivalent appreciation in return.",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},dn={de:ln,en:un};function te(t){return dn[t]}function Ke(t,e,n){if(n&&n.trim())return n;const r=te(t),a=r.bill.bannerText[e]||r.bill.bannerText[1];return r.bill.descriptionText.replace("{bannerText}",a)}function gn(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}function hn(t){return t.replace(/\D/g,"").length>=6}function mn({focusField:t,onFocused:e,onFormFocusChange:n}={}){const r=y(f=>f.appLanguage),a=y(f=>f.personalInfo),o=y(f=>f.setPersonalInfo),s=te(r),[i,l]=h.useState(!1),[u,m]=h.useState(!1),d=i&&a.email.trim()&&!gn(a.email),w=u&&a.phone.trim()&&!hn(a.phone),p=h.useRef(null),b=h.useRef(null),T=h.useRef(null);return h.useEffect(()=>{if(t){const f=t==="name"?p:t==="email"?b:T;setTimeout(()=>{var E,x;(E=f.current)==null||E.click(),(x=f.current)==null||x.focus(),setTimeout(()=>{var I;(I=f.current)==null||I.scrollIntoView({behavior:"smooth",block:"center"})},300),e==null||e()},100)}},[t,e]),c.jsxs("div",{className:"space-y-4",children:[c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:s.form.personalInfo.name})}),c.jsx("input",{ref:p,type:"text",name:"name",autoComplete:"name",placeholder:s.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:a.name,onChange:f=>o({name:f.target.value}),onFocus:f=>{n==null||n(!0),setTimeout(()=>f.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>n==null?void 0:n(!1)})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:s.form.personalInfo.email})}),c.jsx("input",{ref:b,type:"email",name:"email",autoComplete:"email",placeholder:s.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${d?"input-error":""}`,value:a.email,onChange:f=>o({email:f.target.value}),onFocus:f=>{n==null||n(!0),setTimeout(()=>f.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{l(!0),n==null||n(!1)}}),d&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:r==="de"?"Bitte gib eine gültige E-Mail-Adresse ein":"Please enter a valid email address"})})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:s.form.personalInfo.phone})}),c.jsx("input",{ref:T,type:"tel",name:"phone",autoComplete:"tel",placeholder:s.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${w?"input-error":""}`,value:a.phone,onChange:f=>o({phone:f.target.value}),onFocus:f=>{n==null||n(!0),setTimeout(()=>f.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{m(!0),n==null||n(!1)}}),w&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:r==="de"?"Bitte gib eine gültige Telefonnummer ein":"Please enter a valid phone number"})})]})]})}const He={},fn="https://api.stability.ai/v1/generation",pn="https://api.stability.ai/v2beta/stable-image/edit/remove-background",ft="stability_api_key";let me=null;function bn(t){me=t}function wn(){return me}function vn(){return me!==null}const yn={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"},nt=[{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 xn(t,e){const n=t/e;let r=nt[0],a=1/0;for(const o of nt){const s=o.width/o.height,i=Math.abs(n-s);i<a&&(a=i,r=o)}return r}function In(t){return new Promise((e,n)=>{const r=new Image;r.onload=()=>{const a=xn(r.width,r.height),o=document.createElement("canvas");o.width=a.width,o.height=a.height;const s=o.getContext("2d");if(!s){n(new Error("Failed to get canvas context"));return}const i=r.width/r.height,l=a.width/a.height;let u=0,m=0,d=r.width,w=r.height;i>l?(d=r.height*l,u=(r.width-d)/2):(w=r.width/l,m=(r.height-w)/2),s.drawImage(r,u,m,d,w,0,0,a.width,a.height),e(o.toDataURL("image/png"))},r.onerror=()=>n(new Error("Failed to load image")),r.src=t})}function pt(t){var s;const e=t.split(","),n=((s=e[0].match(/:(.*?);/))==null?void 0:s[1])||"image/png",r=atob(e[1]),a=r.length,o=new Uint8Array(a);for(let i=0;i<a;i++)o[i]=r.charCodeAt(i);return new Blob([o],{type:n})}function Pe(){var e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&(He==null?void 0:He.VITE_STABILITY_API_KEY)||typeof process<"u"&&((e=process.env)==null?void 0:e.NEXT_PUBLIC_STABILITY_API_KEY);return t&&t!=="your-api-key-here"?t:typeof localStorage<"u"?localStorage.getItem(ft):null}function bt(t){localStorage.setItem(ft,t)}function je(){return me?!0:Pe()!==null}async function Tn(t){const e=Pe();if(!e)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=t,o=await In(n),s=pt(o),i=new FormData;i.append("init_image",s,"portrait.png"),i.append("init_image_mode","IMAGE_STRENGTH"),i.append("image_strength",String(1-a)),i.append("text_prompts[0][text]",yn[r]),i.append("text_prompts[0][weight]","1"),i.append("cfg_scale","7"),i.append("samples","1"),i.append("steps","30");const u=await fetch(`${fn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${e}`,Accept:"application/json"},body:i});if(!u.ok){const d=await u.text();throw console.error("Stability AI error:",d),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const m=await u.json();if(!m.artifacts||m.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${m.artifacts[0].base64}`}async function wt(t){if(me){const s=await fetch(me,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:t})});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||`API error: ${s.status}`)}return(await s.json()).imageDataUrl}const e=Pe();if(!e)throw new Error("No Stability AI API key configured");const n=pt(t),r=new FormData;r.append("image",n,"image.png"),r.append("output_format","png");const a=await fetch(pn,{method:"POST",headers:{Authorization:`Bearer ${e}`,Accept:"image/*"},body:r});if(!a.ok){const s=await a.text();throw console.error("Stability AI remove background error:",s),a.status===401?new Error("Invalid API key"):a.status===402?new Error("Insufficient credits"):a.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${a.status}`)}const o=await a.blob();return new Promise((s,i)=>{const l=new FileReader;l.onload=()=>s(l.result),l.onerror=()=>i(new Error("Failed to read result")),l.readAsDataURL(o)})}function En(){const[t,e]=h.useState(!1),[n,r]=h.useState(!1),[a,o]=h.useState(null),[s,i]=h.useState(()=>je());h.useEffect(()=>{i(je());const w=setTimeout(()=>{i(je())},150);return()=>clearTimeout(w)},[]);const l=h.useCallback(()=>o(null),[]),u=h.useCallback(w=>{bt(w),i(!0),o(null)},[]),m=h.useCallback(async(w,p=.5,b=40)=>{e(!0),o(null);try{return await lt(w,p,b)}catch(T){const f=T instanceof Error?T.message:"Enhancement failed";throw o(f),T}finally{e(!1)}},[]),d=h.useCallback(async w=>{r(!0),o(null);try{return await wt(w)}catch(p){const b=p instanceof Error?p.message:"Background removal failed";throw o(b),p}finally{r(!1)}},[]);return{enhance:m,removeBg:d,isEnhancing:t,isRemovingBg:n,error:a,hasKey:s,setApiKey:u,clearError:l}}function vt({isOpen:t,onClose:e,onSubmit:n}){const r=y(u=>u.appLanguage),[a,o]=h.useState("");if(!t)return null;const s=u=>{u.preventDefault(),a.trim()&&(n(a.trim()),o(""),e())},l={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."}}[r];return c.jsxs("dialog",{className:"modal modal-open",children:[c.jsxs("div",{className:"modal-box",children:[c.jsx("h3",{className:"font-bold text-lg",children:l.title}),c.jsx("p",{className:"py-4 text-sm opacity-80",children:l.description}),c.jsxs("form",{onSubmit:s,children:[c.jsxs("div",{className:"form-control",children:[c.jsx("input",{type:"password",placeholder:l.placeholder,className:"input input-bordered w-full",value:a,onChange:u=>o(u.target.value),autoFocus:!0}),c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt",children:l.hint})})]}),c.jsxs("div",{className:"modal-action",children:[c.jsx("button",{type:"button",className:"btn btn-ghost",onClick:e,children:l.cancel}),c.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:l.submit})]})]})]}),c.jsx("form",{method:"dialog",className:"modal-backdrop",children:c.jsx("button",{onClick:e,children:"close"})})]})}function we({min:t,max:e,step:n,value:r,onChange:a,className:o="",disabled:s=!1}){const i=h.useRef(null),l=h.useRef(null),u=h.useRef(!1),[m,d]=h.useState(!1),w=(r-t)/(e-t)*100,p=h.useCallback(I=>{if(!i.current)return r;const L=i.current.getBoundingClientRect(),N=Math.max(0,Math.min(1,(I-L.left)/L.width)),R=e-t,C=t+N*R,B=Math.round(C/n)*n;return Math.max(t,Math.min(e,B))},[t,e,n,r]),b=h.useCallback(I=>{if(s)return;const L=I.touches[0];l.current={x:L.clientX,y:L.clientY,value:r,decided:!1},u.current=!1},[r,s]),T=h.useCallback(I=>{if(s||!l.current)return;const L=I.touches[0],N=Math.abs(L.clientX-l.current.x),R=Math.abs(L.clientY-l.current.y);if(!l.current.decided){if(N<8&&R<8)return;if(l.current.decided=!0,R>N){l.current=null;return}u.current=!0,d(!0)}if(u.current){const C=p(L.clientX);C!==r&&a(C)}},[s,p,a,r]),f=h.useCallback(I=>{if(l.current&&!l.current.decided){const L=I.changedTouches[0];if(L){const N=p(L.clientX);N!==r&&a(N)}}l.current=null,u.current=!1,d(!1)},[p,a,r]);h.useEffect(()=>{const I=i.current;if(!I)return;const L=N=>{u.current&&N.preventDefault()};return I.addEventListener("touchmove",L,{passive:!1}),()=>{I.removeEventListener("touchmove",L)}},[]);const E=h.useCallback(I=>{if(s)return;const L=p(I.clientX);a(L),d(!0);const N=C=>{const B=p(C.clientX);a(B)},R=()=>{d(!1),document.removeEventListener("mousemove",N),document.removeEventListener("mouseup",R)};document.addEventListener("mousemove",N),document.addEventListener("mouseup",R)},[s,p,a]),x=`calc(10px + (100% - 20px) * ${w/100})`;return c.jsxs("div",{ref:i,className:`relative h-10 flex items-center cursor-pointer overflow-visible ${s?"opacity-50 cursor-not-allowed":""}`,onTouchStart:b,onTouchMove:T,onTouchEnd:f,onMouseDown:E,children:[c.jsx("div",{className:"absolute h-2 bg-base-300 rounded-full inset-x-0"}),c.jsx("div",{className:`absolute h-2 rounded-full transition-colors ${o.includes("range-primary")?"bg-primary":o.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{left:0,width:x}}),c.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transition-transform ${m?"scale-110":""} ${o.includes("range-primary")?"border-primary":o.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:x,transform:"translateX(-50%)"}})]})}function kn(){const t=y(v=>v.appLanguage),e=y(v=>v.portrait),n=y(v=>v.setPortrait),r=y(v=>v.setPortraitZoom),a=y(v=>v.setPortraitPan),o=y(v=>v.setPortraitRawImage),s=y(v=>v.setPortraitBgRemoved),i=y(v=>v.setPortraitBgOpacity),l=y(v=>v.setPortraitBgBlur),u=y(v=>v.setPortraitEngravingIntensity),{enhance:m,removeBg:d,isEnhancing:w,isRemovingBg:p,error:b,hasKey:T,setApiKey:f}=En(),E=te(t),x=h.useRef(null),[I,L]=h.useState(!1),[N,R]=h.useState(!1),C=h.useRef(null),B=h.useRef(null),H=e.rawImage,V=e.bgRemovedImage,k=e.bgRemoved,U=e.bgOpacity,P=e.bgBlur,$=e.engravingIntensity;h.useEffect(()=>{e.original&&!e.rawImage&&o(e.original)},[e.original,e.rawImage,o]),h.useEffect(()=>()=>{C.current&&clearTimeout(C.current),B.current&&clearTimeout(B.current)},[]);const K=y(v=>v.voucherConfig.templateHue),X=h.useRef(K),G=h.useCallback(async v=>{if(!v.type.startsWith("image/"))return;const j=new FileReader;j.onload=async Y=>{var O;const M=(O=Y.target)==null?void 0:O.result,W=await ct(M);it(),o(W),n(W),r(1),a(0,0),s(!1,null),i(0),l(0),u(0)},j.readAsDataURL(v)},[n,o,r,a,s,i,l,u]),F=h.useCallback(v=>{v.preventDefault(),L(!1);const j=v.dataTransfer.files[0];j&&G(j)},[G]),oe=h.useCallback(v=>{v.preventDefault(),L(!0)},[]),ye=h.useCallback(v=>{v.preventDefault(),L(!1)},[]),fe=()=>{var v;(v=x.current)==null||v.click()},se=v=>{var Y;const j=(Y=v.target.files)==null?void 0:Y[0];j&&G(j)},q=h.useCallback(async(v,j,Y)=>{try{return await m(v,j,Y)}catch(M){return console.error("Enhancement failed:",M),v}},[m]),Z=h.useCallback(async v=>{try{const j=await d(v);return s(!0,j),j}catch(j){return console.error("Background removal failed:",j),v}},[d,s]),_=h.useCallback(async()=>{const v=y.getState(),j=v.portrait,Y=v.voucherConfig.templateHue;if(!j.rawImage)return;let M;j.bgRemoved&&j.bgRemovedImage?M=await Te(j.bgRemovedImage,j.rawImage,j.bgOpacity,j.bgBlur):M=j.rawImage,j.engravingIntensity>0&&(M=await q(M,j.engravingIntensity,Y)),n(M)},[q,n]),ie=h.useRef(!1);h.useEffect(()=>{e.rawImage&&!e.original&&!ie.current&&(ie.current=!0,setTimeout(()=>{_()},0)),e.rawImage||(ie.current=!1)},[e.rawImage,e.original,_]),h.useEffect(()=>{if(X.current===K)return;X.current=K;const v=y.getState().portrait;v.engravingIntensity>0&&v.rawImage&&(C.current&&clearTimeout(C.current),C.current=setTimeout(_,150))},[K,_]);const xe=async()=>{if(!H)return;if(!k&&!T){R(!0);return}if(!k){const j=await Z(H),Y=y.getState(),M=Y.portrait,W=Y.voucherConfig.templateHue;let O=await Te(j,H,M.bgOpacity,M.bgBlur);M.engravingIntensity>0&&(O=await q(O,M.engravingIntensity,W)),n(O)}else{s(!1,null);const j=y.getState(),Y=j.portrait.engravingIntensity,M=j.voucherConfig.templateHue;if(Y>0){const W=await q(H,Y,M);n(W)}else n(H)}},pe=v=>{u(v),C.current&&clearTimeout(C.current),H&&(C.current=setTimeout(_,150))},Ie=async v=>{if(f(v),!H)return;const j=await Z(H),Y=y.getState(),M=Y.portrait,W=Y.voucherConfig.templateHue;let O=await Te(j,H,M.bgOpacity,M.bgBlur);M.engravingIntensity>0&&(O=await q(O,M.engravingIntensity,W)),n(O)},Ce=v=>{i(v),B.current&&clearTimeout(B.current),!(!H||!V)&&(B.current=setTimeout(_,150))},De=v=>{l(v),B.current&&clearTimeout(B.current),!(!H||!V)&&(B.current=setTimeout(_,150))};return c.jsxs("div",{className:"space-y-4",children:[c.jsx("style",{children:`
2
2
  @keyframes sparkle1 {
3
3
  0%, 33%, 100% { opacity: 0.3; }
4
4
  16% { opacity: 1; }
@@ -11,6 +11,6 @@
11
11
  0%, 66%, 100% { opacity: 0.3; }
12
12
  83% { opacity: 1; }
13
13
  }
14
- `}),!e.original&&!e.rawImage?c.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${w?"border-primary bg-primary/10 pointer-events-none":I?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:K,onDragOver:oe,onDragLeave:ye,onClick:fe,children:[c.jsx("input",{ref:m,type:"file",accept:"image/*",className:"hidden",onChange:se}),w?c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),c.jsx("p",{className:"font-medium",children:t==="de"?"Hintergrund wird entfernt ...":"Removing background ..."})]}):c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),c.jsx("p",{className:"font-medium",children:j.form.portrait.upload}),c.jsx("p",{className:"text-sm text-base-content/60",children:j.form.portrait.dragDrop})]})]}):c.jsxs("div",{className:"flex flex-col space-y-4",children:[c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:j.form.portrait.zoom}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(e.zoom*100),"%"]})]}),c.jsx(we,{min:.5,max:2,step:.05,value:e.zoom,onChange:a,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsxs("span",{className:"label-text flex items-center gap-2",children:[t==="de"?"Farbanpassung":"Color adjustment",b&&c.jsx("span",{className:"loading loading-spinner loading-xs"})]}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(_*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:_,onChange:pe,className:"range range-secondary range-sm",disabled:b||!H})]})]}),Q?c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:t==="de"?"Hintergrund":"Background"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(Y*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:Y,onChange:Ce,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:t==="de"?"Unschärfe":"Blur"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(A*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:A,onChange:De,className:"range range-primary range-sm",disabled:Y===0})]})]}):c.jsx("div",{className:"flex justify-center",children:c.jsxs("button",{className:"btn btn-ghost btn gap-2 text-base-content/70",onClick:xe,disabled:w||!H,children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:[c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z",style:w?{animation:"sparkle1 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456z",style:w?{animation:"sparkle2 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z",style:w?{animation:"sparkle3 2.4s ease-in-out infinite"}:void 0})]}),w?t==="de"?"Hintergrund wird entfernt ...":"Removing background ...":t==="de"?"Hintergrund entfernen":"Remove background",!w&&!T&&c.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})}),v&&c.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"stroke-current shrink-0 h-5 w-5",fill:"none",viewBox:"0 0 24 24",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),c.jsx("span",{children:v})]})]}),c.jsx(vt,{isOpen:R,onClose:()=>S(!1),onSubmit:Ie})]})}function jn(){const t=x(i=>i.appLanguage),e=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 s=J(t),o=[1,5,10];return c.jsxs("div",{className:"space-y-4",children:[c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:s.form.voucher.billLanguage}),c.jsxs("div",{className:"join border border-base-300 rounded-lg shadow",children:[c.jsx("button",{className:`join-item btn btn-md ${e==="de"?"btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:s.form.voucher.billLanguageGerman}),c.jsx("button",{className:`join-item btn btn-md ${e==="en"?"btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:s.form.voucher.billLanguageEnglish})]})]})}),c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:s.form.voucher.hours}),c.jsx("div",{className:"join border border-base-300 rounded-lg shadow",children:o.map(i=>c.jsxs("button",{className:`join-item btn btn-md ${n===i?"btn-primary":"btn-ghost"}`,onClick:()=>r(i),children:[i,c.jsxs("span",{className:"hidden sm:inline",children:[" ",i===1?s.form.voucher.hourLabel:s.form.voucher.hoursLabel]})]},i))})]})}),!1]})}const Oe=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",Z=new Map;let Xe=!1;const kn=["/templates/classic/template.json","/templates/modern/template.json"],Ln="/templates/dev/";async function yt(t){try{const e=`${Oe}${t.startsWith("/")?t.slice(1):t}`,n=await fetch(e);if(!n.ok)return console.warn(`Failed to load template from ${e}: ${n.status}`),null;const a=await n.json();return a.assets=Sn(a.assets,t),a}catch(e){return console.warn(`Error loading template from ${t}:`,e),null}}function Sn(t,e){var r;const n=e.substring(0,e.lastIndexOf("/")),a=s=>{if(s)return s.startsWith("http")||s.startsWith("data:")?s:s.startsWith("/")?`${Oe}${s.slice(1)}`:`${Oe}${n.slice(1)}/${s}`};return{...t,background:a(t.background)||t.background,frontFrame:a(t.frontFrame),backFrame:a(t.backFrame),badges:t.badges?{...t.badges,variants:(r=t.badges.variants)==null?void 0:r.map(s=>({...s,image:a(s.image)||s.image}))}:void 0,decorations:t.decorations?Object.fromEntries(Object.entries(t.decorations).map(([s,o])=>[s,a(o)||o])):void 0}}async function _e(){if(Xe)return;const t=kn.map(async e=>{const n=await yt(e);n&&Z.set(n.id,n)});await Promise.all(t),Xe=!0}async function at(){return[]}function Rn(t){var s,o,i,l,u,h,p,b,w,v,T;const e=[],n=[];t.id||e.push({path:"id",message:"Template ID is required",severity:"error"}),t.name||e.push({path:"name",message:"Template name is required",severity:"error"}),t.version||e.push({path:"version",message:"Template version is required",severity:"error"}),(s=t.assets)!=null&&s.background||e.push({path:"assets.background",message:"Background asset is required",severity:"error"}),(!((o=t.schema)!=null&&o.fields)||t.schema.fields.length===0)&&e.push({path:"schema.fields",message:"At least one field is required",severity:"error"}),(i=t.layout)!=null&&i.dimensions||e.push({path:"layout.dimensions",message:"Layout dimensions are required",severity:"error"});const a=new Set;(u=(l=t.schema)==null?void 0:l.fields)==null||u.forEach((f,j)=>{f.id?a.has(f.id)?e.push({path:`schema.fields[${j}].id`,message:`Duplicate field ID: ${f.id}`,severity:"error"}):a.add(f.id):e.push({path:`schema.fields[${j}].id`,message:"Field ID is required",severity:"error"}),f.type||e.push({path:`schema.fields[${j}].type`,message:"Field type is required",severity:"error"})});const r=(f,j)=>{f.forEach((m,I)=>{"fieldId"in m&&m.fieldId&&(a.has(m.fieldId)||e.push({path:`layout.${j}.layers[${I}].fieldId`,message:`Referenced field not found: ${m.fieldId}`,severity:"error"}))})};return(p=(h=t.layout)==null?void 0:h.front)!=null&&p.layers&&r(t.layout.front.layers,"front"),(w=(b=t.layout)==null?void 0:b.back)!=null&&w.layers&&r(t.layout.back.layers,"back"),t.description||n.push({path:"description",message:"Template description is recommended",severity:"warning"}),(v=t.designer)!=null&&v.name||n.push({path:"designer.name",message:"Designer name is recommended",severity:"warning"}),(T=t.shop)!=null&&T.thumbnail||n.push({path:"shop.thumbnail",message:"Thumbnail is recommended for shop display",severity:"warning"}),{valid:e.length===0,errors:e,warnings:n}}const xt={async listTemplates(t){await _e(),await at();let e=Array.from(Z.values());return t!=null&&t.type&&(e=e.filter(n=>n.type===t.type)),t!=null&&t.status&&(e=e.filter(n=>n.status===t.status)),t!=null&&t.language&&(e=e.filter(n=>!n.schema.languages||n.schema.languages.includes(t.language))),e},async getTemplate(t){await _e(),await at();const e=Z.get(t);if(!e)throw new Error(`Template not found: ${t}`);return e},async validateTemplate(t){return Rn(t)},async loadDevTemplate(t){const e=await yt(`${Ln}${t}/template.json`);if(!e)throw new Error(`Dev template not found: ${t}`);return e.status="development",Z.set(e.id,e),e},watchDevTemplates(t){return()=>{}}};function Pn(t){Z.set(t.id,t)}function Nn(t){Z.delete(t)}function Cn(){Z.clear(),Xe=!1}async function Dn(t){return await _e(),Z.has(t)}function Bn(){return"classic-time-voucher"}let ve=xt;function An(t){ve=t}function Mn(){return ve}async function Hn(t){return ve.listTemplates(t)}async function qe(t){return ve.getTemplate(t)}async function Un(t){return ve.validateTemplate(t)}function Yn(t,e){const[n,a]=g.useState(t);return g.useEffect(()=>{const r=setTimeout(()=>a(t),e);return()=>clearTimeout(r)},[t,e]),n}function $n({onPortraitClick:t,onFileDrop:e}={}){const n=x(d=>d.appLanguage),a=x(d=>d.voucherConfig.language),r=x(d=>d.voucherConfig.hours),s=x(d=>d.voucherConfig.description),o=x(d=>d.voucherConfig.templateHue),i=x(d=>d.voucherConfig.templateId),l=x(d=>d.personalInfo),u=x(d=>d.portrait),h=x(d=>d.currentSide),p=x(d=>d.flipSide),b=x(d=>d.setPortraitPan),w=Yn(o,150),[v,T]=g.useState(null),f=J(n),j=g.useRef(null),m=g.useRef(null),I=g.useRef(null),[E,R]=g.useState(!1),[S,P]=g.useState(!1),[B,H]=g.useState(!1),[re,Q]=g.useState(!1),Y=g.useRef(null),A=g.useRef(null),_=g.useRef(!1),ee=g.useRef(0),z=(v==null?void 0:v.layout.dimensions.width)??3633,W=(v==null?void 0:v.layout.dimensions.height)??1920,K=u.useEnhanced&&u.enhanced?u.enhanced:u.original||u.rawImage,oe=Ke(a,r,s),[ye,fe]=g.useState(!0);g.useEffect(()=>{let d=!0;fe(!0);async function L(){try{Se();const N=await qe(i);d&&(T(N),fe(!1))}catch(N){console.error("[BillPreview] Failed to load template:",N),d&&(T(null),fe(!1))}}return L(),()=>{d=!1}},[i]);const se=g.useCallback(async d=>new Promise((L,N)=>{const C=new Image;C.onload=()=>L(C),C.onerror=N,C.src=d}),[]);g.useEffect(()=>{if(!j.current||!v)return;let d=!1;return(async()=>{const N={name:l.name||"",hours:r,email:l.email||"",phone:l.phone||"",description:oe};let C=null;K&&(C=await se(K)),!(d||!j.current)&&await Le(j.current,v,N,"front",{scale:.5,hue:w,language:a,portraitImage:C,portraitTransform:{scale:u.zoom,offsetX:u.panX,offsetY:u.panY}})})(),()=>{d=!0}},[v,K,l,oe,u.zoom,u.panX,u.panY,w,r,a,se]),g.useEffect(()=>{if(!m.current||!v)return;let d=!1;return(async()=>{const N={name:l.name||"",hours:r,email:l.email||"",phone:l.phone||"",description:oe};let C=null;K&&(C=await se(K)),!(d||!m.current)&&await Le(m.current,v,N,"back",{scale:.5,hue:w,language:a,portraitImage:C,portraitTransform:{scale:u.zoom,offsetX:u.panX,offsetY:u.panY}})})(),()=>{d=!0}},[v,K,l,oe,u.zoom,u.panX,u.panY,w,r,a,se]);const V=()=>{R(!E),p()};g.useEffect(()=>{R(h==="back")},[h]);const q=g.useCallback((d,L)=>{if(!I.current||h!=="front")return!1;const N=I.current.getBoundingClientRect(),C=N.width/z,ce=N.height/W,te=(d-N.left)/C,ne=(L-N.top)/ce;if(!v)return!1;const G=v.layout.front.layers.find(Me=>Me.type==="field"&&"fieldId"in Me&&Me.fieldId==="portrait");if(!G||!("position"in G)||!("size"in G))return!1;const Be=G.position.x,Ae=G.position.y,le=G.size,Nt=(le==null?void 0:le.radiusX)||500,Ct=(le==null?void 0:le.radiusY)||500,Ge=(te-Be)/Nt,Ze=(ne-Ae)/Ct;return Ge*Ge+Ze*Ze<=1},[h,z,W,v]),$=5,ie=g.useCallback((d,L)=>{u.original&&(P(!0),Y.current={x:d,y:L,panX:u.panX,panY:u.panY})},[u.original,u.panX,u.panY]),xe=g.useCallback((d,L)=>{if(!S||!Y.current||!I.current)return;const N=performance.now();if(N-ee.current<33)return;ee.current=N;const C=I.current.getBoundingClientRect(),te=4/Math.max(C.width,C.height)*u.zoom,ne=(d-Y.current.x)*te,G=(L-Y.current.y)*te,Be=Math.max(-1,Math.min(1,Y.current.panX+ne)),Ae=Math.max(-1,Math.min(1,Y.current.panY+G));b(Be,Ae)},[S,b,u.zoom]),pe=g.useCallback(()=>{P(!1),Y.current=null,A.current=null},[]),Ie=g.useCallback(()=>{t&&t()},[t]),Ce=d=>{q(d.clientX,d.clientY)&&(d.preventDefault(),A.current={x:d.clientX,y:d.clientY},_.current=!1)},De=d=>{if(H(q(d.clientX,d.clientY)),A.current&&u.original){const L=d.clientX-A.current.x,N=d.clientY-A.current.y;Math.sqrt(L*L+N*N)>$&&!S&&(_.current=!0,ie(A.current.x,A.current.y))}S&&xe(d.clientX,d.clientY)},y=d=>{A.current&&!_.current&&q(d.clientX,d.clientY)&&Ie(),pe()},k=()=>{pe(),H(!1)},M=d=>{if(d.touches.length===1){const L=d.touches[0];q(L.clientX,L.clientY)&&(A.current={x:L.clientX,y:L.clientY},_.current=!1)}},D=d=>{if(d.touches.length===1&&A.current&&u.original){const L=d.touches[0],N=L.clientX-A.current.x,C=L.clientY-A.current.y;Math.sqrt(N*N+C*C)>$&&!S&&(_.current=!0,ie(A.current.x,A.current.y)),S&&xe(L.clientX,L.clientY)}},O=()=>{A.current&&!_.current&&q(A.current.x,A.current.y)&&Ie(),pe()},U=g.useRef(!1);g.useEffect(()=>{U.current=S},[S]),g.useEffect(()=>{const d=I.current;if(!d)return;const L=N=>{U.current&&N.preventDefault()};return d.addEventListener("touchmove",L,{passive:!1}),()=>{d.removeEventListener("touchmove",L)}},[]);const Rt=h==="front"&&u.original,Pt=z/W;return c.jsxs("div",{className:"space-y-2",children:[c.jsxs("div",{className:"flex justify-between items-center mb-6",children:[c.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[c.jsx("button",{className:`join-item btn btn-md ${h==="front"?"btn-primary":"btn-ghost"}`,onClick:()=>h!=="front"&&V(),children:f.preview.front}),c.jsx("button",{className:`join-item btn btn-md ${h==="back"?"btn-primary":"btn-ghost"}`,onClick:()=>h!=="back"&&V(),children:f.preview.back})]}),c.jsxs("button",{className:"btn btn-ghost btn-md",onClick:V,children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),c.jsx("span",{className:"hidden sm:inline",children:f.preview.flip})]})]}),c.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:Pt,perspective:"1500px"},children:[ye&&c.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),c.jsxs("div",{ref:I,className:`relative w-full h-full shadow-lg ${B&&Rt?S?"cursor-grabbing":"cursor-grab":""} ${ye?"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:E?"rotateY(180deg)":"rotateY(0deg)"},onMouseDown:Ce,onMouseMove:De,onMouseUp:y,onMouseLeave:k,onTouchStart:M,onTouchMove:D,onTouchEnd:O,onDragOver:d=>{d.preventDefault(),h==="front"&&Q(!0)},onDragLeave:d=>{d.preventDefault(),Q(!1)},onDrop:d=>{if(d.preventDefault(),Q(!1),h==="front"&&e){const L=d.dataTransfer.files[0];L&&L.type.startsWith("image/")&&e(L)}},children:[c.jsx("canvas",{ref:j,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),c.jsx("canvas",{ref:m,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),h==="front"&&!u.original&&v&&(()=>{const d=v.layout.front.layers.find(ne=>ne.type==="field"&&"fieldId"in ne&&ne.fieldId==="portrait");if(!d||!("position"in d)||!("size"in d))return null;const L=d.position.x,N=d.position.y,C=d.size,ce=(C==null?void 0:C.radiusX)||500,te=(C==null?void 0:C.radiusY)||500;return c.jsx("div",{className:`absolute flex flex-col items-center justify-center transition-colors duration-300 ease-in-out pointer-events-none ${re?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(L-ce)/z*100}%`,top:`${(N-te)/W*100}%`,width:`${ce*2/z*100}%`,height:`${te*2/W*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},children:c.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 flex flex-col items-center gap-0.5 sm:gap-1 h-auto py-1.5 px-2.5 sm:py-3 sm:px-4 bg-base-100/20 hover:bg-base-100/30",children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-7 h-6 sm:w-10 sm:h-9 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"8",r:"4"}),c.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),c.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
14
+ `}),!e.original&&!e.rawImage?c.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${p?"border-primary bg-primary/10 pointer-events-none":I?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:F,onDragOver:oe,onDragLeave:ye,onClick:fe,children:[c.jsx("input",{ref:x,type:"file",accept:"image/*",className:"hidden",onChange:se}),p?c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),c.jsx("p",{className:"font-medium",children:t==="de"?"Hintergrund wird entfernt ...":"Removing background ..."})]}):c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),c.jsx("p",{className:"font-medium",children:E.form.portrait.upload}),c.jsx("p",{className:"text-sm text-base-content/60",children:E.form.portrait.dragDrop})]})]}):c.jsxs("div",{className:"flex flex-col space-y-4",children:[c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:E.form.portrait.zoom}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(e.zoom*100),"%"]})]}),c.jsx(we,{min:.5,max:2,step:.05,value:e.zoom,onChange:r,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsxs("span",{className:"label-text flex items-center gap-2",children:[t==="de"?"Farbanpassung":"Color adjustment",w&&c.jsx("span",{className:"loading loading-spinner loading-xs"})]}),c.jsxs("span",{className:"label-text-alt",children:[Math.round($*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:$,onChange:pe,className:"range range-secondary range-sm",disabled:w||!H})]})]}),k?c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:t==="de"?"Hintergrund":"Background"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(U*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:U,onChange:Ce,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:t==="de"?"Unschärfe":"Blur"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(P*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:P,onChange:De,className:"range range-primary range-sm",disabled:U===0})]})]}):c.jsx("div",{className:"flex justify-center",children:c.jsxs("button",{className:"btn btn-ghost btn gap-2 text-base-content/70",onClick:xe,disabled:p||!H,children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:[c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z",style:p?{animation:"sparkle1 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456z",style:p?{animation:"sparkle2 2.4s ease-in-out infinite"}:void 0}),c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z",style:p?{animation:"sparkle3 2.4s ease-in-out infinite"}:void 0})]}),p?t==="de"?"Hintergrund wird entfernt ...":"Removing background ...":t==="de"?"Hintergrund entfernen":"Remove background",!p&&!T&&c.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})}),b&&c.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"stroke-current shrink-0 h-5 w-5",fill:"none",viewBox:"0 0 24 24",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),c.jsx("span",{children:b})]})]}),c.jsx(vt,{isOpen:N,onClose:()=>R(!1),onSubmit:Ie})]})}function jn(){const t=y(i=>i.appLanguage),e=y(i=>i.voucherConfig.language),n=y(i=>i.voucherConfig.hours);y(i=>i.voucherConfig.templateHue);const r=y(i=>i.setBillLanguage),a=y(i=>i.setHours);y(i=>i.setTemplateHue);const o=te(t),s=[1,5,10];return c.jsxs("div",{className:"space-y-4",children:[c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:o.form.voucher.billLanguage}),c.jsxs("div",{className:"join border border-base-300 rounded-lg shadow",children:[c.jsx("button",{className:`join-item btn btn-md ${e==="de"?"btn-primary":"btn-ghost"}`,onClick:()=>r("de"),children:o.form.voucher.billLanguageGerman}),c.jsx("button",{className:`join-item btn btn-md ${e==="en"?"btn-primary":"btn-ghost"}`,onClick:()=>r("en"),children:o.form.voucher.billLanguageEnglish})]})]})}),c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:o.form.voucher.hours}),c.jsx("div",{className:"join border border-base-300 rounded-lg shadow",children:s.map(i=>c.jsxs("button",{className:`join-item btn btn-md ${n===i?"btn-primary":"btn-ghost"}`,onClick:()=>a(i),children:[i,c.jsxs("span",{className:"hidden sm:inline",children:[" ",i===1?o.form.voucher.hourLabel:o.form.voucher.hoursLabel]})]},i))})]})}),!1]})}const Oe=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ge&&ge.tagName.toUpperCase()==="SCRIPT"&&ge.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",Q=new Map;let Xe=!1;const Ln=["/templates/classic/template.json","/templates/modern/template.json"],Sn="/templates/dev/";async function yt(t){try{const e=`${Oe}${t.startsWith("/")?t.slice(1):t}`,n=await fetch(e);if(!n.ok)return console.warn(`Failed to load template from ${e}: ${n.status}`),null;const r=await n.json();return r.assets=Rn(r.assets,t),r}catch(e){return console.warn(`Error loading template from ${t}:`,e),null}}function Rn(t,e){var a;const n=e.substring(0,e.lastIndexOf("/")),r=o=>{if(o)return o.startsWith("http")||o.startsWith("data:")?o:o.startsWith("/")?`${Oe}${o.slice(1)}`:`${Oe}${n.slice(1)}/${o}`};return{...t,background:r(t.background)||t.background,front:r(t.front),back:r(t.back),frontFrame:r(t.frontFrame),backFrame:r(t.backFrame),badges:t.badges?{...t.badges,variants:(a=t.badges.variants)==null?void 0:a.map(o=>({...o,image:r(o.image)||o.image}))}:void 0,decorations:t.decorations?Object.fromEntries(Object.entries(t.decorations).map(([o,s])=>[o,r(s)||s])):void 0}}async function _e(){if(Xe)return;const t=Ln.map(async e=>{const n=await yt(e);n&&Q.set(n.id,n)});await Promise.all(t),Xe=!0}async function rt(){return[]}function Pn(t){var o,s,i,l,u,m,d,w,p,b,T;const e=[],n=[];t.id||e.push({path:"id",message:"Template ID is required",severity:"error"}),t.name||e.push({path:"name",message:"Template name is required",severity:"error"}),t.version||e.push({path:"version",message:"Template version is required",severity:"error"}),(o=t.assets)!=null&&o.background||e.push({path:"assets.background",message:"Background asset is required",severity:"error"}),(!((s=t.schema)!=null&&s.fields)||t.schema.fields.length===0)&&e.push({path:"schema.fields",message:"At least one field is required",severity:"error"}),(i=t.layout)!=null&&i.dimensions||e.push({path:"layout.dimensions",message:"Layout dimensions are required",severity:"error"});const r=new Set;(u=(l=t.schema)==null?void 0:l.fields)==null||u.forEach((f,E)=>{f.id?r.has(f.id)?e.push({path:`schema.fields[${E}].id`,message:`Duplicate field ID: ${f.id}`,severity:"error"}):r.add(f.id):e.push({path:`schema.fields[${E}].id`,message:"Field ID is required",severity:"error"}),f.type||e.push({path:`schema.fields[${E}].type`,message:"Field type is required",severity:"error"})});const a=(f,E)=>{f.forEach((x,I)=>{"fieldId"in x&&x.fieldId&&(r.has(x.fieldId)||e.push({path:`layout.${E}.layers[${I}].fieldId`,message:`Referenced field not found: ${x.fieldId}`,severity:"error"}))})};return(d=(m=t.layout)==null?void 0:m.front)!=null&&d.layers&&a(t.layout.front.layers,"front"),(p=(w=t.layout)==null?void 0:w.back)!=null&&p.layers&&a(t.layout.back.layers,"back"),t.description||n.push({path:"description",message:"Template description is recommended",severity:"warning"}),(b=t.designer)!=null&&b.name||n.push({path:"designer.name",message:"Designer name is recommended",severity:"warning"}),(T=t.shop)!=null&&T.thumbnail||n.push({path:"shop.thumbnail",message:"Thumbnail is recommended for shop display",severity:"warning"}),{valid:e.length===0,errors:e,warnings:n}}const xt={async listTemplates(t){await _e(),await rt();let e=Array.from(Q.values());return t!=null&&t.type&&(e=e.filter(n=>n.type===t.type)),t!=null&&t.status&&(e=e.filter(n=>n.status===t.status)),t!=null&&t.language&&(e=e.filter(n=>!n.schema.languages||n.schema.languages.includes(t.language))),e},async getTemplate(t){await _e(),await rt();const e=Q.get(t);if(!e)throw new Error(`Template not found: ${t}`);return e},async validateTemplate(t){return Pn(t)},async loadDevTemplate(t){const e=await yt(`${Sn}${t}/template.json`);if(!e)throw new Error(`Dev template not found: ${t}`);return e.status="development",Q.set(e.id,e),e},watchDevTemplates(t){return()=>{}}};function Nn(t){Q.set(t.id,t)}function Cn(t){Q.delete(t)}function Dn(){Q.clear(),Xe=!1}async function Bn(t){return await _e(),Q.has(t)}function An(){return"classic-time-voucher"}let ve=xt;function Mn(t){ve=t}function Hn(){return ve}async function Un(t){return ve.listTemplates(t)}async function Ge(t){return ve.getTemplate(t)}async function Yn(t){return ve.validateTemplate(t)}function $n(t,e){const[n,r]=h.useState(t);return h.useEffect(()=>{const a=setTimeout(()=>r(t),e);return()=>clearTimeout(a)},[t,e]),n}function On({onPortraitClick:t,onFileDrop:e}={}){const n=y(g=>g.appLanguage),r=y(g=>g.voucherConfig.language),a=y(g=>g.voucherConfig.hours),o=y(g=>g.voucherConfig.description),s=y(g=>g.voucherConfig.templateHue),i=y(g=>g.voucherConfig.templateId),l=y(g=>g.personalInfo),u=y(g=>g.portrait),m=y(g=>g.currentSide),d=y(g=>g.flipSide),w=y(g=>g.setPortraitPan),p=$n(s,150),[b,T]=h.useState(null),f=te(n),E=h.useRef(null),x=h.useRef(null),I=h.useRef(null),[L,N]=h.useState(!1),[R,C]=h.useState(!1),[B,H]=h.useState(!1),[V,k]=h.useState(!1),U=h.useRef(null),P=h.useRef(null),$=h.useRef(!1),K=h.useRef(0),X=(b==null?void 0:b.layout.dimensions.width)??3633,G=(b==null?void 0:b.layout.dimensions.height)??1920,F=u.useEnhanced&&u.enhanced?u.enhanced:u.original||u.rawImage,oe=Ke(r,a,o),[ye,fe]=h.useState(!0);h.useEffect(()=>{let g=!0;fe(!0);async function S(){try{Se();const D=await Ge(i);g&&(T(D),fe(!1))}catch(D){console.error("[BillPreview] Failed to load template:",D),g&&(T(null),fe(!1))}}return S(),()=>{g=!1}},[i]);const se=h.useCallback(async g=>new Promise((S,D)=>{const A=new Image;A.onload=()=>S(A),A.onerror=D,A.src=g}),[]);h.useEffect(()=>{if(!E.current||!b)return;let g=!1;return(async()=>{const D={name:l.name||"",hours:a,email:l.email||"",phone:l.phone||"",description:oe};let A=null;F&&(A=await se(F)),!(g||!E.current)&&await Le(E.current,b,D,"front",{scale:.5,hue:p,language:r,portraitImage:A,portraitTransform:{scale:u.zoom,offsetX:u.panX,offsetY:u.panY}})})(),()=>{g=!0}},[b,F,l,oe,u.zoom,u.panX,u.panY,p,a,r,se]),h.useEffect(()=>{if(!x.current||!b)return;let g=!1;return(async()=>{const D={name:l.name||"",hours:a,email:l.email||"",phone:l.phone||"",description:oe};let A=null;F&&(A=await se(F)),!(g||!x.current)&&await Le(x.current,b,D,"back",{scale:.5,hue:p,language:r,portraitImage:A,portraitTransform:{scale:u.zoom,offsetX:u.panX,offsetY:u.panY}})})(),()=>{g=!0}},[b,F,l,oe,u.zoom,u.panX,u.panY,p,a,r,se]);const q=()=>{N(!L),d()};h.useEffect(()=>{N(m==="back")},[m]);const Z=h.useCallback((g,S)=>{if(!I.current||m!=="front")return!1;const D=I.current.getBoundingClientRect(),A=D.width/X,ce=D.height/G,ne=(g-D.left)/A,re=(S-D.top)/ce;if(!b)return!1;const J=b.layout.front.layers.find(Me=>Me.type==="field"&&"fieldId"in Me&&Me.fieldId==="portrait");if(!J||!("position"in J)||!("size"in J))return!1;const Be=J.position.x,Ae=J.position.y,le=J.size,Nt=(le==null?void 0:le.radiusX)||500,Ct=(le==null?void 0:le.radiusY)||500,qe=(ne-Be)/Nt,Fe=(re-Ae)/Ct;return qe*qe+Fe*Fe<=1},[m,X,G,b]),_=5,ie=h.useCallback((g,S)=>{u.original&&(C(!0),U.current={x:g,y:S,panX:u.panX,panY:u.panY})},[u.original,u.panX,u.panY]),xe=h.useCallback((g,S)=>{if(!R||!U.current||!I.current)return;const D=performance.now();if(D-K.current<33)return;K.current=D;const A=I.current.getBoundingClientRect(),ne=4/Math.max(A.width,A.height)*u.zoom,re=(g-U.current.x)*ne,J=(S-U.current.y)*ne,Be=Math.max(-1,Math.min(1,U.current.panX+re)),Ae=Math.max(-1,Math.min(1,U.current.panY+J));w(Be,Ae)},[R,w,u.zoom]),pe=h.useCallback(()=>{C(!1),U.current=null,P.current=null},[]),Ie=h.useCallback(()=>{t&&t()},[t]),Ce=g=>{Z(g.clientX,g.clientY)&&(g.preventDefault(),P.current={x:g.clientX,y:g.clientY},$.current=!1)},De=g=>{if(H(Z(g.clientX,g.clientY)),P.current&&u.original){const S=g.clientX-P.current.x,D=g.clientY-P.current.y;Math.sqrt(S*S+D*D)>_&&!R&&($.current=!0,ie(P.current.x,P.current.y))}R&&xe(g.clientX,g.clientY)},v=g=>{P.current&&!$.current&&Z(g.clientX,g.clientY)&&Ie(),pe()},j=()=>{pe(),H(!1)},Y=g=>{if(g.touches.length===1){const S=g.touches[0];Z(S.clientX,S.clientY)&&(P.current={x:S.clientX,y:S.clientY},$.current=!1)}},M=g=>{if(g.touches.length===1&&P.current&&u.original){const S=g.touches[0],D=S.clientX-P.current.x,A=S.clientY-P.current.y;Math.sqrt(D*D+A*A)>_&&!R&&($.current=!0,ie(P.current.x,P.current.y)),R&&xe(S.clientX,S.clientY)}},W=()=>{P.current&&!$.current&&Z(P.current.x,P.current.y)&&Ie(),pe()},O=h.useRef(!1);h.useEffect(()=>{O.current=R},[R]),h.useEffect(()=>{const g=I.current;if(!g)return;const S=D=>{O.current&&D.preventDefault()};return g.addEventListener("touchmove",S,{passive:!1}),()=>{g.removeEventListener("touchmove",S)}},[]);const Rt=m==="front"&&u.original,Pt=X/G;return c.jsxs("div",{className:"space-y-2",children:[c.jsxs("div",{className:"flex justify-between items-center mb-6",children:[c.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[c.jsx("button",{className:`join-item btn btn-md ${m==="front"?"btn-primary":"btn-ghost"}`,onClick:()=>m!=="front"&&q(),children:f.preview.front}),c.jsx("button",{className:`join-item btn btn-md ${m==="back"?"btn-primary":"btn-ghost"}`,onClick:()=>m!=="back"&&q(),children:f.preview.back})]}),c.jsxs("button",{className:"btn btn-ghost btn-md",onClick:q,children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),c.jsx("span",{className:"hidden sm:inline",children:f.preview.flip})]})]}),c.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:Pt,perspective:"1500px"},children:[ye&&c.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),c.jsxs("div",{ref:I,className:`relative w-full h-full shadow-lg ${B&&Rt?R?"cursor-grabbing":"cursor-grab":""} ${ye?"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:L?"rotateY(180deg)":"rotateY(0deg)"},onMouseDown:Ce,onMouseMove:De,onMouseUp:v,onMouseLeave:j,onTouchStart:Y,onTouchMove:M,onTouchEnd:W,onDragOver:g=>{g.preventDefault(),m==="front"&&k(!0)},onDragLeave:g=>{g.preventDefault(),k(!1)},onDrop:g=>{if(g.preventDefault(),k(!1),m==="front"&&e){const S=g.dataTransfer.files[0];S&&S.type.startsWith("image/")&&e(S)}},children:[c.jsx("canvas",{ref:E,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),c.jsx("canvas",{ref:x,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),m==="front"&&!u.original&&b&&(()=>{const g=b.layout.front.layers.find(re=>re.type==="field"&&"fieldId"in re&&re.fieldId==="portrait");if(!g||!("position"in g)||!("size"in g))return null;const S=g.position.x,D=g.position.y,A=g.size,ce=(A==null?void 0:A.radiusX)||500,ne=(A==null?void 0:A.radiusY)||500;return c.jsx("div",{className:`absolute flex flex-col items-center justify-center transition-colors duration-300 ease-in-out pointer-events-none ${V?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(S-ce)/X*100}%`,top:`${(D-ne)/G*100}%`,width:`${ce*2/X*100}%`,height:`${ne*2/G*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},children:c.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 flex flex-col items-center gap-0.5 sm:gap-1 h-auto py-1.5 px-2.5 sm:py-3 sm:px-4 bg-base-100/20 hover:bg-base-100/30",children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-7 h-6 sm:w-10 sm:h-9 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"8",r:"4"}),c.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),c.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
15
15
  hochladen`:`Upload
16
- photo`})]})})})()]})]})]})}function On(){const t=g.useRef(null),e=g.useRef(null);return{frontCanvasRef:t,backCanvasRef:e}}const We=3,It=600,rt=Math.round(We/25.4*It);async function ot(t){return new Promise((e,n)=>{const a=new Image;a.onload=()=>e(a),a.onerror=n,a.src=t})}function st(t,e){const n=t.width,a=t.height,r=n+e*2,s=a+e*2,o=document.createElement("canvas");o.width=r,o.height=s;const i=o.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return i.drawImage(t,e,e),i.drawImage(t,0,0,n,1,e,0,n,e),i.drawImage(t,0,a-1,n,1,e,a+e,n,e),i.drawImage(t,0,0,1,a,0,e,e,a),i.drawImage(t,n-1,0,1,a,n+e,e,e,a),i.drawImage(t,0,0,1,1,0,0,e,e),i.drawImage(t,n-1,0,1,1,n+e,0,e,e),i.drawImage(t,0,a-1,1,1,0,a+e,e,e),i.drawImage(t,n-1,a-1,1,1,n+e,a+e,e,e),o}async function Tt(t){const{frontImageDataUrl:e,backImageDataUrl:n,templateWidth:a,templateHeight:r}=t,[s,o]=await Promise.all([ot(e),ot(n)]),i=st(s,rt),l=st(o,rt),u=i.toDataURL("image/jpeg",.95),h=l.toDataURL("image/jpeg",.95),p=j=>j/It*25.4,b=p(a),w=p(r),v=b+We*2,T=w+We*2,f=new Bt.jsPDF({orientation:v>T?"landscape":"portrait",unit:"mm",format:[v,T]});return f.addImage(u,"JPEG",0,0,v,T),f.addPage([v,T]),f.addImage(h,"JPEG",0,0,v,T),f.output("blob")}function Et(t,e){const n=URL.createObjectURL(t),a=document.createElement("a");a.href=n,a.download=e,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}async function jt(t){const e=await Tt(t);Et(e,t.filename)}async function Xn(t){return new Promise((e,n)=>{const a=new Image;a.onload=()=>e(a),a.onerror=n,a.src=t})}function _n(){const t=x(m=>m.appLanguage),e=x(m=>m.voucherConfig.language),n=x(m=>m.voucherConfig.hours),a=x(m=>m.voucherConfig.description),r=x(m=>m.voucherConfig.templateHue),s=x(m=>m.voucherConfig.templateId),o=x(m=>m.personalInfo),i=x(m=>m.portrait),l=x(m=>m.isExporting),u=x(m=>m.setIsExporting),h=J(t),[p,b]=g.useState(null);g.useEffect(()=>{async function m(){try{const E=await qe(s||"classic-time-voucher");b(E)}catch(I){console.error("[ExportButton] Failed to load template:",I)}}m()},[s]);const w=i.useEnhanced&&i.enhanced?i.enhanced:i.original||i.rawImage,v=Ke(e,n,a),T=i.original!==null||i.rawImage!==null,f=o.name.trim().length>0&&o.email.trim().length>0&&o.phone.trim().length>0&&T&&p!==null,j=async()=>{if(!(!f||l||!p)){u(!0);try{let m=null;w&&(m=await Xn(w));const I={name:o.name,hours:n,email:o.email,phone:o.phone,description:v},E={scale:1,hue:r,language:e,portraitImage:m,portraitTransform:{scale:i.zoom,offsetX:i.panX,offsetY:i.panY}},[R,S]=await Promise.all([$e(p,I,"front",E),$e(p,I,"back",E)]),P=`zeitgutschein-${n}h-${o.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await jt({frontImageDataUrl:R,backImageDataUrl:S,templateWidth:p.layout.dimensions.width,templateHeight:p.layout.dimensions.height,filename:P})}catch(m){console.error("PDF export failed:",m)}finally{u(!1)}}};return c.jsxs("button",{className:`btn btn-primary w-full btn-md ${f?"":"btn-disabled"}`,onClick:j,disabled:!f,"aria-busy":l,children:[l?c.jsx("span",{className:"loading loading-spinner loading-sm"}):c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),h.export.button]})}function kt(){const t=x(a=>a.appLanguage),e=x(a=>a.setAppLanguage),n=a=>{e(a)};return c.jsxs("div",{className:"join",children:[c.jsx("button",{className:`join-item btn btn-sm ${t==="de"?"btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),c.jsx("button",{className:`join-item btn btn-sm ${t==="en"?"btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Wn(){const t=x(n=>n.appLanguage),e=J(t);return c.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg shrink-0",children:[c.jsx("div",{className:"navbar-start",children:c.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:e.header.title})}),c.jsx("div",{className:"navbar-center hidden sm:flex",children:c.jsx("span",{className:"text-sm opacity-80",children:e.header.subtitle})}),c.jsx("div",{className:"navbar-end",children:c.jsx(kt,{})})]})}const Lt=3633,St=1920;function Vn(t,e){return{front:"",back:"",width:Lt,height:St}}const Ne={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},zn=Ne,Kn=Ne;function qn(t){return Ne}exports.ApiKeyModal=vt;exports.BillPreview=$n;exports.ExportButton=_n;exports.Header=Wn;exports.LAYOUT_HDPI=zn;exports.LAYOUT_LDPI=Kn;exports.LanguageToggle=kt;exports.PersonalInfoForm=hn;exports.PortraitUpload=En;exports.TEMPLATE_HEIGHT=St;exports.TEMPLATE_LAYOUT=Ne;exports.TEMPLATE_WIDTH=Lt;exports.TouchSlider=we;exports.VoucherConfig=jn;exports.applyEngravingEffect=lt;exports.applyHueShift=dt;exports.clearImageCache=it;exports.clearRendererCache=Se;exports.clearTemplateCache=Cn;exports.compositeWithBackground=Te;exports.downloadBlob=Et;exports.enhancePortrait=In;exports.exportBillAsPdfV2=jt;exports.formatDescription=Ke;exports.generateBillPdfV2=Tt;exports.getApiKey=Pe;exports.getDefaultTemplateId=Bn;exports.getLayout=qn;exports.getRemoveBackgroundEndpoint=bn;exports.getTemplate=Vn;exports.getTemplateByIdV2=qe;exports.getTemplateProvider=Mn;exports.hasApiKey=ke;exports.hasCustomEndpoint=wn;exports.hasTemplate=Dn;exports.initializeBillStore=sn;exports.listTemplatesV2=Hn;exports.registerTemplate=Pn;exports.removeBackground=wt;exports.renderTemplate=Le;exports.renderTemplateToDataUrl=$e;exports.resizeImage=ct;exports.resizeImageForStorage=Mt;exports.setApiKey=bt;exports.setRemoveBackgroundEndpoint=pn;exports.setTemplateProvider=An;exports.t=J;exports.templateProviderV2=xt;exports.unregisterTemplate=Nn;exports.useBillCanvasRefs=On;exports.useBillStore=x;exports.validateTemplate=Un;
16
+ photo`})]})})})()]})]})]})}function Xn(){const t=h.useRef(null),e=h.useRef(null);return{frontCanvasRef:t,backCanvasRef:e}}const We=3,It=600,at=Math.round(We/25.4*It);async function ot(t){return new Promise((e,n)=>{const r=new Image;r.onload=()=>e(r),r.onerror=n,r.src=t})}function st(t,e){const n=t.width,r=t.height,a=n+e*2,o=r+e*2,s=document.createElement("canvas");s.width=a,s.height=o;const i=s.getContext("2d");if(!i)throw new Error("Failed to get canvas context");return i.drawImage(t,e,e),i.drawImage(t,0,0,n,1,e,0,n,e),i.drawImage(t,0,r-1,n,1,e,r+e,n,e),i.drawImage(t,0,0,1,r,0,e,e,r),i.drawImage(t,n-1,0,1,r,n+e,e,e,r),i.drawImage(t,0,0,1,1,0,0,e,e),i.drawImage(t,n-1,0,1,1,n+e,0,e,e),i.drawImage(t,0,r-1,1,1,0,r+e,e,e),i.drawImage(t,n-1,r-1,1,1,n+e,r+e,e,e),s}async function Tt(t){const{frontImageDataUrl:e,backImageDataUrl:n,templateWidth:r,templateHeight:a}=t,[o,s]=await Promise.all([ot(e),ot(n)]),i=st(o,at),l=st(s,at),u=i.toDataURL("image/jpeg",.95),m=l.toDataURL("image/jpeg",.95),d=E=>E/It*25.4,w=d(r),p=d(a),b=w+We*2,T=p+We*2,f=new Bt.jsPDF({orientation:b>T?"landscape":"portrait",unit:"mm",format:[b,T]});return f.addImage(u,"JPEG",0,0,b,T),f.addPage([b,T]),f.addImage(m,"JPEG",0,0,b,T),f.output("blob")}function Et(t,e){const n=URL.createObjectURL(t),r=document.createElement("a");r.href=n,r.download=e,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}async function kt(t){const e=await Tt(t);Et(e,t.filename)}async function _n(t){return new Promise((e,n)=>{const r=new Image;r.onload=()=>e(r),r.onerror=n,r.src=t})}function Wn(){var V;const t=y(k=>k.appLanguage),e=y(k=>k.voucherConfig.language),n=y(k=>k.voucherConfig.hours),r=y(k=>k.voucherConfig.description),a=y(k=>k.voucherConfig.templateHue),o=y(k=>k.voucherConfig.templateId),s=y(k=>k.personalInfo),i=y(k=>k.portrait),l=y(k=>k.isExporting),u=y(k=>k.setIsExporting),m=te(t),[d,w]=h.useState(null),[p,b]=h.useState(!0);h.useEffect(()=>{let k=!1;b(!0);async function U(){try{const $=await Ge(o||"classic-time-voucher");k||(w($),b(!1))}catch(P){console.error("[ExportButton] Failed to load template:",P),k||b(!1)}}return U(),()=>{k=!0}},[o]);const T=i.useEnhanced&&i.enhanced?i.enhanced:i.original||i.rawImage,f=Ke(e,n,r),E=(V=d==null?void 0:d.features)!=null&&V.portraitEditing?Object.values(d.features.portraitEditing).some(k=>k===!0):!0,x=k=>{var P;if(!((P=d==null?void 0:d.schema)!=null&&P.fields))return!0;const U=d.schema.fields.find($=>$.id===k);return(U==null?void 0:U.required)??!0},I=i.original!==null||i.rawImage!==null,L=!E||I,N=!x("name")||s.name.trim().length>0,R=!x("email")||s.email.trim().length>0,C=!x("phone")||s.phone.trim().length>0,B=!p&&d!==null&&N&&R&&C&&L,H=async()=>{if(!(!B||l||!d)){u(!0);try{let k=null;T&&(k=await _n(T));const U={name:s.name,hours:n,email:s.email,phone:s.phone,description:f},P={scale:1,hue:a,language:e,portraitImage:k,portraitTransform:{scale:i.zoom,offsetX:i.panX,offsetY:i.panY}},[$,K]=await Promise.all([$e(d,U,"front",P),$e(d,U,"back",P)]),X=`zeitgutschein-${n}h-${s.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await kt({frontImageDataUrl:$,backImageDataUrl:K,templateWidth:d.layout.dimensions.width,templateHeight:d.layout.dimensions.height,filename:X})}catch(k){console.error("PDF export failed:",k)}finally{u(!1)}}};return c.jsxs("button",{className:`btn btn-primary w-full btn-md ${B?"":"btn-disabled"}`,onClick:H,disabled:!B,"aria-busy":l||p,children:[l||p?c.jsx("span",{className:"loading loading-spinner loading-sm"}):c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),m.export.button]})}function jt(){const t=y(r=>r.appLanguage),e=y(r=>r.setAppLanguage),n=r=>{e(r)};return c.jsxs("div",{className:"join",children:[c.jsx("button",{className:`join-item btn btn-sm ${t==="de"?"btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),c.jsx("button",{className:`join-item btn btn-sm ${t==="en"?"btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}const zn={de:{voucher:"Gutschein","prompt-generator":"Prompt Generator",gallery:"Galerie"},en:{voucher:"Voucher","prompt-generator":"Prompt Generator",gallery:"Gallery"}};function Vn({currentView:t="voucher",onViewChange:e}){const n=y(o=>o.appLanguage),r=te(n),a=zn[n];return c.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg shrink-0",children:[c.jsx("div",{className:"navbar-start",children:c.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:r.header.title})}),c.jsxs("div",{className:"navbar-center",children:[e&&c.jsxs("div",{className:"tabs tabs-boxed bg-currency-green/50",children:[c.jsx("button",{className:`tab ${t==="voucher"?"tab-active bg-currency-cream text-currency-green":"text-currency-cream"}`,onClick:()=>e("voucher"),children:a.voucher}),c.jsx("button",{className:`tab ${t==="prompt-generator"?"tab-active bg-currency-cream text-currency-green":"text-currency-cream"}`,onClick:()=>e("prompt-generator"),children:a["prompt-generator"]}),c.jsx("button",{className:`tab ${t==="gallery"?"tab-active bg-currency-cream text-currency-green":"text-currency-cream"}`,onClick:()=>e("gallery"),children:a.gallery})]}),!e&&c.jsx("span",{className:"text-sm opacity-80 hidden sm:flex",children:r.header.subtitle})]}),c.jsx("div",{className:"navbar-end",children:c.jsx(jt,{})})]})}const Lt=3633,St=1920;function Kn(t,e){return{front:"",back:"",width:Lt,height:St}}const Ne={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},Gn=Ne,qn=Ne;function Fn(t){return Ne}exports.ApiKeyModal=vt;exports.BillPreview=On;exports.ExportButton=Wn;exports.Header=Vn;exports.LAYOUT_HDPI=Gn;exports.LAYOUT_LDPI=qn;exports.LanguageToggle=jt;exports.PersonalInfoForm=mn;exports.PortraitUpload=kn;exports.TEMPLATE_HEIGHT=St;exports.TEMPLATE_LAYOUT=Ne;exports.TEMPLATE_WIDTH=Lt;exports.TouchSlider=we;exports.VoucherConfig=jn;exports.applyEngravingEffect=lt;exports.applyHueShift=dt;exports.clearImageCache=it;exports.clearRendererCache=Se;exports.clearTemplateCache=Dn;exports.compositeWithBackground=Te;exports.downloadBlob=Et;exports.enhancePortrait=Tn;exports.exportBillAsPdfV2=kt;exports.formatDescription=Ke;exports.generateBillPdfV2=Tt;exports.getApiKey=Pe;exports.getDefaultTemplateId=An;exports.getLayout=Fn;exports.getRemoveBackgroundEndpoint=wn;exports.getTemplate=Kn;exports.getTemplateByIdV2=Ge;exports.getTemplateProvider=Hn;exports.hasApiKey=je;exports.hasCustomEndpoint=vn;exports.hasTemplate=Bn;exports.initializeBillStore=cn;exports.listTemplatesV2=Un;exports.registerTemplate=Nn;exports.removeBackground=wt;exports.renderTemplate=Le;exports.renderTemplateToDataUrl=$e;exports.resizeImage=ct;exports.resizeImageForStorage=Mt;exports.setApiKey=bt;exports.setRemoveBackgroundEndpoint=bn;exports.setTemplateProvider=Mn;exports.t=te;exports.templateProviderV2=xt;exports.unregisterTemplate=Cn;exports.useBillCanvasRefs=Xn;exports.useBillStore=y;exports.validateTemplate=Yn;
package/dist/index.d.ts CHANGED
@@ -36,6 +36,8 @@ export declare function applyEngravingEffect(imageDataUrl: string, intensity?: n
36
36
  */
37
37
  export declare function applyHueShift(imageDataUrl: string, targetHue: number): Promise<string>;
38
38
 
39
+ declare type AppView = 'voucher' | 'prompt-generator' | 'gallery';
40
+
39
41
  /**
40
42
  * Arc-Konfiguration für gebogenen Text
41
43
  */
@@ -402,7 +404,12 @@ export declare function hasCustomEndpoint(): boolean;
402
404
  */
403
405
  export declare function hasTemplate(id: string): Promise<boolean>;
404
406
 
405
- export declare function Header(): JSX.Element;
407
+ export declare function Header({ currentView, onViewChange }: HeaderProps): JSX.Element;
408
+
409
+ declare interface HeaderProps {
410
+ currentView?: AppView;
411
+ onViewChange?: (view: AppView) => void;
412
+ }
406
413
 
407
414
  export declare type HourValue = 1 | 5 | 10;
408
415
 
@@ -605,6 +612,8 @@ export declare interface RenderOptions {
605
612
  hue?: number;
606
613
  /** Aktuelle Sprache */
607
614
  language?: string;
615
+ /** Welche Seite wird gerendert */
616
+ side?: 'front' | 'back';
608
617
  /** Portrait-Bild (bereits verarbeitet) */
609
618
  portraitImage?: HTMLImageElement | null;
610
619
  /** Portrait-Transform (zoom, pan) */
@@ -730,12 +739,16 @@ export declare const TEMPLATE_WIDTH = 3633;
730
739
  * Alle Template-Assets
731
740
  */
732
741
  export declare interface TemplateAssets {
733
- /** Hintergrundbild (WebP/PNG) */
734
- background: string;
735
- /** Frame für Vorderseite (optional) */
742
+ /** Hintergrundbild (WebP/PNG) - Legacy Format */
743
+ background?: string;
744
+ /** Frame für Vorderseite (optional) - Legacy Format */
736
745
  frontFrame?: string;
737
- /** Frame für Rückseite (optional) */
746
+ /** Frame für Rückseite (optional) - Legacy Format */
738
747
  backFrame?: string;
748
+ /** Vollbild für Vorderseite (WebP/PNG) - Neues Format */
749
+ front?: string;
750
+ /** Vollbild für Rückseite (WebP/PNG) - Neues Format */
751
+ back?: string;
739
752
  /** Badge-System */
740
753
  badges?: BadgeAssets;
741
754
  /** Dekorative Elemente */