@zencemarketing/spin-scratch-sdk 0.1.0-alpha.1

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.
@@ -0,0 +1,2 @@
1
+ !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).SpinWheelSDK={})}(this,function(t){"use strict";function n(t,n){if(!t||"string"!=typeof t)return`rgba(0,0,0,${n})`;const e=t.replace("#","");return`rgba(${parseInt(e.slice(0,2),16)||0},${parseInt(e.slice(2,4),16)||0},${parseInt(e.slice(4,6),16)||0},${n})`}function e(t){return null!==t&&"object"==typeof t&&!Array.isArray(t)&&t.constructor===Object}function i(t,...n){if(!n.length)return t;const o=n.shift();if(e(t)&&e(o))for(const n in o)Object.prototype.hasOwnProperty.call(o,n)&&(e(o[n])?(t[n]||(t[n]={}),i(t[n],o[n])):void 0!==o[n]&&(t[n]=o[n]));return i(t,...n)}function o(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}const r='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>',s=["#e8c547","#dc2626","#16a34a","#2563eb","#7c3aed","#ea580c"],a=Object.freeze({container:null,segments:[],winningIndex:null,spinDuration:5e3,minSpins:5,maxSpins:8,spinLimit:null,headerTitle:null,headerSubtitle:null,titleColor:null,subtitleColor:null,hubLabel:"Spin & win",hubIcon:"▲",showButton:!0,buttonText:"SPIN!",backgroundColor:null,backgroundImage:null,ringColor:null,ringShadow:!0,ringAnimation:!0,pointerColor:null,buttonColor:null,buttonShadow:!0,buttonAnimation:!0,showWinCard:!0,generateCode:!0,codeLength:9,redeemUrl:null,winCardBrandLabel:null,winCardWorthLabel:"WORTH",winCardRedeemButtonText:"Redeem Now",winCardRedeemButtonColorTop:"#15803d",winCardRedeemButtonColorBottom:"#166534",winCardRedeemButtonTextColor:"#ffffff",confettiOnWin:!0,confettiColors:null,confettiCount:40,theme:Object.freeze({gold:"#e8c547",goldLight:"#f5d76e",goldDark:"#c9a227",bgDark:"#0d0d12",textMuted:"#9ca3af"}),onSpinStart:null,onSpinEnd:null,onRedeem:null,onSpinLimitReached:null});function l(t){if(!t.container)throw new Error('[SpinWheel] "container" is required.');if(!Array.isArray(t.segments)||t.segments.length<2)throw new Error('[SpinWheel] "segments" must be an array with at least 2 items.');for(let n=0;n<t.segments.length;n++){const e=t.segments[n];if(!e||"object"!=typeof e)throw new Error(`[SpinWheel] segments[${n}] must be an object.`);if(!e.label||"string"!=typeof e.label)throw new Error(`[SpinWheel] segments[${n}].label is required and must be a string.`);if(!e.color||"string"!=typeof e.color)throw new Error(`[SpinWheel] segments[${n}].color is required and must be a string.`)}void 0!==t.spinDuration&&("number"!=typeof t.spinDuration||isNaN(t.spinDuration)?(console.warn('[SpinWheel] "spinDuration" must be a number. Using default (5000).'),t.spinDuration=a.spinDuration):t.spinDuration<=0&&(console.warn(`[SpinWheel] "spinDuration" (${t.spinDuration}) must be positive. Clamping to 500.`),t.spinDuration=500)),void 0!==t.codeLength&&("number"!=typeof t.codeLength||isNaN(t.codeLength)?(console.warn('[SpinWheel] "codeLength" must be a number. Using default (9).'),t.codeLength=a.codeLength):t.codeLength<1?(console.warn(`[SpinWheel] "codeLength" (${t.codeLength}) is below 1. Clamping to 1.`),t.codeLength=1):t.codeLength=Math.floor(t.codeLength)),void 0!==t.confettiCount&&("number"!=typeof t.confettiCount||isNaN(t.confettiCount)?(console.warn('[SpinWheel] "confettiCount" must be a number. Using default (40).'),t.confettiCount=a.confettiCount):t.confettiCount<0&&(console.warn(`[SpinWheel] "confettiCount" (${t.confettiCount}) is negative. Clamping to 0.`),t.confettiCount=0)),void 0!==t.minSpins&&("number"!=typeof t.minSpins||isNaN(t.minSpins)?(console.warn('[SpinWheel] "minSpins" must be a number. Using default (5).'),t.minSpins=a.minSpins):t.minSpins<1&&(console.warn(`[SpinWheel] "minSpins" (${t.minSpins}) is below 1. Clamping to 1.`),t.minSpins=1)),void 0!==t.maxSpins&&("number"!=typeof t.maxSpins||isNaN(t.maxSpins)?(console.warn('[SpinWheel] "maxSpins" must be a number. Using default (8).'),t.maxSpins=a.maxSpins):t.maxSpins<1&&(console.warn(`[SpinWheel] "maxSpins" (${t.maxSpins}) is below 1. Clamping to 1.`),t.maxSpins=1));const n=t.minSpins??a.minSpins,e=t.maxSpins??a.maxSpins;if("number"==typeof n&&"number"==typeof e&&n>e&&(console.warn(`[SpinWheel] "minSpins" (${n}) is greater than "maxSpins" (${e}). Swapping values.`),t.minSpins=e,t.maxSpins=n),void 0!==t.spinLimit&&null!==t.spinLimit&&("number"!=typeof t.spinLimit||isNaN(t.spinLimit)?(console.warn('[SpinWheel] "spinLimit" must be a positive number or null. Setting to null (unlimited).'),t.spinLimit=null):t.spinLimit<1&&(console.warn(`[SpinWheel] "spinLimit" (${t.spinLimit}) is below 1. Clamping to 1.`),t.spinLimit=1)),void 0!==t.winningIndex&&null!==t.winningIndex)if("number"!=typeof t.winningIndex||isNaN(t.winningIndex))console.warn('[SpinWheel] "winningIndex" must be a number or null. Setting to null (random).'),t.winningIndex=null;else if(t.winningIndex<0)console.warn(`[SpinWheel] "winningIndex" (${t.winningIndex}) is negative. Clamping to 0.`),t.winningIndex=0;else if(t.winningIndex>=t.segments.length){const n=t.segments.length-1;console.warn(`[SpinWheel] "winningIndex" (${t.winningIndex}) exceeds max (${n}). Clamping to ${n}.`),t.winningIndex=n}}const c="undefined"!=typeof window&&"undefined"!=typeof document;let d=null;function h(t){if(!c)return;const e={theme:{...a.theme,...t.theme||{}},titleColor:t.titleColor,subtitleColor:t.subtitleColor,backgroundColor:t.backgroundColor,backgroundImage:t.backgroundImage,ringColor:t.ringColor,ringShadow:t.ringShadow,ringAnimation:t.ringAnimation,pointerColor:t.pointerColor,buttonColor:t.buttonColor,buttonShadow:t.buttonShadow,buttonAnimation:t.buttonAnimation,winCardRedeemButtonColorTop:t.winCardRedeemButtonColorTop,winCardRedeemButtonColorBottom:t.winCardRedeemButtonColorBottom,winCardRedeemButtonTextColor:t.winCardRedeemButtonTextColor},i=JSON.stringify(e);if(d===i)return;const o=c?document.querySelector("style[data-spin-wheel-sdk]"):null;o&&o.remove(),d=i;const r=document.createElement("style");r.setAttribute("data-spin-wheel-sdk",""),r.textContent=function(t,n){const e=t.theme||{},i=e.gold||"#e8c547",o=e.goldLight||"#f5d76e",r=e.goldDark||"#c9a227";e.bgDark;const s=e.textMuted||"#9ca3af",a=t.titleColor||o,l=t.subtitleColor||s,c=t.ringColor||i,d=t.pointerColor||i,h=t.buttonColor||i,u=t.winCardRedeemButtonColorTop||"#15803d",p=t.winCardRedeemButtonColorBottom||"#166534",m=t.winCardRedeemButtonTextColor||"#ffffff",g=!1!==t.ringShadow,b=!1!==t.ringAnimation,f=!1!==t.buttonShadow,w=!1!==t.buttonAnimation;n(i,.4);const _=n(c,.4),v=n(h,.4),x=g?`box-shadow:0 0 0 2px rgba(0,0,0,.5), 0 0 50px ${_}, inset 0 2px 4px rgba(255,255,255,.35), inset 0 -2px 4px rgba(0,0,0,.2);`:"box-shadow:0 0 0 2px rgba(0,0,0,.5), inset 0 2px 4px rgba(255,255,255,.35), inset 0 -2px 4px rgba(0,0,0,.2);",C=b?"animation:sw-ring-pulse 3s ease-in-out infinite;":"",y=f?`box-shadow:0 4px 0 ${r}, 0 6px 20px ${v}, inset 0 1px 0 rgba(255,255,255,.3);`:`box-shadow:0 4px 0 ${r}, inset 0 1px 0 rgba(255,255,255,.3);`,E=w?`.sw-spin-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 0 ${r},0 8px 28px ${v},inset 0 1px 0 rgba(255,255,255,.3)}`:".sw-spin-btn:hover:not(:disabled){filter:brightness(1.05)}",S=w?`.sw-spin-btn:active:not(:disabled){transform:translateY(2px);box-shadow:0 2px 0 ${r},0 4px 15px ${v},inset 0 1px 0 rgba(255,255,255,.2)}`:".sw-spin-btn:active:not(:disabled){transform:translateY(1px)}";return`\n/* === SpinWheel SDK v2.1 === */\n@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;800&family=Outfit:wght@300;500;600;700&display=swap');\n\n.sw-root *, .sw-overlay * { margin:0; padding:0; box-sizing:border-box; }\n\n.sw-root {\n font-family:'Outfit',sans-serif;\n display:flex; flex-direction:column; align-items:center; width:100%;\n ${t.backgroundColor?`background-color:${t.backgroundColor};`:""}\n ${t.backgroundImage?`background-image:url('${t.backgroundImage}');background-size:cover;background-position:center;`:""}\n}\n\n/* ── header ── */\n.sw-header { text-align:center; margin-bottom:.5rem; }\n.sw-title {\n font-family:'Playfair Display',serif;\n font-size:clamp(2rem,6vw,3.5rem); font-weight:800; letter-spacing:.02em;\n}\n.sw-title .sw-spin-text {\n color:${a};\n text-shadow:0 0 30px ${n(a,.4)}, 0 0 60px ${n(a,.2)};\n}\n.sw-title .sw-win-text { color:${r}; }\n.sw-subtitle { margin-top:.5rem; color:${l}; font-size:1rem; font-weight:300; }\n\n/* ── wheel ── */\n.sw-wheel-container {\n position:relative; width:min(340px,90vw); aspect-ratio:1; margin:2rem; padding-top:28px;\n}\n.sw-wheel-outer {\n position:absolute; inset:-10px; border-radius:50%;\n background:linear-gradient(145deg,${o} 0%,${c} 25%,${r} 50%,${c} 75%,${r} 100%);\n padding:8px;\n ${x}\n ${C}\n}\n${b?`\n@keyframes sw-ring-pulse {\n 0%,100%{box-shadow:0 0 0 2px rgba(0,0,0,.5),0 0 50px ${_},inset 0 2px 4px rgba(255,255,255,.35),inset 0 -2px 4px rgba(0,0,0,.2)}\n 50%{box-shadow:0 0 0 2px rgba(0,0,0,.5),0 0 65px ${n(c,.5)},inset 0 2px 6px rgba(255,255,255,.4),inset 0 -2px 4px rgba(0,0,0,.2)}\n}`:""}\n.sw-wheel-inner {\n width:100%; height:100%; border-radius:50%; overflow:hidden;\n position:relative; background:transparent;\n box-shadow:inset 0 0 0 3px rgba(0,0,0,.6);\n}\n.sw-wheel {\n width:100%; height:100%; border-radius:50%; position:relative;\n transition:transform .1s linear; will-change:transform;\n}\n.sw-wheel.sw-spinning { transition:none; }\n\n/* ── hub ── */\n.sw-wheel-hub {\n position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);\n width:20%; height:20%; min-width:52px; min-height:52px; border-radius:50%;\n background:linear-gradient(145deg,${o} 0%,${i} 40%,${r} 100%);\n box-shadow:0 3px 12px rgba(0,0,0,.4), inset 0 2px 4px rgba(255,255,255,.4), inset 0 -1px 2px rgba(0,0,0,.2);\n display:flex; flex-direction:column; align-items:center; justify-content:center;\n z-index:10; cursor:pointer; transition:transform .15s ease, filter .15s ease;\n}\n.sw-wheel-hub:hover { transform:translate(-50%,-50%) scale(1.05); filter:brightness(1.1); }\n.sw-wheel-hub:active { transform:translate(-50%,-50%) scale(.98); }\n.sw-wheel-hub-icon { font-size:12px; color:#1a1a1f; line-height:1; margin-bottom:1px; }\n.sw-wheel-hub-brand { font-size:8px; font-weight:700; color:#1a1a1f; letter-spacing:.02em; text-transform:lowercase; }\n.sw-wheel-hub-brand::first-letter { text-transform:uppercase; }\n\n/* ── segments ── */\n.sw-segment {\n position:absolute; width:50%; height:50%; left:50%; top:50%;\n transform-origin:0% 0%; display:flex; align-items:center; justify-content:center; border:none;\n}\n.sw-segment-content {\n position:absolute; width:70%; top:30%; text-align:center; color:#000; font-weight:600;\n font-size:clamp(.6rem,2vw,.8rem); text-shadow:0 1px 3px rgb(220 220 220/50%);\n display:flex; flex-direction:row; align-items:center; justify-content:center;\n gap:4px; word-wrap:break-word; left:30%;\n}\n.sw-segment-icon { font-size:1em; line-height:1; flex-shrink:0; }\n.sw-segment-label { display:inline-block; }\n\n/* ── pointer ── */\n.sw-pointer {\n position:absolute; top:4px; left:50%; transform:translateX(-50%); z-index:20; width:0; height:0;\n}\n.sw-pointer-outer {\n position:absolute; left:50%; transform:translateX(-50%); width:0; height:0;\n border-left:22px solid transparent; border-right:22px solid transparent;\n border-top:36px solid ${d};\n filter:drop-shadow(0 3px 8px rgba(0,0,0,.5)) drop-shadow(0 0 10px ${n(d,.4)}); top:-40px;\n}\n.sw-pointer.sw-highlight .sw-pointer-outer {\n animation:sw-pointer-bounce .5s cubic-bezier(.34,1.56,.64,1);\n}\n@keyframes sw-pointer-bounce {\n 0%{transform:translateX(-50%) scale(1)}\n 40%{transform:translateX(-50%) scale(1.12)}\n 100%{transform:translateX(-50%) scale(1)}\n}\n\n/* ── spin button ── */\n.sw-spin-btn {\n font-family:'Outfit',sans-serif; font-size:1.25rem; font-weight:700;\n letter-spacing:.15em; padding:1rem 3rem; border:none; border-radius:12px;\n background:linear-gradient(180deg,${o},${r}); color:#1a1a1f;\n cursor:pointer;\n ${y}\n transition:transform .15s ease, box-shadow .2s ease, filter .2s ease;\n}\n${E}\n${S}\n.sw-spin-btn:disabled{opacity:.6;cursor:not-allowed}\n\n/* ── overlay & win card ── */\n.sw-overlay {\n position:fixed; inset:0; background:rgba(0,0,0,.6); backdrop-filter:blur(6px);\n display:flex; align-items:center; justify-content:center;\n z-index:100; opacity:0; visibility:hidden;\n transition:opacity .4s ease, visibility .4s ease;\n font-family:'Outfit',sans-serif;\n}\n.sw-overlay.sw-visible { opacity:1; visibility:visible; }\n\n.sw-win-card {\n position:relative; max-width:340px; width:90%; border-radius:12px; overflow:hidden;\n box-shadow:0 25px 50px -12px rgba(0,0,0,.5), 0 0 0 1px rgba(0,0,0,.1);\n transform:scale(.6); opacity:0; transition:none;\n}\n.sw-overlay.sw-visible .sw-win-card {\n animation:sw-card-flare .6s cubic-bezier(.34,1.56,.64,1) forwards;\n}\n@keyframes sw-card-flare {\n 0%{transform:scale(.6);opacity:0;filter:blur(8px)}\n 50%{transform:scale(1.08);opacity:1;filter:blur(0)}\n 70%{transform:scale(.98)}\n 100%{transform:scale(1);opacity:1;filter:blur(0)}\n}\n\n.sw-win-card-top {\n background:linear-gradient(160deg,#fff,#fff); padding:1.75rem 1.25rem;\n text-align:center; position:relative;\n}\n.sw-win-card-product {\n width:100px; height:100px; margin:0 auto .75rem; border-radius:12px;\n display:flex; align-items:center; justify-content:center; font-size:3rem;\n box-shadow:0 8px 24px rgba(0,0,0,.3); background:linear-gradient(145deg,#252530,#1c1c24);\n}\n.sw-win-card-brand { font-size:1rem; font-weight:600; color:#000; letter-spacing:.05em; }\n\n.sw-win-card-perf { height:14px; background:#fff; position:relative; }\n.sw-win-card-perf::after {\n content:''; position:absolute; left:0; right:0; top:-7px; height:14px;\n background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='14' viewBox='0 0 12 14'%3E%3Cpath fill='%231a1a22' d='M0 14V7h2v7H0zm2 0V4h2v10H2zm2 0V7h2v7H4zm2 0V4h2v10H6zm2 0V7h2v7H8zm2 0V0h2v14h-2z'/%3E%3C/svg%3E") repeat-x;\n background-size:12px 14px;\n}\n\n.sw-win-card-mid {\n background:#fff; padding:1.25rem 1.25rem 1.25rem 1rem; position:relative;\n}\n.sw-win-card-title {\n font-size:1rem; font-weight:700; color:#1a1a1f;\n text-transform:lowercase; margin-bottom:.25rem; line-height:1.3;\n}\n.sw-win-card-title::first-letter { text-transform:uppercase; }\n.sw-win-card-worth { font-size:.8rem; color:#6b7280; margin-bottom:.75rem; font-weight:500; }\n.sw-win-card-code-wrap { display:flex; align-items:center; gap:.5rem; }\n.sw-win-card-code {\n flex:1; font-size:.85rem; font-weight:600; letter-spacing:.08em;\n color:#374151; background:#f3f4f6; border:none; border-radius:8px;\n padding:.5rem .75rem; font-family:'Outfit',monospace;\n}\n.sw-win-card-copy {\n width:40px; height:40px; border-radius:8px; border:none;\n background:#e5e7eb; color:#4b5563; cursor:pointer;\n display:flex; align-items:center; justify-content:center;\n transition:background .2s, color .2s;\n}\n.sw-win-card-copy:hover { background:#d1d5db; color:#1f2937; }\n.sw-win-card-copy svg { width:18px; height:18px; }\n\n.sw-win-card-bot {\n background:linear-gradient(180deg,${u},${p});\n padding:1rem 1.25rem; display:flex; align-items:center;\n justify-content:center; gap:.5rem; cursor:pointer;\n transition:filter .2s; position:relative;\n}\n.sw-win-card-bot:hover { filter:brightness(1.08); }\n.sw-win-card-redeem { font-size:1rem; font-weight:700; color:${m}; letter-spacing:.02em; }\n.sw-win-card-arrow { width:20px; height:20px; color:${m}; }\n\n/* ── confetti ── */\n.sw-confetti {\n position:fixed; inset:0; pointer-events:none; z-index:99; overflow:hidden;\n}\n.sw-confetti span {\n position:absolute; width:10px; height:10px; border-radius:2px;\n animation:sw-confetti-fall 1.2s ease-out forwards; opacity:0;\n}\n.sw-overlay.sw-visible .sw-confetti span { opacity:1; }\n@keyframes sw-confetti-fall {\n 0%{transform:translateY(-20px) rotate(0deg);opacity:1}\n 100%{transform:translateY(100vh) rotate(720deg);opacity:0}\n}\n\n/* ── prefers-reduced-motion ── */\n@media (prefers-reduced-motion: reduce) {\n .sw-wheel { transition:none !important; }\n .sw-wheel-outer { animation:none !important; }\n .sw-spin-btn { transition:none !important; }\n .sw-spin-btn:hover:not(:disabled) { transform:none !important; }\n .sw-spin-btn:active:not(:disabled) { transform:none !important; }\n .sw-overlay.sw-visible .sw-win-card { animation:none !important; opacity:1; transform:scale(1); }\n .sw-confetti span { animation:none !important; display:none; }\n .sw-pointer.sw-highlight .sw-pointer-outer { animation:none !important; }\n}\n`}(e,n),document.head.appendChild(r)}class u{constructor(t){if(!c)throw new Error("[SpinWheel] SpinWheel requires a browser environment (window + document).");if(l(t),this.options=i({},a,t),this.options.theme={...a.theme,...t.theme||{}},this.currentRotation=0,this.isSpinning=!1,this._destroyed=!1,this._lastWonPrize=null,this._lastWonIndex=-1,this._spinCount=0,this._rafId=null,this._boundListeners={},this.containerEl="string"==typeof this.options.container?document.querySelector(this.options.container):this.options.container,!this.containerEl)throw new Error("[SpinWheel] container not found. Ensure the container element exists in the DOM.");this.segmentAngle=360/this.options.segments.length,h(this.options),this._rootEl=null,this._wheelEl=null,this._hubEl=null,this._pointerEl=null,this._btnEl=null,this._overlayEl=null,this._confettiEl=null,this._cardProductEl=null,this._cardBrandEl=null,this._cardTitleEl=null,this._cardWorthEl=null,this._cardCodeEl=null,this._cardCopyEl=null,this._cardRedeemEl=null,this._cardRedeemTextEl=null,this._build(),this._bind()}_build(){const t=this.options,n=document.createElement("div");if(n.className="sw-root",t.headerTitle){const e=document.createElement("header");e.className="sw-header";const i=t.headerTitle.split("&");e.innerHTML=`<h1 class="sw-title"><span class="sw-spin-text">${o(i[0]||"Spin")}</span>`+(i.length>1?` <span class="sw-win-text">& ${o(i[1])}</span>`:"")+"</h1>"+(t.headerSubtitle?`<p class="sw-subtitle">${o(t.headerSubtitle)}</p>`:""),n.appendChild(e)}const e=document.createElement("div");e.className="sw-wheel-container";const i=document.createElement("div");i.className="sw-wheel-outer";const r=document.createElement("div");r.className="sw-wheel-inner";const s=document.createElement("div");s.className="sw-wheel",this._wheelEl=s,this._buildSegments(s);const a=document.createElement("div");a.className="sw-wheel-hub",a.title="Spin the wheel",a.innerHTML=`<span class="sw-wheel-hub-icon">${o(t.hubIcon)}</span><span class="sw-wheel-hub-brand">${o(t.hubLabel)}</span>`,this._hubEl=a,r.append(s,a),i.appendChild(r),e.appendChild(i);const l=document.createElement("div");if(l.className="sw-pointer",l.innerHTML='<div class="sw-pointer-outer"></div>',this._pointerEl=l,e.appendChild(l),n.appendChild(e),t.showButton){const e=document.createElement("button");e.className="sw-spin-btn",e.type="button",e.textContent=t.buttonText,this._btnEl=e,n.appendChild(e)}this.containerEl.appendChild(n),this._rootEl=n,t.showWinCard&&this._buildOverlay()}_buildSegments(t){const n=this.segmentAngle,e=function(t){const n=["0 0"],e=Math.max(12,Math.round(t/3)),i=t*Math.PI/180;for(let t=0;t<=e;t++){const o=t/e*i,r=(100*Math.cos(o)).toFixed(2),s=(100*Math.sin(o)).toFixed(2);n.push(`${r}% ${s}%`)}return`polygon(${n.join(", ")})`}(n),i=90+n/2;const r=this.options.segments;for(let s=0;s<r.length;s++){const a=r[s],l=document.createElement("div");l.className="sw-segment",l.style.transform=`rotate(${s*n}deg)`,l.style.clipPath=e,l.style.webkitClipPath=e,l.style.background=a.color||"#ccc",l.innerHTML=`<div class="sw-segment-content" style="transform:rotate(${i}deg)"><span class="sw-segment-icon">${o(a.icon||"")}</span><span class="sw-segment-label">${o(a.label)}</span></div>`,t.appendChild(l)}}_buildOverlay(){const t=this.options,n=t.winCardBrandLabel||t.hubLabel,e=t.winCardRedeemButtonText||"Redeem Now",i=document.createElement("div");i.className="sw-overlay";const s=document.createElement("div");s.className="sw-confetti",this._confettiEl=s;const a=document.createElement("div");a.className="sw-win-card",a.innerHTML=`<div class="sw-win-card-top"> <div class="sw-win-card-product">🎁</div> <div class="sw-win-card-brand">${o(n)}</div></div><div class="sw-win-card-perf"></div><div class="sw-win-card-mid"> <div class="sw-win-card-title">Prize</div> <div class="sw-win-card-worth">${o(t.winCardWorthLabel)} ₹99</div> <div class="sw-win-card-code-wrap"> <input type="text" class="sw-win-card-code" readonly value="XXXXXXXXX" /> <button type="button" class="sw-win-card-copy" aria-label="Copy code">${r}</button> </div></div><div class="sw-win-card-bot"> <span class="sw-win-card-redeem">${o(e)}</span> <svg class="sw-win-card-arrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg></div>`,i.append(s,a),this.containerEl.appendChild(i),this._overlayEl=i,this._cardProductEl=a.querySelector(".sw-win-card-product"),this._cardBrandEl=a.querySelector(".sw-win-card-brand"),this._cardTitleEl=a.querySelector(".sw-win-card-title"),this._cardWorthEl=a.querySelector(".sw-win-card-worth"),this._cardCodeEl=a.querySelector(".sw-win-card-code"),this._cardCopyEl=a.querySelector(".sw-win-card-copy"),this._cardRedeemEl=a.querySelector(".sw-win-card-bot"),this._cardRedeemTextEl=a.querySelector(".sw-win-card-redeem")}_bind(){const t=this._boundListeners;this._btnEl&&(t._btnClick=()=>this.spin(),this._btnEl.addEventListener("click",t._btnClick)),this._hubEl&&(this._hubEl.setAttribute("tabindex","0"),this._hubEl.setAttribute("role","button"),this._hubEl.setAttribute("aria-label","Spin the wheel"),t._hubClick=t=>{t.stopPropagation(),this.spin()},t._hubKeydown=t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.spin())},this._hubEl.addEventListener("click",t._hubClick),this._hubEl.addEventListener("keydown",t._hubKeydown)),this._btnEl&&(t._btnKeydown=t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.spin())},this._btnEl.addEventListener("keydown",t._btnKeydown)),this._overlayEl&&(t._overlayClick=t=>{t.target===this._overlayEl&&this.hideWinCard()},this._overlayEl.addEventListener("click",t._overlayClick),t._copyClick=t=>{t.stopPropagation();const n=this._cardCodeEl.value;if(this._cardCodeEl.select(),this._cardCodeEl.setSelectionRange(0,999),navigator.clipboard?.writeText)navigator.clipboard.writeText(n).then(()=>this._showCopied());else try{document.execCommand("copy"),this._showCopied()}catch(t){}},this._cardCopyEl.addEventListener("click",t._copyClick),t._redeemClick=t=>{if(t.stopPropagation(),"function"==typeof this.options.onRedeem)try{this.options.onRedeem(this._lastWonPrize)}catch(t){console.error("[SpinWheel] onRedeem callback error:",t)}this.options.redeemUrl&&window.open(this.options.redeemUrl,"_blank","noopener,noreferrer"),this.hideWinCard()},this._cardRedeemEl.addEventListener("click",t._redeemClick)),t._docKeydown=t=>{"Escape"===t.key&&this._overlayEl?.classList.contains("sw-visible")&&this.hideWinCard()},document.addEventListener("keydown",t._docKeydown)}_showCopied(){this._cardCopyEl&&!this._destroyed&&(this._cardCopyEl.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{this._cardCopyEl&&(this._cardCopyEl.innerHTML=r)},1500))}_isSpinLimitReached(){const t=this.options.spinLimit;return"number"==typeof t&&t>0&&this._spinCount>=t}spin(t){if(this.isSpinning||this._destroyed)return;if(this._isSpinLimitReached()){if("function"==typeof this.options.onSpinLimitReached)try{this.options.onSpinLimitReached(this._spinCount)}catch(t){console.error("[SpinWheel] onSpinLimitReached callback error:",t)}return}this.isSpinning=!0,this._spinCount++,this._btnEl&&(this._btnEl.disabled=!0),this._wheelEl&&this._wheelEl.classList.add("sw-spinning");const{segments:n,minSpins:e,maxSpins:i,spinDuration:o,winningIndex:r}=this.options,s=n.length,a=this.segmentAngle;let l;var c;if(null!=t?"number"!=typeof t||isNaN(t)?(console.warn(`[SpinWheel] spin(forceIndex): invalid forceIndex "${t}". Using random.`),l=Math.floor(Math.random()*s)):l=Math.max(0,Math.min(s-1,Math.floor(t))):l="number"==typeof(c=r)&&!isNaN(c)&&c>=0&&c<s?r:Math.floor(Math.random()*s),"function"==typeof this.options.onSpinStart)try{this.options.onSpinStart(l)}catch(t){console.error("[SpinWheel] onSpinStart callback error:",t)}const d=l*a+a/2,h=360*((e||5)+Math.floor(Math.random()*((i||8)-(e||5)+1)))+(270-d-this.currentRotation%360+720)%360,u=this.currentRotation+h,p=o||5e3,m=performance.now(),g=this.currentRotation,b=t=>{if(this._destroyed)return;const e=t-m,i=Math.min(e/p,1),o=1-Math.pow(1-i,3),r=g+h*o;if(this._wheelEl&&(this._wheelEl.style.transform=`rotate(${r}deg)`),i<1)this._rafId=requestAnimationFrame(b);else{if(this.currentRotation=u%360,this._wheelEl&&(this._wheelEl.classList.remove("sw-spinning"),this._wheelEl.style.transform=`rotate(${this.currentRotation}deg)`),this._highlightPointer(),this._lastWonPrize=n[l],this._lastWonIndex=l,"function"==typeof this.options.onSpinEnd)try{this.options.onSpinEnd(n[l],l)}catch(t){console.error("[SpinWheel] onSpinEnd callback error:",t)}this.options.showWinCard&&this._showWinCard(n[l]),this.isSpinning=!1,this._btnEl&&(this._btnEl.disabled=this._isSpinLimitReached())}};this._rafId=requestAnimationFrame(b)}_highlightPointer(){this._pointerEl&&!this._destroyed&&(this._pointerEl.classList.remove("sw-highlight"),this._pointerEl.offsetHeight,this._pointerEl.classList.add("sw-highlight"),setTimeout(()=>this._pointerEl.classList.remove("sw-highlight"),500))}_showWinCard(t){if(!t||this._destroyed)return;const n=this.options;if(this._cardProductEl&&(this._cardProductEl.textContent=t.icon||"🎁",this._cardProductEl.style.background=`linear-gradient(145deg,${t.color||"#252530"}22,${t.color||"#1c1c24"}11)`),this._cardTitleEl&&(this._cardTitleEl.textContent=t.title||t.label||""),this._cardWorthEl){const e=n.winCardWorthLabel||"WORTH";this._cardWorthEl.textContent=t.worth?`${e} ${t.worth}`:"",this._cardWorthEl.style.display=t.worth?"":"none"}this._cardCodeEl&&(n.generateCode?(this._cardCodeEl.value=t.code||function(t=9){const n="ABCDEFGHJKLMNPQRSTUVWXYZ23456789";let e="";for(let i=0;i<t;i++)e+=n[Math.floor(32*Math.random())];return e}(n.codeLength),this._cardCodeEl.parentElement&&(this._cardCodeEl.parentElement.style.display="")):t.code?(this._cardCodeEl.value=t.code,this._cardCodeEl.parentElement&&(this._cardCodeEl.parentElement.style.display="")):this._cardCodeEl.parentElement&&(this._cardCodeEl.parentElement.style.display="none")),this._cardRedeemTextEl&&n.winCardRedeemButtonText&&(this._cardRedeemTextEl.textContent=n.winCardRedeemButtonText),!1===n.confettiOnWin||c&&window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches||this._createConfetti(),this._overlayEl&&this._overlayEl.classList.add("sw-visible"),this._announceToScreenReader(`You won ${t.title||t.label||"a prize"}${t.worth?", worth "+t.worth:""}.`)}hideWinCard(){this._overlayEl&&this._overlayEl.classList.remove("sw-visible")}_createConfetti(){if(!this._confettiEl||this._destroyed)return;const t=this.options,n=t.confettiColors||s,e=t.confettiCount||40;this._confettiEl.innerHTML="";for(let t=0;t<e;t++){const t=document.createElement("span");t.style.left=100*Math.random()+"%",t.style.top="-10px",t.style.background=n[Math.floor(Math.random()*n.length)],t.style.animationDelay=.3*Math.random()+"s",t.style.animationDuration=.8+.6*Math.random()+"s",this._confettiEl.appendChild(t)}}updateSegments(t){this._destroyed||(!Array.isArray(t)||t.length<2?console.warn("[SpinWheel] updateSegments: at least 2 segments are required. Ignoring."):(this.options.segments=t,this.segmentAngle=360/t.length,this._wheelEl&&(this._wheelEl.innerHTML="",this._buildSegments(this._wheelEl)),this.currentRotation=0,this._wheelEl&&(this._wheelEl.style.transform="rotate(0deg)")))}destroy(){if(this._destroyed)return;this._destroyed=!0,this._rafId&&(cancelAnimationFrame(this._rafId),this._rafId=null);const t=this._boundListeners;t._btnClick&&this._btnEl&&(this._btnEl.removeEventListener("click",t._btnClick),this._btnEl.removeEventListener("keydown",t._btnKeydown)),t._hubClick&&this._hubEl&&(this._hubEl.removeEventListener("click",t._hubClick),this._hubEl.removeEventListener("keydown",t._hubKeydown)),t._overlayClick&&this._overlayEl&&this._overlayEl.removeEventListener("click",t._overlayClick),t._copyClick&&this._cardCopyEl&&this._cardCopyEl.removeEventListener("click",t._copyClick),t._redeemClick&&this._cardRedeemEl&&this._cardRedeemEl.removeEventListener("click",t._redeemClick),t._docKeydown&&document.removeEventListener("keydown",t._docKeydown),this._boundListeners={},this._liveRegion?.parentNode&&this._liveRegion.parentNode.removeChild(this._liveRegion),this._rootEl?.parentNode?.removeChild(this._rootEl),this._overlayEl?.parentNode?.removeChild(this._overlayEl),this._rootEl=null,this._wheelEl=null,this._hubEl=null,this._pointerEl=null,this._btnEl=null,this._overlayEl=null,this._confettiEl=null,this._cardProductEl=null,this._cardBrandEl=null,this._cardTitleEl=null,this._cardWorthEl=null,this._cardCodeEl=null,this._cardCopyEl=null,this._cardRedeemEl=null,this._cardRedeemTextEl=null,this._liveRegion=null}get lastWonPrize(){return this._lastWonPrize}get lastWonIndex(){return this._lastWonIndex}get spinCount(){return this._spinCount}get remainingSpins(){const t=this.options.spinLimit;return"number"!=typeof t||t<=0?null:Math.max(0,t-this._spinCount)}resetSpinCount(t=0){this._spinCount=Math.max(0,"number"!=typeof t||isNaN(t)?0:Math.floor(t)),this._btnEl&&(this._btnEl.disabled=this._isSpinLimitReached())}_announceToScreenReader(t){if(c){if(!this._liveRegion){const t=document.createElement("div");t.setAttribute("aria-live","assertive"),t.setAttribute("aria-atomic","true"),t.setAttribute("role","status"),t.style.cssText="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;",document.body.appendChild(t),this._liveRegion=t}this._liveRegion.textContent="",setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent=t)},100)}}updateOptions(t){if(this._destroyed)return;if(!t||"object"!=typeof t)return void console.warn("[SpinWheel] updateOptions: argument must be an object. Ignoring.");const n={...this.options,...t,container:this.options.container,segments:this.options.segments};l(n);for(const e of Object.keys(t))e in n&&(t[e]=n[e]);if(this.options=i({},this.options,t),t.theme&&(this.options.theme={...a.theme,...this.options.theme,...t.theme}),h(this.options),this._btnEl&&void 0!==t.buttonText&&(this._btnEl.textContent=this.options.buttonText),this._hubEl&&(void 0===t.hubLabel&&void 0===t.hubIcon||(this._hubEl.innerHTML=`<span class="sw-wheel-hub-icon">${o(this.options.hubIcon)}</span><span class="sw-wheel-hub-brand">${o(this.options.hubLabel)}</span>`)),this._cardBrandEl&&(void 0!==t.winCardBrandLabel||void 0!==t.hubLabel)){const t=this.options.winCardBrandLabel||this.options.hubLabel;this._cardBrandEl.textContent=t}this._cardRedeemTextEl&&void 0!==t.winCardRedeemButtonText&&(this._cardRedeemTextEl.textContent=this.options.winCardRedeemButtonText)}}class p{static init(t){return new u(t)}static Instance=u;static VERSION="0.1.0-alpha.1";static DEFAULTS=a}const m=Object.freeze(["segments","winningIndex","spinDuration","minSpins","maxSpins","spinLimit","headerTitle","headerSubtitle","titleColor","subtitleColor","hubLabel","hubIcon","showButton","buttonText","backgroundColor","backgroundImage","ringColor","ringShadow","ringAnimation","pointerColor","buttonColor","buttonShadow","buttonAnimation","showWinCard","generateCode","codeLength","redeemUrl","winCardBrandLabel","winCardWorthLabel","winCardRedeemButtonText","winCardRedeemButtonColorTop","winCardRedeemButtonColorBottom","winCardRedeemButtonTextColor","confettiOnWin","confettiColors","confettiCount","theme"]);function g(t){const{useEffect:n,useRef:e,useImperativeHandle:i,forwardRef:o,createElement:r}=t,s=o(function(t,o){const s=e(null),a=e(null),l=e({});return l.current.onSpinStart=t.onSpinStart,l.current.onSpinEnd=t.onSpinEnd,l.current.onRedeem=t.onRedeem,l.current.onSpinLimitReached=t.onSpinLimitReached,n(()=>{if(!s.current||"undefined"==typeof window)return;const n={};m.forEach(e=>{void 0!==t[e]&&(n[e]=t[e])}),n.container=s.current,n.onSpinStart=t=>l.current.onSpinStart?.(t),n.onSpinEnd=(t,n)=>l.current.onSpinEnd?.(t,n),n.onRedeem=t=>l.current.onRedeem?.(t),n.onSpinLimitReached=t=>l.current.onSpinLimitReached?.(t);try{a.current=p.init(n)}catch(t){console.error("[SpinWheelReact] Failed to initialize SpinWheel:",t)}return()=>{try{a.current?.destroy()}catch(t){}a.current=null}},[]),n(()=>{if(a.current&&t.segments)try{a.current.updateSegments(t.segments)}catch(t){}},[t.segments]),i(o,()=>({spin(t){a.current?.spin(t)},updateSegments(t){a.current?.updateSegments(t)},hideWinCard(){a.current?.hideWinCard()},updateOptions(t){a.current?.updateOptions(t)},resetSpinCount(t){a.current?.resetSpinCount(t)},get spinCount(){return a.current?.spinCount},get remainingSpins(){return a.current?.remainingSpins},get lastWonPrize(){return a.current?.lastWonPrize},get lastWonIndex(){return a.current?.lastWonIndex},get instance(){return a.current}}),[]),r("div",{ref:s,className:t.className||"",style:t.style||{}})});return s.displayName="SpinWheelReact",s}t.SpinWheelReact=null,"undefined"!=typeof window&&window.React&&(t.SpinWheelReact=g(window.React));const b=Object.freeze({container:null,prize:null,headerTitle:"Scratch the Card to Win Exciting Prizes!",headerTitleColor:null,instruction:"Scratch the card to win exciting prizes.",instructionColor:null,revealThreshold:55,brushSize:28,coinSize:56,showCoin:!0,coinIcon:"$",coinGradientStart:null,coinGradientEnd:null,cardBackground:null,cardShadow:!0,cardBorderRadius:24,scratchZoneBackground:null,scratchZoneShadow:!0,scratchZoneBorderRadius:20,scratchLayerColor:"rgb(150, 130, 180)",scratchLayerSparkles:!0,scratchLayerSparkleCount:40,prizeTextColor:null,prizeNameColor:null,prizeIconBackground:null,showGiftIcon:!0,giftIcon:"🎁",giftIconBackground:null,showModal:!0,modalTitle:"Congratulations!",modalTitleColor:null,modalButtonText:"Claim your",modalButtonColor:null,modalButtonTextColor:null,modalBackdropBlur:!0,confettiEnabled:!0,confettiColors:null,confettiCount:100,confettiDuration:5500,animationType:"default",animationDuration:600,theme:Object.freeze({purpleDark:"#4a2c6a",purpleMid:"#6b4a8a",purpleLight:"#8b6baa",gold:"#d4a84b",goldLight:"#e8c547",goldDark:"#b8923a",white:"#ffffff",textDark:"#2d2d2d",textMuted:"#6b6b6b"}),onScratchStart:null,onScratchProgress:null,onReveal:null,onClaim:null});function f(t){if(!t.container)throw new Error('[ScratchCard] "container" is required.');if(!t.prize||"object"!=typeof t.prize)throw new Error('[ScratchCard] "prize" is required and must be an object.');if(!t.prize.name||"string"!=typeof t.prize.name)throw new Error('[ScratchCard] "prize.name" is required and must be a string.');void 0!==t.revealThreshold&&("number"!=typeof t.revealThreshold||isNaN(t.revealThreshold)?(console.warn('[ScratchCard] "revealThreshold" must be a number. Using default (55).'),t.revealThreshold=b.revealThreshold):t.revealThreshold<10?(console.warn(`[ScratchCard] "revealThreshold" (${t.revealThreshold}) is below 10. Clamping to 10.`),t.revealThreshold=10):t.revealThreshold>90&&(console.warn(`[ScratchCard] "revealThreshold" (${t.revealThreshold}) is above 90. Clamping to 90.`),t.revealThreshold=90)),void 0!==t.brushSize&&("number"!=typeof t.brushSize||isNaN(t.brushSize)?(console.warn('[ScratchCard] "brushSize" must be a number. Using default (28).'),t.brushSize=b.brushSize):t.brushSize<1&&(console.warn(`[ScratchCard] "brushSize" (${t.brushSize}) is below 1. Clamping to 1.`),t.brushSize=1)),void 0!==t.coinSize&&("number"!=typeof t.coinSize||isNaN(t.coinSize)?(console.warn('[ScratchCard] "coinSize" must be a number. Using default (56).'),t.coinSize=b.coinSize):t.coinSize<1&&(console.warn(`[ScratchCard] "coinSize" (${t.coinSize}) is below 1. Clamping to 1.`),t.coinSize=1)),void 0!==t.confettiCount&&("number"!=typeof t.confettiCount||isNaN(t.confettiCount)?(console.warn('[ScratchCard] "confettiCount" must be a number. Using default (100).'),t.confettiCount=b.confettiCount):t.confettiCount<0&&(console.warn(`[ScratchCard] "confettiCount" (${t.confettiCount}) is negative. Clamping to 0.`),t.confettiCount=0)),void 0!==t.confettiDuration&&("number"!=typeof t.confettiDuration||isNaN(t.confettiDuration)?(console.warn('[ScratchCard] "confettiDuration" must be a number. Using default (5500).'),t.confettiDuration=b.confettiDuration):t.confettiDuration<=0&&(console.warn(`[ScratchCard] "confettiDuration" (${t.confettiDuration}) must be positive. Clamping to 100.`),t.confettiDuration=100)),void 0!==t.animationDuration&&("number"!=typeof t.animationDuration||isNaN(t.animationDuration)?(console.warn('[ScratchCard] "animationDuration" must be a number. Using default (600).'),t.animationDuration=b.animationDuration):t.animationDuration<=0&&(console.warn(`[ScratchCard] "animationDuration" (${t.animationDuration}) must be positive. Clamping to 100.`),t.animationDuration=100)),void 0===t.animationType||["default","bounce","none"].includes(t.animationType)||(console.warn(`[ScratchCard] "animationType" ("${t.animationType}") is invalid. Must be "default", "bounce", or "none". Using "default".`),t.animationType="default"),void 0!==t.cardBorderRadius&&("number"!=typeof t.cardBorderRadius||isNaN(t.cardBorderRadius)?(console.warn('[ScratchCard] "cardBorderRadius" must be a number. Using default (24).'),t.cardBorderRadius=b.cardBorderRadius):t.cardBorderRadius<0&&(console.warn(`[ScratchCard] "cardBorderRadius" (${t.cardBorderRadius}) is negative. Clamping to 0.`),t.cardBorderRadius=0)),void 0!==t.scratchZoneBorderRadius&&("number"!=typeof t.scratchZoneBorderRadius||isNaN(t.scratchZoneBorderRadius)?(console.warn('[ScratchCard] "scratchZoneBorderRadius" must be a number. Using default (20).'),t.scratchZoneBorderRadius=b.scratchZoneBorderRadius):t.scratchZoneBorderRadius<0&&(console.warn(`[ScratchCard] "scratchZoneBorderRadius" (${t.scratchZoneBorderRadius}) is negative. Clamping to 0.`),t.scratchZoneBorderRadius=0)),void 0!==t.scratchLayerSparkleCount&&("number"!=typeof t.scratchLayerSparkleCount||isNaN(t.scratchLayerSparkleCount)?(console.warn('[ScratchCard] "scratchLayerSparkleCount" must be a number. Using default (40).'),t.scratchLayerSparkleCount=b.scratchLayerSparkleCount):t.scratchLayerSparkleCount<0&&(console.warn(`[ScratchCard] "scratchLayerSparkleCount" (${t.scratchLayerSparkleCount}) is negative. Clamping to 0.`),t.scratchLayerSparkleCount=0))}const w="undefined"!=typeof window&&"undefined"!=typeof document;let _=null;function v(t){if(!w)return;const e={theme:{...b.theme,...t.theme||{}},headerTitleColor:t.headerTitleColor,instructionColor:t.instructionColor,coinGradientStart:t.coinGradientStart,coinGradientEnd:t.coinGradientEnd,cardBackground:t.cardBackground,cardShadow:t.cardShadow,cardBorderRadius:t.cardBorderRadius,scratchZoneBackground:t.scratchZoneBackground,scratchZoneShadow:t.scratchZoneShadow,scratchZoneBorderRadius:t.scratchZoneBorderRadius,prizeTextColor:t.prizeTextColor,prizeNameColor:t.prizeNameColor,prizeIconBackground:t.prizeIconBackground,giftIconBackground:t.giftIconBackground,modalTitleColor:t.modalTitleColor,modalButtonColor:t.modalButtonColor,modalButtonTextColor:t.modalButtonTextColor,modalBackdropBlur:t.modalBackdropBlur,animationType:t.animationType,animationDuration:t.animationDuration},i=JSON.stringify(e);if(_===i)return;const o=w?document.querySelector("style[data-scratch-card-sdk]"):null;o&&o.remove(),_=i;const r=document.createElement("style");r.setAttribute("data-scratch-card-sdk",""),r.textContent=function(t,n){const e=t.theme||{},i=e.purpleDark||"#4a2c6a",o=e.purpleMid||"#6b4a8a",r=e.purpleLight||"#8b6baa",s=e.gold||"#d4a84b",a=e.goldLight||"#e8c547",l=e.goldDark||"#b8923a",c=e.white||"#ffffff",d=e.textDark||"#2d2d2d",h=e.textMuted||"#6b6b6b",u=t.headerTitleColor||d,p=t.instructionColor||h,m=t.coinGradientStart||a,g=t.coinGradientEnd||l,b=t.prizeTextColor||"rgba(255,255,255,0.95)",f=t.prizeNameColor||a,w=t.prizeIconBackground||"rgba(255,255,255,0.15)",_=t.giftIconBackground||"rgba(255,255,255,0.25)",v=t.modalTitleColor||d,x=t.modalButtonTextColor||c,C=!1!==t.cardShadow,y=!1!==t.scratchZoneShadow,E=!1!==t.modalBackdropBlur,S=t.cardBorderRadius||24,z=t.scratchZoneBorderRadius||20,k=t.animationDuration||600,L=t.animationType||"default",$=t.cardBackground||"linear-gradient(180deg, #faf8fc 0%, #f0ebf5 100%)",R=t.scratchZoneBackground||`linear-gradient(145deg, ${i} 0%, ${o} 50%, #5a3a7a 100%)`,T=t.modalButtonColor||`linear-gradient(145deg, ${o} 0%, ${i} 100%)`;n(s,.4);const M=C?`box-shadow:0 4px 24px ${n(i,.12)}, 0 12px 48px rgba(0,0,0,0.08);`:"",B=y?`box-shadow:inset 0 2px 20px rgba(0,0,0,0.2), 0 8px 24px ${n(i,.35)};`:"",D=E?"backdrop-filter:blur(4px);":"",I="none"===L?"":"bounce"===L?`animation:sc-card-bounce ${k}ms cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards;`:`animation:sc-card-slide ${k}ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;`,N="none"===L?"":`transition:transform ${.66*k}ms cubic-bezier(0.34, 1.56, 0.64, 1);`;return`\n/* === ScratchCard SDK v1.1 === */\n@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap');\n\n.sc-root *, .sc-modal-overlay * { margin:0; padding:0; box-sizing:border-box; }\n\n.sc-root {\n font-family:'Outfit',sans-serif;\n display:flex;\n align-items:center;\n justify-content:center;\n padding:2rem 1rem;\n min-height:100%;\n background:linear-gradient(135deg, #e8e0f0 0%, #d8d0e8 50%, #e0d8f0 100%);\n position:relative;\n overflow:hidden;\n}\n\n.sc-page-bg {\n position:fixed;\n inset:0;\n background:radial-gradient(ellipse 80% 70% at 50% 40%, ${n(o,.15)} 0%, transparent 60%);\n pointer-events:none;\n animation:sc-glow-pulse 4s ease-in-out infinite;\n}\n\n@keyframes sc-glow-pulse {\n 0%, 100% { opacity:1; }\n 50% { opacity:0.7; }\n}\n\n.sc-wrapper {\n position:relative;\n width:min(360px, 92vw);\n ${I}\n}\n\n@keyframes sc-card-slide {\n from { opacity:0; transform:translateY(24px) scale(0.96); }\n to { opacity:1; transform:translateY(0) scale(1); }\n}\n\n@keyframes sc-card-bounce {\n 0% { opacity:0; transform:scale(0.5); }\n 60% { opacity:1; transform:scale(1.05); }\n 80% { transform:scale(0.98); }\n 100% { transform:scale(1); }\n}\n\n.sc-main-card {\n background:${$};\n border-radius:${S}px;\n padding:28px 24px 32px;\n ${M}\n}\n\n.sc-header {\n text-align:center;\n margin-bottom:20px;\n}\n\n.sc-header h1 {\n font-size:1.5rem;\n font-weight:700;\n color:${u};\n letter-spacing:-0.02em;\n}\n\n.sc-zone {\n position:relative;\n width:100%;\n aspect-ratio:1.05;\n max-height:320px;\n border-radius:${z}px;\n overflow:hidden;\n background:${R};\n ${B}\n}\n\n.sc-zone:not(.sc-ready) .sc-prize-content {\n visibility:hidden;\n}\n\n.sc-prize-content {\n position:absolute;\n inset:0;\n z-index:0;\n display:flex;\n flex-direction:column;\n align-items:center;\n justify-content:center;\n padding:20px;\n background:\n radial-gradient(circle at 30% 30%, rgba(255,255,255,0.08) 0%, transparent 45%),\n linear-gradient(145deg, ${i} 0%, ${o} 100%);\n}\n\n.sc-prize-content::before {\n content:'';\n position:absolute;\n inset:0;\n background-image:\n url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M30 5 L35 25 L55 30 L35 35 L30 55 L25 35 L5 30 L25 25 Z' fill='none' stroke='rgba(255,255,255,0.06)' stroke-width='0.5'/%3E%3C/svg%3E"),\n url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='20' cy='20' r='1' fill='rgba(255,255,255,0.1)'/%3E%3C/svg%3E");\n opacity:0.9;\n pointer-events:none;\n}\n\n.sc-prize-text {\n position:relative;\n z-index:1;\n text-align:center;\n color:${b};\n font-size:1.25rem;\n font-weight:700;\n text-shadow:0 2px 8px rgba(0,0,0,0.3);\n margin-bottom:8px;\n}\n\n.sc-prize-name {\n font-size:1.5rem;\n font-weight:700;\n color:${f};\n text-shadow:0 0 20px ${n(s,.5)};\n}\n\n.sc-prize-icon {\n width:80px;\n height:80px;\n margin:12px auto;\n background:${w};\n border-radius:50%;\n display:flex;\n align-items:center;\n justify-content:center;\n font-size:2.5rem;\n}\n\n.sc-prize-icon-visible {\n position:absolute;\n left:50%;\n top:50%;\n margin-left:-40px;\n margin-top:-40px;\n width:80px;\n height:80px;\n background:${_};\n border-radius:50%;\n display:flex;\n align-items:center;\n justify-content:center;\n font-size:2.5rem;\n z-index:11;\n pointer-events:none;\n box-shadow:0 4px 20px rgba(0,0,0,0.15);\n}\n\n.sc-coin {\n position:absolute;\n left:0;\n top:0;\n width:56px;\n height:56px;\n border-radius:50%;\n background:linear-gradient(145deg, ${m} 0%, ${s} 30%, ${g} 70%, #9a7a2a 100%);\n box-shadow:\n inset 0 2px 4px rgba(255,255,255,0.4),\n inset 0 -2px 6px rgba(0,0,0,0.25),\n 0 6px 16px rgba(0,0,0,0.3);\n display:flex;\n align-items:center;\n justify-content:center;\n font-weight:800;\n font-size:1.5rem;\n color:${g};\n text-shadow:0 1px 0 rgba(255,255,255,0.4);\n z-index:12;\n pointer-events:auto;\n cursor:grab;\n touch-action:none;\n transition:box-shadow 0.15s ease;\n}\n\n.sc-coin:active {\n cursor:grabbing;\n box-shadow:\n inset 0 2px 4px rgba(255,255,255,0.3),\n 0 4px 12px rgba(0,0,0,0.35);\n}\n\n.sc-coin.dragging {\n animation:none;\n}\n\n.sc-canvas {\n position:absolute;\n top:0;\n left:0;\n right:0;\n bottom:0;\n width:100%;\n height:100%;\n z-index:10;\n display:block;\n cursor:crosshair;\n touch-action:none;\n}\n\n.sc-instruction {\n text-align:center;\n margin-top:18px;\n font-size:0.95rem;\n color:${p};\n font-weight:500;\n}\n\n/* Modal */\n.sc-modal-overlay {\n position:fixed;\n inset:0;\n background:rgba(0,0,0,0.5);\n ${D}\n display:flex;\n align-items:center;\n justify-content:center;\n padding:1.5rem;\n z-index:100;\n opacity:0;\n visibility:hidden;\n transition:opacity 0.35s ease, visibility 0.35s ease;\n}\n\n.sc-modal-overlay.active {\n opacity:1;\n visibility:visible;\n}\n\n.sc-confetti-canvas {\n position:absolute;\n inset:0;\n width:100%;\n height:100%;\n pointer-events:none;\n z-index:1;\n}\n\n.sc-modal-bg-glow {\n position:absolute;\n inset:0;\n z-index:2;\n background:radial-gradient(\n ellipse 90% 80% at 50% 50%,\n ${n(o,.4)} 0%,\n ${n(i,.2)} 40%,\n transparent 70%\n );\n animation:sc-modal-glow 3s ease-in-out infinite;\n}\n\n@keyframes sc-modal-glow {\n 0%, 100% { opacity:1; }\n 50% { opacity:0.85; }\n}\n\n.sc-modal-card {\n position:relative;\n z-index:3;\n width:min(340px, 100%);\n background:${c};\n border-radius:${S}px;\n padding:32px 24px 28px;\n box-shadow:0 24px 64px rgba(0,0,0,0.2);\n transform:scale(0.9) translateY(20px);\n ${N}\n overflow:hidden;\n}\n\n.sc-modal-overlay.active .sc-modal-card {\n transform:scale(1) translateY(0);\n}\n\n.sc-modal-card::before {\n content:'';\n position:absolute;\n top:-50%;\n left:-50%;\n width:200%;\n height:200%;\n background:radial-gradient(circle at 50% 50%, ${n(r,.08)} 0%, transparent 50%);\n pointer-events:none;\n}\n\n.sc-modal-header {\n text-align:center;\n margin-bottom:20px;\n}\n\n.sc-modal-header h2 {\n font-size:1.5rem;\n font-weight:700;\n color:${v};\n line-height:1.3;\n}\n\n.sc-modal-prize-box {\n background:linear-gradient(180deg, #f8f4fc 0%, #f0eaf8 100%);\n border-radius:20px;\n padding:28px 20px;\n margin-bottom:24px;\n text-align:center;\n position:relative;\n}\n\n.sc-modal-prize-circle {\n width:100px;\n height:100px;\n margin:0 auto 16px;\n background:linear-gradient(145deg, ${r} 0%, ${o} 100%);\n border-radius:50%;\n display:flex;\n align-items:center;\n justify-content:center;\n font-size:2.8rem;\n box-shadow:0 8px 24px ${n(i,.3)};\n}\n\n.sc-modal-prize-box .sc-prize-label {\n font-size:1.1rem;\n font-weight:600;\n color:${d};\n}\n\n.sc-modal-prize-box .sc-prize-name {\n font-size:1.35rem;\n color:${o};\n margin-top:4px;\n}\n\n.sc-btn-claim {\n display:block;\n width:100%;\n padding:16px 24px;\n border:none;\n border-radius:14px;\n background:${T};\n color:${x};\n font-family:inherit;\n font-size:1.1rem;\n font-weight:600;\n cursor:pointer;\n box-shadow:0 6px 20px ${n(i,.4)};\n transition:transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.sc-btn-claim:hover {\n transform:translateY(-2px);\n box-shadow:0 8px 28px ${n(i,.5)};\n}\n\n.sc-btn-claim:active {\n transform:translateY(0);\n}\n\n.sc-modal-terms {\n text-align:center;\n margin-top:16px;\n}\n\n.sc-modal-terms a {\n font-size:0.875rem;\n color:${h};\n text-decoration:none;\n}\n\n.sc-modal-terms a:hover {\n color:${o};\n text-decoration:underline;\n}\n\n/* ── prefers-reduced-motion ── */\n@media (prefers-reduced-motion: reduce) {\n .sc-wrapper { animation:none !important; opacity:1; transform:none; }\n .sc-page-bg { animation:none !important; }\n .sc-modal-bg-glow { animation:none !important; }\n .sc-modal-card { transition:none !important; transform:scale(1) translateY(0) !important; }\n .sc-btn-claim { transition:none !important; }\n .sc-btn-claim:hover { transform:none !important; }\n .sc-coin { transition:none !important; }\n}\n`}(e,n),document.head.appendChild(r)}class x{constructor(t){if(!w)throw new Error("[ScratchCard] ScratchCard requires a browser environment (window + document).");if(f(t),this.options=i({},b,t),this.options.theme={...b.theme,...t.theme||{}},this.scratchPercent=0,this.isScratching=!1,this.isDraggingCoin=!1,this.hasRevealed=!1,this._destroyed=!1,this._scratchStartFired=!1,this._confettiRafId=null,this._confettiTimeouts=[],this._prize=this.options.prize,this.containerEl="string"==typeof this.options.container?document.querySelector(this.options.container):this.options.container,!this.containerEl)throw new Error("[ScratchCard] container not found. Ensure the container element exists in the DOM.");this.zoneW=0,this.zoneH=0,this._lastPoint=null,this._resizeObserver=null,v(this.options),this._rootEl=null,this._zoneEl=null,this._canvasEl=null,this._ctx=null,this._coinEl=null,this._giftIconEl=null,this._modalEl=null,this._confettiCanvasEl=null,this._prizeContentEl=null,this._instructionEl=null,this._build(),this._bind()}_build(){const t=this.options,n=document.createElement("div");n.className="sc-root";const e=document.createElement("div");e.className="sc-page-bg",e.setAttribute("aria-hidden","true"),n.appendChild(e);const i=document.createElement("div");i.className="sc-wrapper";const r=document.createElement("div");r.className="sc-main-card";const s=document.createElement("header");s.className="sc-header",s.innerHTML=`<h1>${o(t.headerTitle)}</h1>`,r.appendChild(s);const a=document.createElement("div");a.className="sc-zone",a.id=`sc-zone-${this._id()}`,this._zoneEl=a;const l=document.createElement("div");l.className="sc-prize-content",l.innerHTML=`\n <div class="sc-prize-text">${o(this._prize.label||"Congratulations!")}</div>\n <div class="sc-prize-name">${o(this._prize.name)}</div>\n <div class="sc-prize-icon">${o(this._prize.icon||"🎁")}</div>\n `,a.appendChild(l),this._prizeContentEl=l;const c=document.createElement("canvas");if(c.className="sc-canvas",c.id=`sc-canvas-${this._id()}`,c.setAttribute("aria-label","Scratch to reveal your prize"),a.appendChild(c),this._canvasEl=c,this._ctx=c.getContext("2d"),!1!==t.showGiftIcon){const n=document.createElement("div");n.className="sc-prize-icon-visible",n.id=`sc-gift-icon-${this._id()}`,n.setAttribute("aria-hidden","true"),n.textContent=t.giftIcon||"🎁",a.appendChild(n),this._giftIconEl=n}if(t.showCoin){const n=document.createElement("div");n.className="sc-coin",n.id=`sc-coin-${this._id()}`,n.setAttribute("aria-hidden","true"),n.textContent=t.coinIcon,a.appendChild(n),this._coinEl=n}r.appendChild(a);const d=document.createElement("p");d.className="sc-instruction",d.textContent=t.instruction,r.appendChild(d),this._instructionEl=d,i.appendChild(r),n.appendChild(i),this.containerEl.appendChild(n),this._rootEl=n,t.showModal&&this._buildModal(),this._initCanvas()}_id(){return Math.random().toString(36).slice(2,9)}_buildModal(){const t=this.options,n=t.modalTitle||"Congratulations!",e=t.modalButtonText||"Claim your",i=document.createElement("div");i.className="sc-modal-overlay",i.setAttribute("role","dialog"),i.setAttribute("aria-modal","true"),i.setAttribute("aria-hidden","true"),i.setAttribute("aria-label","Prize won");const r=document.createElement("canvas");r.className="sc-confetti-canvas",r.setAttribute("aria-hidden","true"),i.appendChild(r),this._confettiCanvasEl=r;const s=document.createElement("div");s.className="sc-modal-bg-glow",i.appendChild(s);const a=document.createElement("div");a.className="sc-modal-card",a.innerHTML=`\n <div class="sc-modal-header">\n <h2>${o(n)} You won ${o(this._prize.name)}.</h2>\n </div>\n <div class="sc-modal-prize-box">\n <div class="sc-modal-prize-circle">${o(this._prize.icon||"🎁")}</div>\n <div class="sc-prize-label">${o(this._prize.label||n)} You won ${o(this._prize.name)}!</div>\n <div class="sc-prize-name">${o(this._prize.name)}</div>\n </div>\n <button type="button" class="sc-btn-claim">${o(e)} ${o(this._prize.name)}</button>\n <p class="sc-modal-terms">\n <a href="#" onclick="return false;">Terms & Conditions</a>\n </p>\n `,i.appendChild(a),this.containerEl.appendChild(i),this._modalEl=i}_initCanvas(){const t=()=>{const t=this._zoneEl.clientWidth,n=this._zoneEl.clientHeight;if(t<=0||n<=0)return;this.zoneW=t,this.zoneH=n;const e=window.devicePixelRatio||1;this._canvasEl.width=Math.ceil(t*e),this._canvasEl.height=Math.ceil(n*e),this._canvasEl.style.width=t+"px",this._canvasEl.style.height=n+"px",this._ctx.setTransform(1,0,0,1,0,0),this._ctx.scale(e,e),this._drawSurface(),this._positionCoinInitial(),this._zoneEl.classList.add("sc-ready")};this._resizeObserver=new ResizeObserver(()=>{requestAnimationFrame(t)}),this._resizeObserver.observe(this._zoneEl),requestAnimationFrame(()=>requestAnimationFrame(t))}_drawSurface(){const t=this.zoneW,n=this.zoneH;if(t<=0||n<=0)return;const e=this._ctx,i=this.options;if(e.fillStyle=i.scratchLayerColor||"rgb(150, 130, 180)",e.fillRect(0,0,t,n),!1!==i.scratchLayerSparkles){const o=i.scratchLayerSparkleCount||40;e.globalCompositeOperation="overlay",e.fillStyle="rgba(255, 255, 255, 0.2)";for(let i=0;i<o;i++)e.beginPath(),e.arc(Math.random()*t,Math.random()*n,2+3*Math.random(),0,2*Math.PI),e.fill();e.globalCompositeOperation="source-over"}}_positionCoinInitial(){if(!this._coinEl||this.zoneW<=0||this.zoneH<=0)return;const t=this.options.coinSize/2,n=Math.round(.15*this.zoneW-t),e=Math.round(.82*this.zoneH-t);this._coinEl.style.transform=`translate(${n}px, ${e}px)`}_bind(){const t=this._canvasEl;if(this._boundStartScratch=this._onStartScratch.bind(this),this._boundMoveScratch=this._onMoveScratch.bind(this),this._boundEndScratch=this._onEndScratch.bind(this),t.addEventListener("mousedown",this._boundStartScratch),t.addEventListener("mousemove",this._boundMoveScratch),t.addEventListener("mouseup",this._boundEndScratch),t.addEventListener("mouseleave",this._boundEndScratch),t.addEventListener("touchstart",this._boundStartScratch,{passive:!1}),t.addEventListener("touchmove",this._boundMoveScratch,{passive:!1}),t.addEventListener("touchend",this._boundEndScratch),t.addEventListener("touchcancel",this._boundEndScratch),this._coinEl&&(this._boundStartCoinDrag=this._onStartCoinDrag.bind(this),this._coinEl.addEventListener("mousedown",this._boundStartCoinDrag),this._coinEl.addEventListener("touchstart",this._boundStartCoinDrag,{passive:!1})),this._boundDocMouseMove=t=>{this.isDraggingCoin&&this._onMoveCoinDrag(t)},this._boundDocMouseUp=this._onEndCoinDrag.bind(this),this._boundDocTouchMove=t=>{this.isDraggingCoin&&(t.preventDefault(),this._onMoveCoinDrag(t))},this._boundDocTouchEnd=this._onEndCoinDrag.bind(this),this._boundDocTouchCancel=this._onEndCoinDrag.bind(this),document.addEventListener("mousemove",this._boundDocMouseMove),document.addEventListener("mouseup",this._boundDocMouseUp),document.addEventListener("touchmove",this._boundDocTouchMove,{passive:!1}),document.addEventListener("touchend",this._boundDocTouchEnd),document.addEventListener("touchcancel",this._boundDocTouchCancel),this._modalEl){this._boundModalClick=t=>{(t.target===this._modalEl||t.target.classList.contains("sc-modal-bg-glow"))&&this.hideModal()},this._modalEl.addEventListener("click",this._boundModalClick);const t=this._modalEl.querySelector(".sc-btn-claim");t&&(this._boundClaimClick=()=>{if(this.hideModal(),"function"==typeof this.options.onClaim)try{this.options.onClaim(this._prize)}catch(t){console.error("[ScratchCard] onClaim callback error:",t)}},this._claimBtnEl=t,t.addEventListener("click",this._boundClaimClick))}this._boundDocKeydown=t=>{"Escape"===t.key&&this._modalEl?.classList.contains("active")&&this.hideModal()},document.addEventListener("keydown",this._boundDocKeydown)}_getEventPoint(t){if(!this._zoneEl)return{x:0,y:0};const n=this._zoneEl.getBoundingClientRect();return t.touches&&t.touches.length?{x:t.touches[0].clientX-n.left,y:t.touches[0].clientY-n.top}:{x:t.clientX-n.left,y:t.clientY-n.top}}_onStartScratch(t){if(!this.hasRevealed&&!this._destroyed&&(t.preventDefault(),this.isScratching=!0,this._giftIconEl&&(this._giftIconEl.style.display="none"),this._lastPoint=this._getEventPoint(t),this._scratch(this._lastPoint.x,this._lastPoint.y),!this._scratchStartFired&&"function"==typeof this.options.onScratchStart)){this._scratchStartFired=!0;try{this.options.onScratchStart()}catch(t){console.error("[ScratchCard] onScratchStart callback error:",t)}}}_onMoveScratch(t){if(!this.isScratching||this.hasRevealed||this._destroyed)return;t.preventDefault();const n=this._getEventPoint(t),e=n.x-this._lastPoint.x,i=n.y-this._lastPoint.y,o=Math.sqrt(e*e+i*i),r=Math.max(1,Math.floor(o/4));for(let t=1;t<=r;t++){const n=t/r,o=this._lastPoint.x+e*n,s=this._lastPoint.y+i*n;this._scratch(o,s)}this._lastPoint=n}_onEndScratch(){this.isScratching=!1,this._lastPoint=null}_scratch(t,n,e){if(!this._ctx||this._destroyed)return;const i=void 0!==e?e:this.options.brushSize/2,o=this._ctx;o.globalCompositeOperation="destination-out",o.fillStyle="rgba(0, 0, 0, 1)",o.beginPath(),o.arc(t,n,i,0,2*Math.PI),o.fill(),o.globalCompositeOperation="source-over",this.hasRevealed||this._updateScratchPercent()}_updateScratchPercent(){if(!this._ctx||this._destroyed)return;const t=this.zoneW,n=this.zoneH;if(t<=0||n<=0)return;const e=window.devicePixelRatio||1,i=Math.ceil(t*e),o=Math.ceil(n*e);if(i<=0||o<=0)return;let r;try{r=this._ctx.getImageData(0,0,i,o)}catch(t){return}const s=r.data;let a=0;for(let t=0;t<s.length;t+=32)s[t+3]<128&&a++;const l=i*o/8;if(this.scratchPercent=l>0?Math.round(a/l*100):0,"function"==typeof this.options.onScratchProgress)try{this.options.onScratchProgress(this.scratchPercent)}catch(t){console.error("[ScratchCard] onScratchProgress callback error:",t)}this.scratchPercent>=this.options.revealThreshold&&this._reveal()}_reveal(){if(!this.hasRevealed&&!this._destroyed){if(this.hasRevealed=!0,this._ctx)try{this._ctx.clearRect(0,0,this.zoneW,this.zoneH)}catch(t){}if(this._giftIconEl&&(this._giftIconEl.style.display="none"),this._modalEl){this._modalEl.classList.add("active"),this._modalEl.setAttribute("aria-hidden","false"),!1===this.options.confettiEnabled||w&&window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches||this._startConfetti();const t=this._modalEl.querySelector(".sc-btn-claim");t&&setTimeout(()=>t.focus(),100)}if(this._announceToScreenReader(`Prize revealed: ${this._prize?.name||"your prize"}`),"function"==typeof this.options.onReveal)try{this.options.onReveal(this._prize)}catch(t){console.error("[ScratchCard] onReveal callback error:",t)}}}_onStartCoinDrag(t){if(this.hasRevealed||this._destroyed)return;t.preventDefault(),t.stopPropagation(),this.isDraggingCoin=!0,this._coinEl&&this._coinEl.classList.add("dragging"),this._giftIconEl&&(this._giftIconEl.style.display="none");const n=this._getEventPoint(t),e=this._clampCoinPosition(n.x,n.y);if(this._updateCoinPosition(e.x,e.y),this._scratch(e.x,e.y,this.options.coinSize/2),!this._scratchStartFired&&"function"==typeof this.options.onScratchStart){this._scratchStartFired=!0;try{this.options.onScratchStart()}catch(t){console.error("[ScratchCard] onScratchStart callback error:",t)}}}_onMoveCoinDrag(t){if(!this.isDraggingCoin||this.hasRevealed||this._destroyed)return;t.preventDefault(),t.stopPropagation();const n=this._getEventPoint(t),e=this._clampCoinPosition(n.x,n.y);this._updateCoinPosition(e.x,e.y),this._scratch(e.x,e.y,this.options.coinSize/2)}_onEndCoinDrag(){this.isDraggingCoin&&(this.isDraggingCoin=!1,this._coinEl&&this._coinEl.classList.remove("dragging"))}_clampCoinPosition(t,n){const e=this.options.coinSize/2;return{x:Math.max(e,Math.min(this.zoneW-e,t)),y:Math.max(e,Math.min(this.zoneH-e,n))}}_updateCoinPosition(t,n){if(!this._coinEl)return;const e=this.options.coinSize/2;this._coinEl.style.transform=`translate(${t-e}px, ${n-e}px)`}_startConfetti(){if(!this._confettiCanvasEl||!this._modalEl||this._destroyed)return;const t=this.options,n=this._modalEl.getBoundingClientRect(),e=n.width,i=n.height;if(e<=0||i<=0)return;this._confettiCanvasEl.width=e,this._confettiCanvasEl.height=i,this._confettiCanvasEl.style.width=e+"px",this._confettiCanvasEl.style.height=i+"px";const o=this._confettiCanvasEl.getContext("2d");if(!o)return;const r=t.confettiColors||["#e8c547","#d4a84b","#6b4a8a","#8b6baa","#c94a6a","#4ac97a","#fff","#ff6b6b"],s=[],a=e/2,l=i/2,c=t.confettiCount||100;for(let t=0;t<c;t++){const n=2*Math.PI*t/c+.5*Math.random(),e=4+10*Math.random();s.push({x:a,y:l,vx:Math.cos(n)*e+4*(Math.random()-.5),vy:Math.sin(n)*e-6+2*(Math.random()-.5),color:r[Math.floor(Math.random()*r.length)],size:4+8*Math.random(),rotation:Math.random()*Math.PI*2,rotationSpeed:.3*(Math.random()-.5),opacity:1,birth:0})}this._confettiTimeouts.push(setTimeout(()=>this._addBurst(s,a,l,35,o,e,i),200),setTimeout(()=>this._addBurst(s,a,l,30,o,e,i),450));const d=Date.now(),h=t.confettiDuration||5500,u=()=>{const t=Date.now()-d;if(t>h||this._destroyed)return o.clearRect(0,0,e,i),void(this._confettiRafId=null);o.clearRect(0,0,e,i);for(let n=0;n<s.length;n++){const e=s[n],r=e.birth?Date.now()-e.birth:t;e.x+=e.vx,e.y+=e.vy,e.vy+=.22,e.vx*=.99,e.vy*=.99,e.rotation+=e.rotationSpeed;const a=1-r/(e.birth?3200:h);e.opacity=Math.max(0,a),e.opacity<=0||e.y>i+20||(o.save(),o.globalAlpha=e.opacity,o.translate(e.x,e.y),o.rotate(e.rotation),o.fillStyle=e.color,o.fillRect(-e.size/2,-e.size/4,e.size,e.size/2),o.restore())}this._confettiRafId=requestAnimationFrame(u)};this._confettiRafId=requestAnimationFrame(u)}_addBurst(t,n,e,i,o,r,s){const a=this.options.confettiColors||["#e8c547","#d4a84b","#6b4a8a","#8b6baa","#c94a6a","#4ac97a","#fff","#ff6b6b"];for(let o=0;o<i;o++){const i=Math.random()*Math.PI*2,o=3+8*Math.random();t.push({x:n+120*(Math.random()-.5),y:e-40+20*(Math.random()-.5),vx:Math.cos(i)*o,vy:Math.sin(i)*o-4,color:a[Math.floor(Math.random()*a.length)],size:3+6*Math.random(),rotation:Math.random()*Math.PI*2,rotationSpeed:.3*(Math.random()-.5),opacity:1,birth:Date.now()})}}reveal(){this._destroyed||this._reveal()}hideModal(){!this._destroyed&&this._modalEl&&(this._modalEl.classList.remove("active"),this._modalEl.setAttribute("aria-hidden","true"))}showModal(){!this._destroyed&&this._modalEl&&(this._modalEl.classList.add("active"),this._modalEl.setAttribute("aria-hidden","false"))}reset(){this._destroyed||(this.hasRevealed=!1,this.scratchPercent=0,this.isScratching=!1,this.isDraggingCoin=!1,this._lastPoint=null,this._scratchStartFired=!1,this._drawSurface(),this._positionCoinInitial(),this._giftIconEl&&(this._giftIconEl.style.display=""),this.hideModal(),this._zoneEl&&(this._zoneEl.classList.remove("sc-ready"),requestAnimationFrame(()=>{this._zoneEl&&this._zoneEl.classList.add("sc-ready")})))}updatePrize(t){if(this._destroyed)return;if(!t||"object"!=typeof t)return void console.warn("[ScratchCard] updatePrize: prize must be an object. Ignoring.");this._prize={...this._prize,...t},this.reset();const n=this.options,e=n.modalTitle||"Congratulations!",i=n.modalButtonText||"Claim your";if(this._prizeContentEl&&(this._prizeContentEl.innerHTML=`\n <div class="sc-prize-text">${o(this._prize.label||e)}</div>\n <div class="sc-prize-name">${o(this._prize.name)}</div>\n <div class="sc-prize-icon">${o(this._prize.icon||"🎁")}</div>\n `),this._modalEl){const t=this._modalEl.querySelector(".sc-modal-header h2");t&&(t.textContent=`${e} You won ${this._prize.name}.`);const n=this._modalEl.querySelector(".sc-modal-prize-circle");n&&(n.textContent=this._prize.icon||"🎁");const o=this._modalEl.querySelector(".sc-modal-prize-box .sc-prize-label");o&&(o.textContent=`${this._prize.label||e} You won ${this._prize.name}!`);const r=this._modalEl.querySelector(".sc-modal-prize-box .sc-prize-name");r&&(r.textContent=this._prize.name);const s=this._modalEl.querySelector(".sc-btn-claim");s&&(s.textContent=`${i} ${this._prize.name}`)}}updateOptions(t){if(this._destroyed)return;if(!t||"object"!=typeof t)return void console.warn("[ScratchCard] updateOptions: argument must be an object. Ignoring.");f({...this.options,...t,container:this.options.container,prize:this.options.prize}),this.options=i({},this.options,t),t.theme&&(this.options.theme={...b.theme,...this.options.theme,...t.theme}),v(this.options);const n=this._rootEl?.querySelector(".sc-header h1");n&&void 0!==t.headerTitle&&(n.textContent=this.options.headerTitle),this._instructionEl&&void 0!==t.instruction&&(this._instructionEl.textContent=this.options.instruction),this._coinEl&&void 0!==t.coinIcon&&(this._coinEl.textContent=this.options.coinIcon),this._giftIconEl&&void 0!==t.giftIcon&&(this._giftIconEl.textContent=this.options.giftIcon)}_announceToScreenReader(t){if(w){if(!this._liveRegion){const t=document.createElement("div");t.setAttribute("aria-live","assertive"),t.setAttribute("aria-atomic","true"),t.setAttribute("role","status"),t.style.cssText="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;",document.body.appendChild(t),this._liveRegion=t}this._liveRegion.textContent="",setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent=t)},100)}}destroy(){this._destroyed||(this._destroyed=!0,this._confettiRafId&&(cancelAnimationFrame(this._confettiRafId),this._confettiRafId=null),this._confettiTimeouts&&(this._confettiTimeouts.forEach(clearTimeout),this._confettiTimeouts=[]),this._canvasEl&&(this._canvasEl.removeEventListener("mousedown",this._boundStartScratch),this._canvasEl.removeEventListener("mousemove",this._boundMoveScratch),this._canvasEl.removeEventListener("mouseup",this._boundEndScratch),this._canvasEl.removeEventListener("mouseleave",this._boundEndScratch),this._canvasEl.removeEventListener("touchstart",this._boundStartScratch),this._canvasEl.removeEventListener("touchmove",this._boundMoveScratch),this._canvasEl.removeEventListener("touchend",this._boundEndScratch),this._canvasEl.removeEventListener("touchcancel",this._boundEndScratch)),this._coinEl&&this._boundStartCoinDrag&&(this._coinEl.removeEventListener("mousedown",this._boundStartCoinDrag),this._coinEl.removeEventListener("touchstart",this._boundStartCoinDrag)),this._boundDocMouseMove&&(document.removeEventListener("mousemove",this._boundDocMouseMove),document.removeEventListener("mouseup",this._boundDocMouseUp),document.removeEventListener("touchmove",this._boundDocTouchMove),document.removeEventListener("touchend",this._boundDocTouchEnd),document.removeEventListener("touchcancel",this._boundDocTouchCancel)),this._modalEl&&this._boundModalClick&&this._modalEl.removeEventListener("click",this._boundModalClick),this._claimBtnEl&&this._boundClaimClick&&this._claimBtnEl.removeEventListener("click",this._boundClaimClick),this._boundDocKeydown&&document.removeEventListener("keydown",this._boundDocKeydown),this._liveRegion?.parentNode&&this._liveRegion.parentNode.removeChild(this._liveRegion),this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._modalEl&&this._modalEl.parentNode&&this._modalEl.parentNode.removeChild(this._modalEl),this._rootEl&&this._rootEl.parentNode&&this._rootEl.parentNode.removeChild(this._rootEl),this._rootEl=null,this._zoneEl=null,this._canvasEl=null,this._ctx=null,this._coinEl=null,this._giftIconEl=null,this._modalEl=null,this._confettiCanvasEl=null,this._prizeContentEl=null,this._instructionEl=null,this._prize=null,this._lastPoint=null,this._liveRegion=null,this._claimBtnEl=null)}get prize(){return this._prize}}const C={init:t=>new x(t),Instance:x,VERSION:"0.1.0-alpha.1",DEFAULTS:b},y=Object.freeze(["prize","headerTitle","headerTitleColor","instruction","instructionColor","revealThreshold","brushSize","coinSize","showCoin","coinIcon","coinGradientStart","coinGradientEnd","cardBackground","cardShadow","cardBorderRadius","scratchZoneBackground","scratchZoneShadow","scratchZoneBorderRadius","scratchLayerColor","scratchLayerSparkles","scratchLayerSparkleCount","prizeTextColor","prizeNameColor","prizeIconBackground","showGiftIcon","giftIcon","giftIconBackground","showModal","modalTitle","modalTitleColor","modalButtonText","modalButtonColor","modalButtonTextColor","modalBackdropBlur","confettiEnabled","confettiColors","confettiCount","confettiDuration","animationType","animationDuration","theme"]);function E(t){const{useEffect:n,useRef:e,useImperativeHandle:i,forwardRef:o,createElement:r}=t,s=o(function(t,o){const s=e(null),a=e(null),l=e({});return l.current.onScratchStart=t.onScratchStart,l.current.onScratchProgress=t.onScratchProgress,l.current.onReveal=t.onReveal,l.current.onClaim=t.onClaim,n(()=>{if(!s.current||"undefined"==typeof window)return;const n={};y.forEach(e=>{void 0!==t[e]&&(n[e]=t[e])}),n.container=s.current,n.onScratchStart=()=>l.current.onScratchStart?.(),n.onScratchProgress=t=>l.current.onScratchProgress?.(t),n.onReveal=t=>l.current.onReveal?.(t),n.onClaim=t=>l.current.onClaim?.(t);try{a.current=C.init(n)}catch(t){console.error("[ScratchCardReact] Failed to initialize ScratchCard:",t)}return()=>{try{a.current?.destroy()}catch(t){}a.current=null}},[]),n(()=>{if(a.current&&t.prize)try{a.current.updatePrize(t.prize)}catch(t){}},[t.prize]),i(o,()=>({reveal(){a.current?.reveal()},hideModal(){a.current?.hideModal()},showModal(){a.current?.showModal()},reset(){a.current?.reset()},updatePrize(t){a.current?.updatePrize(t)},updateOptions(t){a.current?.updateOptions(t)},get scratchPercent(){return a.current?.scratchPercent},get hasRevealed(){return a.current?.hasRevealed},get prize(){return a.current?.prize},get instance(){return a.current}}),[]),r("div",{ref:s,className:t.className||"",style:t.style||{}})});return s.displayName="ScratchCardReact",s}t.ScratchCardReact=null,"undefined"!=typeof window&&window.React&&(t.ScratchCardReact=E(window.React)),t.ScratchCard=C,t.ScratchCardInstance=x,t.SpinWheel=p,t.SpinWheelInstance=u,t.createScratchCardReact=E,t.createSpinWheelReact=g});
2
+ //# sourceMappingURL=spin-wheel-sdk.umd.min.js.map