@liiift-studio/threadtext 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  **Render any text as photorealistic, procedural satin-stitch embroidery — in real time, in the browser, from the font's actual glyph geometry.**
4
4
 
5
- > Status: **in-progress.** The framework-agnostic core (`createThreadText`) + React
6
- > hook/component are now extracted, typed, tested, and building to ESM/CJS/`.d.ts`. Still
7
- > to come: Framer/Webflow bindings and the landing site (and a free-licensed demo font).
8
- > The original reference renderer lives in [`demo/index.html`](./demo/index.html) and stays
9
- > the visual oracle. See [`HANDOFF.md`](./HANDOFF.md) for what's left; tool-build conventions
10
- > are in the monorepo [`../GUIDE.md`](../GUIDE.md).
5
+ > Status: **shipped.** Published to npm (`@liiift-studio/threadtext`) with a framework-agnostic
6
+ > core (`createThreadText`), a React hook + component, Framer and Webflow ports, tests, and a
7
+ > live landing site at [threadtext.com](https://threadtext.com) (demo font: the OFL Fraunces
8
+ > variable). The original single-file reference renderer lives in
9
+ > [`demo/index.html`](./demo/index.html) as the visual oracle; tool-build conventions are in the
10
+ > monorepo [`../GUIDE.md`](../GUIDE.md).
11
11
 
12
12
  Homepage: [threadtext.com](https://threadtext.com) · npm: `@liiift-studio/threadtext`
13
13
 
@@ -58,10 +58,12 @@ const thread = createThreadText(document.getElementById('host'), {
58
58
  weight: 680,
59
59
  })
60
60
 
61
- thread.setText('Threads') // appended letters sew in; unrelated text re-sews the word
62
- thread.replay() // re-run the full sew-in
63
- thread.resize() // re-fit to the container
64
- thread.destroy() // cancel rAF, remove listeners, free canvases
61
+ thread.setText('Threads') // re-fit to width and redraw instantly (no sew-in)
62
+ thread.update({ threadColor: '#e6c200', fill: 0.8 }) // live changes instant, no re-sew
63
+ thread.replay() // re-run the sew-in animation
64
+ thread.resize() // re-fit to the container
65
+ thread.focus() // focus the surface for typing (editable mode)
66
+ thread.destroy() // cancel rAF, remove listeners, free canvases
65
67
  ```
66
68
 
67
69
  React:
@@ -74,13 +76,17 @@ import { ThreadText } from '@liiift-studio/threadtext'
74
76
 
75
77
  Thread colour, `fill` (size — the word re-fits to the container width on load/resize),
76
78
  `weight`, `font`, `sewRate`, `sheen`, `animate`, and `editable` (type straight on the
77
- artwork) are all options see `ThreadTextOptions`. Change any of them live with
79
+ artwork backed by a real input, so touch keyboards and IME work) with an `onTextChange`
80
+ callback are all options — see `ThreadTextOptions`. Change any of them live with
78
81
  `instance.update(...)` — it redraws instantly, never re-running the sew-in. `react`/`react-dom`
79
82
  are optional peers; the core is framework-free.
80
83
 
81
84
  ## What's next
82
85
 
83
- The renderer is proven. Finishing it means productionising per [`../GUIDE.md`](../GUIDE.md): extract a framework-agnostic **core** with a typed API, add the **React hook + component**, **Framer** + **Webflow** bindings, tests, a landing **site**, then ship (npm + Vercel). A proposed core API and step-by-step plan are in `HANDOFF.md`.
86
+ Now shipped. Remaining ideas (see `HANDOFF.md`): region-limit or move the per-keystroke geometry
87
+ rebuild to a Web Worker/WASM (it currently re-runs the full distance-transform pipeline on every
88
+ edit); real variable-font axis control (`opsz`/`wght`) via path-based glyph rendering, since canvas
89
+ `fillText` can't set `font-variation-settings`; and additional stitch modes (chain, cross, running).
84
90
 
85
91
  ---
86
92
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const X=require("react"),xe=require("react/jsx-runtime"),pt={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function Q(m,e){let o=Math.imul(m|0,374761393)+Math.imul(e|0,668265263)|0;return o=Math.imul(o^o>>>13,1274126177),((o^o>>>16)>>>0)/4294967295}function Qt(m,e){const o=Math.floor(m),r=Math.floor(e),i=m-o,a=e-r,f=i*i*(3-2*i),A=a*a*(3-2*a),E=Q(o,r),C=Q(o+1,r),c=Q(o,r+1),d=Q(o+1,r+1);return E+(C-E)*f+(c-E)*A+(E-C-c+d)*f*A}const Mt=1e20;function Zt(m,e,o,r,i){let a=0;r[0]=0,i[0]=-Mt,i[1]=Mt;for(let f=1;f<e;f++){let A=(m[f]+f*f-(m[r[a]]+r[a]*r[a]))/(2*f-2*r[a]);for(;A<=i[a];)a--,A=(m[f]+f*f-(m[r[a]]+r[a]*r[a]))/(2*f-2*r[a]);a++,r[a]=f,i[a]=A,i[a+1]=Mt}a=0;for(let f=0;f<e;f++){for(;i[a+1]<f;)a++;o[f]=(f-r[a])*(f-r[a])+m[r[a]]}}function ge(m,e,o){const r=new Float64Array(e*o);for(let c=0;c<e*o;c++)r[c]=m[c]?Mt:0;const i=Math.max(e,o),a=new Float64Array(i),f=new Float64Array(i),A=new Int32Array(i),E=new Float64Array(i+1);for(let c=0;c<e;c++){for(let d=0;d<o;d++)a[d]=r[d*e+c];Zt(a,o,f,A,E);for(let d=0;d<o;d++)r[d*e+c]=f[d]}for(let c=0;c<o;c++){for(let d=0;d<e;d++)a[d]=r[c*e+d];Zt(a,e,f,A,E);for(let d=0;d<e;d++)r[c*e+d]=f[d]}const C=new Float32Array(e*o);for(let c=0;c<e*o;c++)C[c]=Math.sqrt(r[c]);return C}function Ht(m,e,o,r,i){let a=Float32Array.from(m);const f=new Float32Array(e*o),A=1/(2*r+1),E=(C,c)=>C<0?0:C>c?c:C;for(let C=0;C<i;C++){for(let c=0;c<o;c++){const d=c*e;let $=0;for(let B=-r;B<=r;B++)$+=a[d+E(B,e-1)];for(let B=0;B<e;B++)f[d+B]=$*A,$+=a[d+E(B+r+1,e-1)]-a[d+E(B-r,e-1)]}for(let c=0;c<e;c++){let d=0;for(let $=-r;$<=r;$++)d+=f[E($,o-1)*e+c];for(let $=0;$<o;$++)a[$*e+c]=d*A,d+=f[E($+r+1,o-1)*e+c]-f[E($-r,o-1)*e+c]}}return a}function Wt(m,e){if(!m)return e;const o=m.trim();if(o[0]==="#"){let i=o.slice(1);if(i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),i.length>=6){const a=parseInt(i.slice(0,2),16),f=parseInt(i.slice(2,4),16),A=parseInt(i.slice(4,6),16);if(!Number.isNaN(a)&&!Number.isNaN(f)&&!Number.isNaN(A))return[a,f,A]}return e}const r=o.match(/rgba?\(([^)]+)\)/i);if(r){const i=r[1].split(",").map(a=>parseFloat(a));if(i.length>=3&&i.slice(0,3).every(a=>!Number.isNaN(a)))return[Math.round(i[0]),Math.round(i[1]),Math.round(i[2])]}return e}function K(m){return m<0?0:m>255?255:Math.round(m)}function te(m){return(m.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function ee(m,e){if(typeof window>"u"||typeof document>"u"||!m)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return e.text??""}};let o=e.text??"",r=e.font??"Georgia, serif",i=e.weight??680,a=e.fill??.9,f=e.sewRate??110,A=e.sheen??!0,E=e.animate??!0,C=e.editable??!1,c=e.pitch,d=e.onTextChange,$=te(r);const B=e.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let D=Wt(e.threadColor??"#fffbf3",[255,251,243]),tt=[0,0,0],N=[0,0,0];function et(t){D=Wt(t,[255,251,243]),tt=[D[0]*.585,D[1]*.585,D[2]*.585],N=[D[0]*.47,D[1]*.47,D[2]*.47]}et(e.threadColor??"#fffbf3");const G=[];let P,g;m instanceof HTMLCanvasElement?(P=m,g=m.parentElement??m):(g=m,P=document.createElement("canvas"),G.push(P),g.appendChild(P)),P.classList.add(pt.bg);const O=document.createElement("canvas");G.push(O),O.classList.add(pt.fx),g.appendChild(O),getComputedStyle(g).position==="static"&&(g.style.position="relative"),P.style.display="block",P.style.width="100%",Object.assign(O.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let S=null,Z=!1,s=0,h=0,H=0,bt=0,ft=4,nt=[],ot=0,rt=0,Ct=new Uint8Array(0),Tt=new Float32Array(0),ut=new Float32Array(0),dt=new Float32Array(0),U=null,it=null,ht=null,mt=[],yt=3;const L={rows:[],idx:0,acc:0,rate:0,on:!1},Y={x:0,y:0,set:!1};let W=!0,vt=0,Bt=!1,xt=0,q=!1,J=!1;function re(){const t=g.getBoundingClientRect(),n=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),l=o||"Ag",y=P.getContext("2d");let T=100;y&&(y.font=`${i} 100px ${r}`,T=y.measureText(l).width||100);let b=Math.max(8,100*(n*a)/T),v=b*.7,R=b*.3,I=n*a;if(y){y.font=`${i} ${b}px ${r}`;const p=y.measureText(l);I=p.width||I,p.actualBoundingBoxAscent>0&&(v=p.actualBoundingBoxAscent),p.actualBoundingBoxDescent>0&&(R=p.actualBoundingBoxDescent)}const w=Math.max(1,Math.round(2*Math.max(v,R)*1.12));let u=Math.min(window.devicePixelRatio||1,1.7);for(;n*u*w*u>9e5&&u>.4;)u-=.1;s=Math.max(1,Math.round(n*u)),h=Math.max(1,Math.round(w*u)),H=Math.max(4,Math.round(b*u)),bt=Math.round(s/2-I*u/2);for(const p of[P,O])p.width=s,p.height=h,p.style.height=w+"px";g.style.height=w+"px",ft=c??Math.max(3,h*.0095)}function ie(){it=document.createElement("canvas"),it.width=s,it.height=h,ht=it.getContext("2d",{willReadFrequently:!0})}function Nt(){const t=Math.max(7,ft*2.5),n=Math.max(3.2,ft*1.3);ot=Math.ceil(t)+2,rt=Math.ceil(n)+2,nt=[];for(let l=0;l<20;l++){const y=.34+l/19*.82,T=document.createElement("canvas");T.width=ot,T.height=rt;const b=T.getContext("2d");if(!b){nt.push(T);continue}const v=ot/2,R=rt/2,I=b.createLinearGradient(0,R-n/2,0,R+n/2),w=(k,j)=>`rgba(${K(k[0]*y)},${K(k[1]*y)},${K(k[2]*y)},${j})`;I.addColorStop(0,w(N,0)),I.addColorStop(.16,w(tt,1)),I.addColorStop(.5,w(D,1)),I.addColorStop(.84,w(tt,1)),I.addColorStop(1,w(N,0)),b.fillStyle=I,b.beginPath();const u=n/2;b.moveTo(v-t/2+u,R-u),b.lineTo(v+t/2-u,R-u),b.arc(v+t/2-u,R,u,-Math.PI/2,Math.PI/2),b.lineTo(v-t/2+u,R+u),b.arc(v-t/2+u,R,u,Math.PI/2,-Math.PI/2),b.closePath(),b.fill(),b.globalCompositeOperation="destination-in";const p=b.createLinearGradient(v-t/2,0,v+t/2,0);p.addColorStop(0,"rgba(0,0,0,0)"),p.addColorStop(.22,"rgba(0,0,0,1)"),p.addColorStop(.78,"rgba(0,0,0,1)"),p.addColorStop(1,"rgba(0,0,0,0)"),b.fillStyle=p,b.fillRect(0,0,ot,rt),nt.push(T)}}function ae(){if(!ht)return;const t=ht;t.clearRect(0,0,s,h),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${i} ${H}px ${r}`,t.fillText(o,bt,h*.5);const n=t.getImageData(0,0,s,h).data,l=new Uint8Array(s*h);for(let x=0;x<h;x++)for(let M=0;M<s;M++){const F=x*s+M,_=n[F*4+3]/255,z=Qt(M*.5,x*.5)*.22+Qt(M*1.8,x*1.8)*.1;l[F]=_>.5+(z-.16)?1:0}Ct=l;const y=ge(l,s,h),T=new Float32Array(s*h);for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const F=x*s+M;T[F]=(y[F]*4+y[F-1]+y[F+1]+y[F-s]+y[F+s])/8}const b=new Float32Array(s*h),v=new Float32Array(s*h),R=new Float32Array(s*h),I=new Float32Array(s*h);for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const F=x*s+M;if(!l[F])continue;const _=(T[F+1]-T[F-1])*.5,z=(T[F+s]-T[F-s])*.5;R[F]=_,I[F]=z,b[F]=_*_-z*z,v[F]=2*_*z}const w=Math.max(7,Math.round(h*.05)),u=Ht(b,s,h,w,2),p=Ht(v,s,h,w,2);ut=new Float32Array(s*h),dt=new Float32Array(s*h);for(let x=0;x<s*h;x++){if(!l[x])continue;const M=.5*Math.atan2(p[x],u[x]);ut[x]=Math.cos(M),dt[x]=Math.sin(M)}const k=Math.max(9,h*.04),j=new Float32Array(s*h),ct=-.45,st=-.62,wt=.64;for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const F=x*s+M;if(!l[F])continue;let _=R[F],z=I[F];const Ut=Math.hypot(_,z)||1;_/=Ut,z/=Ut;const Vt=T[F],Yt=(1-Math.min(Vt/k,1))*1.25;let It=-_*Yt,Pt=-z*Yt;const Jt=1.5,Dt=Math.hypot(It,Pt,Jt);It/=Dt,Pt/=Dt;let kt=It*ct+Pt*st+Jt/Dt*wt;kt<0&&(kt=0);const ye=Math.min(1,.45+.55*Math.min(Vt/(k*.7),1));j[F]=Math.min(1.12,(.5+.75*kt)*ye)}Tt=j,U=document.createElement("canvas"),U.width=s,U.height=h;const V=U.getContext("2d");if(V){const x=V.createImageData(s,h);for(let M=0;M<s*h;M++)l[M]&&(x.data[M*4]=255,x.data[M*4+1]=255,x.data[M*4+2]=255,x.data[M*4+3]=255);V.putImageData(x,0,0)}}function le(){const t=Math.max(1.6,ft*.6);yt=t;const n=[];for(let l=0;l<h;l+=t)for(let y=0;y<s;y+=t){const T=(Q(Math.floor(y),Math.floor(l))-.5)*t*.9,b=(Q(Math.floor(l),Math.floor(y))-.5)*t*.9,v=Math.round(y+T),R=Math.round(l+b);if(v<1||R<1||v>=s-1||R>=h-1)continue;const I=R*s+v;if(!Ct[I])continue;const w=Math.atan2(dt[I],ut[I]),u=.86+Q(v*7,R*13)*.18;let p=Tt[I]*u;p=p<0?0:p>1.12?1.12:p,n.push({x:v,y:R,ang:w,idx:Math.min(19,Math.max(0,Math.round(p/1.12*19)))})}n.sort((l,y)=>l.x-y.x),mt=n}function Ot(t,n){t.save(),t.translate(n.x,n.y),t.rotate(n.ang),t.drawImage(nt[n.idx],-ot/2,-rt/2),t.restore()}function At(){const t=P.getContext("2d");if(t)for(const n of mt)Ot(t,n)}function Et(){const t=P.getContext("2d");t&&t.clearRect(0,0,s,h)}function ce(t){if(!t.length)return[];const n=Math.max(4,yt*1.5),l=new Map,y=(w,u)=>w+","+u;t.forEach((w,u)=>{const p=y(Math.floor(w.x/n),Math.floor(w.y/n));let k=l.get(p);k||l.set(p,k=[]),k.push(u)});const T=yt*1.8*(yt*1.8);function b(w){const u=t[w],p=Math.floor(u.x/n),k=Math.floor(u.y/n),j=[];for(let ct=-1;ct<=1;ct++)for(let st=-1;st<=1;st++){const wt=l.get(y(p+ct,k+st));if(wt)for(const V of wt){if(V===w)continue;const x=t[V].x-u.x,M=t[V].y-u.y;x*x+M*M<=T&&j.push(V)}}return j}const v=new Uint8Array(t.length),R=[],I=t.map((w,u)=>u).sort((w,u)=>t[w].x+t[w].y-(t[u].x+t[u].y));for(const w of I){if(v[w])continue;let u=[w];for(v[w]=1;u.length;){R.push(u.map(k=>t[k]));const p=[];for(const k of u)for(const j of b(k))v[j]||(v[j]=1,p.push(j));u=p}}return R}function se(){if(Et(),B||!E){At(),L.on=!1;return}L.rows=ce(mt),L.idx=0,L.acc=0,L.rate=f,L.on=L.rows.length>0}function fe(t){const n=P.getContext("2d");if(n)for(t>L.rows.length&&(t=L.rows.length);L.idx<t;){const l=L.rows[L.idx++];for(const y of l)Ot(n,y)}}function ue(t,n){const l=O.getContext("2d");if(!l||(l.clearRect(0,0,s,h),!A||!U))return;const y=s*.32,T=l.createRadialGradient(t,n,0,t,n,y);T.addColorStop(0,"rgba(255,250,238,0.18)"),T.addColorStop(.5,"rgba(255,250,238,0.055)"),T.addColorStop(1,"rgba(255,250,238,0)"),l.fillStyle=T,l.fillRect(0,0,s,h),l.globalCompositeOperation="destination-in",l.drawImage(U,0,0),l.globalCompositeOperation="source-over"}function de(){S||!C||(S=document.createElement("span"),S.className=pt.caret,S.setAttribute("aria-hidden","true"),Object.assign(S.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${K(D[0])},${K(D[1])},${K(D[2])})`}),g.appendChild(S),G.push(S))}function St(){if(!C||!S)return;const t=P.getContext("2d");if(!t)return;t.font=`${i} ${H}px ${r}`;const n=t.measureText(o).width,l=(P.clientWidth||s)/s,y=H*.7;S.style.left=(bt+n+H*.05)*l+"px",S.style.top=.5*(P.clientHeight||h)-y*l/2+"px",S.style.height=y*l+"px",S.style.width=Math.max(2,Math.round(H*.02*l))+"px",S.style.background=`rgb(${K(D[0])},${K(D[1])},${K(D[2])})`}function jt(t){if(q)return;xt||(xt=t);const n=Math.min(.25,(t-xt)/1e3);xt=t,L.on&&(L.acc+=L.rate*n,fe(L.acc),L.idx>=L.rows.length&&(L.on=!1)),W&&U&&(ue(Y.set?Y.x:s*.5,Y.set?Y.y:h*.34),W=!1),S&&(S.style.opacity=C&&Z&&Math.floor(t/530)%2===0?"1":"0"),vt=requestAnimationFrame(jt)}function gt(t){const n=O.getBoundingClientRect();Y.x=(t.clientX-n.left)/(n.width||1)*s,Y.y=(t.clientY-n.top)/(n.height||1)*h,Y.set=!0,W=!0}function qt(t){if(!(!C||t.metaKey||t.ctrlKey||t.altKey)){if(t.key==="Backspace"){t.preventDefault(),Rt(o.slice(0,-1),!0);return}if(t.key==="Enter"){t.preventDefault(),$t.replay();return}[...t.key].length===1&&(t.preventDefault(),Rt(o+t.key,!0))}}function _t(){Z=!0}function zt(){Z=!1,S&&(S.style.opacity="0")}function Kt(){C&&g.focus()}function Ft(t){C=t,t?(g.tabIndex=0,g.setAttribute("role","textbox"),g.getAttribute("aria-label")||g.setAttribute("aria-label","Editable embroidered text — type to change it"),de(),g.addEventListener("keydown",qt),g.addEventListener("focus",_t),g.addEventListener("blur",zt),g.addEventListener("pointerdown",Kt),St()):(g.removeAttribute("tabindex"),g.removeAttribute("role"),g.removeEventListener("keydown",qt),g.removeEventListener("focus",_t),g.removeEventListener("blur",zt),g.removeEventListener("pointerdown",Kt),S&&(S.style.opacity="0"))}function he(t){if(t!==A)if(A=t,t)window.addEventListener("pointermove",gt,{passive:!0}),W=!0;else{window.removeEventListener("pointermove",gt);const n=O.getContext("2d");n&&n.clearRect(0,0,s,h)}}function at(t){re(),ie(),Nt(),ae(),le(),t?se():(Et(),At(),L.on=!1),St(),W=!0}function Rt(t,n){t=t??"",!(t===o&&J)&&(o=t,J&&(at(!1),n&&d&&d(o)))}let lt;function Xt(t,n,l){const y=`${n} 200px ${t}`;let T=!1;try{T=!!document.fonts&&document.fonts.check(y)}catch{T=!0}if(!document.fonts||T){l();return}let b=!1;const v=()=>{b||(b=!0,lt&&clearTimeout(lt),l())};document.fonts.load(y,o).then(()=>document.fonts.ready).then(v,v),lt=setTimeout(v,1500)}function me(){q||(at(!0),J=!0,Bt||(Bt=!0,vt=requestAnimationFrame(jt)))}C&&Ft(!0),A&&window.addEventListener("pointermove",gt,{passive:!0}),Xt($,i,me);let Lt;function Gt(){clearTimeout(Lt),Lt=setTimeout(()=>$t.resize(),200)}window.addEventListener("resize",Gt);const $t={get text(){return o},setText(t){if(!q){if(!J){o=t??"";return}Rt(t,!1)}},replay(){q||!J||at(!0)},resize(){q||!J||at(!1)},update(t){if(q)return;let n=!1,l=!1;t.font!==void 0&&t.font!==r&&(r=t.font,$=te(r),n=!0),t.weight!==void 0&&t.weight!==i&&(i=t.weight,n=!0),t.fill!==void 0&&t.fill!==a&&(a=t.fill,n=!0),t.pitch!==void 0&&t.pitch!==c&&(c=t.pitch,n=!0),t.threadColor!==void 0&&(et(t.threadColor),l=!0),t.sewRate!==void 0&&(f=t.sewRate),t.animate!==void 0&&(E=t.animate),t.onTextChange!==void 0&&(d=t.onTextChange),t.sheen!==void 0&&he(t.sheen),t.editable!==void 0&&t.editable!==C&&Ft(t.editable),J&&(n?Xt($,i,()=>{q||at(!1)}):l&&(Nt(),Et(),At(),St()),W=!0)},focus(){!q&&C&&g.focus()},destroy(){if(!q){q=!0,cancelAnimationFrame(vt),clearTimeout(Lt),lt&&clearTimeout(lt),window.removeEventListener("resize",Gt),window.removeEventListener("pointermove",gt),C&&Ft(!1);for(const t of G)t.remove();nt=[],mt=[],L.rows=[],Ct=new Uint8Array(0),Tt=new Float32Array(0),ut=new Float32Array(0),dt=new Float32Array(0),U=it=null,ht=null,S=null}}};return $t}function ne(m){const e=X.useRef(null),o=X.useRef(null),r=X.useRef(m);r.current=m;const i=X.useRef(m.onTextChange);i.current=m.onTextChange;const{text:a,font:f,weight:A,threadColor:E,pitch:C,fill:c,animate:d,sewRate:$,sheen:B,editable:D,reducedMotion:tt}=m;return X.useLayoutEffect(()=>{const N=e.current;if(!N)return;const et=ee(N,{...r.current,onTextChange:O=>{var S;return(S=i.current)==null?void 0:S.call(i,O)}});o.current=et;let G=0,P=0,g;return typeof ResizeObserver<"u"&&(g=new ResizeObserver(O=>{const S=Math.round(O[0].contentRect.width);S!==P&&(P=S,cancelAnimationFrame(G),G=requestAnimationFrame(()=>{var Z;return(Z=o.current)==null?void 0:Z.resize()}))}),g.observe(N)),()=>{g==null||g.disconnect(),cancelAnimationFrame(G),et.destroy(),o.current=null}},[tt]),X.useEffect(()=>{var N;(N=o.current)==null||N.update({font:f,weight:A,threadColor:E,pitch:C,fill:c,animate:d,sewRate:$,sheen:B,editable:D})},[f,A,E,C,c,d,$,B,D]),X.useEffect(()=>{var N;(N=o.current)==null||N.setText(a)},[a]),e}const oe=X.forwardRef(function({className:e,style:o,as:r="div","aria-label":i,role:a,"aria-describedby":f,...A},E){const C=ne(A),c=X.useCallback(d=>{C.current=d,typeof E=="function"?E(d):E&&(E.current=d)},[C,E]);return xe.jsx(r,{ref:c,className:e,style:o,role:a??"img","aria-label":i??A.text,"aria-describedby":f})});oe.displayName="ThreadText";exports.THREAD_TEXT_CLASSES=pt;exports.ThreadText=oe;exports.createThreadText=ee;exports.useThreadText=ne;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const V=require("react"),At=require("react/jsx-runtime"),Te={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function W(h,t){let n=Math.imul(h|0,374761393)+Math.imul(t|0,668265263)|0;return n=Math.imul(n^n>>>13,1274126177),((n^n>>>16)>>>0)/4294967295}function tt(h,t){const n=Math.floor(h),r=Math.floor(t),i=h-n,a=t-r,u=i*i*(3-2*i),b=a*a*(3-2*a),S=W(n,r),E=W(n+1,r),c=W(n,r+1),m=W(n+1,r+1);return S+(E-S)*u+(c-S)*b+(S-E-c+m)*u*b}const Ee=1e20;function nt(h,t,n,r,i){let a=0;r[0]=0,i[0]=-Ee,i[1]=Ee;for(let u=1;u<t;u++){let b=(h[u]+u*u-(h[r[a]]+r[a]*r[a]))/(2*u-2*r[a]);for(;b<=i[a];)a--,b=(h[u]+u*u-(h[r[a]]+r[a]*r[a]))/(2*u-2*r[a]);a++,r[a]=u,i[a]=b,i[a+1]=Ee}a=0;for(let u=0;u<t;u++){for(;i[a+1]<u;)a++;n[u]=(u-r[a])*(u-r[a])+h[r[a]]}}function St(h,t,n){const r=new Float64Array(t*n);for(let c=0;c<t*n;c++)r[c]=h[c]?Ee:0;const i=Math.max(t,n),a=new Float64Array(i),u=new Float64Array(i),b=new Int32Array(i),S=new Float64Array(i+1);for(let c=0;c<t;c++){for(let m=0;m<n;m++)a[m]=r[m*t+c];nt(a,n,u,b,S);for(let m=0;m<n;m++)r[m*t+c]=u[m]}for(let c=0;c<n;c++){for(let m=0;m<t;m++)a[m]=r[c*t+m];nt(a,t,u,b,S);for(let m=0;m<t;m++)r[c*t+m]=u[m]}const E=new Float32Array(t*n);for(let c=0;c<t*n;c++)E[c]=Math.sqrt(r[c]);return E}function ot(h,t,n,r,i){let a=Float32Array.from(h);const u=new Float32Array(t*n),b=1/(2*r+1),S=(E,c)=>E<0?0:E>c?c:E;for(let E=0;E<i;E++){for(let c=0;c<n;c++){const m=c*t;let I=0;for(let N=-r;N<=r;N++)I+=a[m+S(N,t-1)];for(let N=0;N<t;N++)u[m+N]=I*b,I+=a[m+S(N+r+1,t-1)]-a[m+S(N-r,t-1)]}for(let c=0;c<t;c++){let m=0;for(let I=-r;I<=r;I++)m+=u[S(I,n-1)*t+c];for(let I=0;I<n;I++)a[I*t+c]=m*b,m+=u[S(I+r+1,n-1)*t+c]-u[S(I-r,n-1)*t+c]}}return a}function rt(h,t){if(!h)return t;const n=h.trim();if(n[0]==="#"){let i=n.slice(1);if(i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),i.length>=6){const a=parseInt(i.slice(0,2),16),u=parseInt(i.slice(2,4),16),b=parseInt(i.slice(4,6),16);if(!Number.isNaN(a)&&!Number.isNaN(u)&&!Number.isNaN(b))return[a,u,b]}return t}const r=n.match(/rgba?\(([^)]+)\)/i);if(r){const i=r[1].split(",").map(a=>parseFloat(a));if(i.length>=3&&i.slice(0,3).every(a=>!Number.isNaN(a)))return[Math.round(i[0]),Math.round(i[1]),Math.round(i[2])]}return t}function K(h){return h<0?0:h>255?255:Math.round(h)}function be(h,t,n){return h<t?t:h>n?n:h}function it(h){return(h.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function at(h,t){if(typeof window>"u"||typeof document>"u"||!h)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return t.text??""}};let n=t.text??"",r=t.font??"Georgia, serif",i=be(t.weight??680,1,1e3),a=be(t.fill??.9,.05,1),u=Math.max(1,t.sewRate??110),b=t.sheen??!0,S=t.animate??!0,E=t.editable??!1,c=t.pitch,m=t.onTextChange,I=it(r);const N=t.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let B=rt(t.threadColor??"#fffbf3",[255,251,243]),ae=[0,0,0],D=[0,0,0];function le(e){B=rt(e,[255,251,243]),ae=[B[0]*.585,B[1]*.585,B[2]*.585],D=[B[0]*.47,B[1]*.47,B[2]*.47]}le(t.threadColor??"#fffbf3");const G=[];let O,L;h instanceof HTMLCanvasElement?(O=h,L=h.parentElement??h):(L=h,O=document.createElement("canvas"),G.push(O),L.appendChild(O)),O.classList.add(Te.bg);const j=document.createElement("canvas");G.push(j),j.classList.add(Te.fx),L.appendChild(j),getComputedStyle(L).position==="static"&&(L.style.position="relative"),O.style.display="block",O.style.width="100%",Object.assign(j.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let y=null,A=null,Q=!1,s=0,x=0,ee=0,Ae=0,te=4,ne=[],se=0,ce=0,je=-1,qe="",ze=-1,_e=-1,Se=new Uint8Array(0),Fe=new Float32Array(0),me=new Float32Array(0),xe=new Float32Array(0),Y=null,oe=null,ye=null,ge=[],pe=3;const $={rows:[],idx:0,acc:0,rate:0,on:!1},U={x:0,y:0,set:!1};let Z=!0,Re=0,fe=!1,ue=0,q=!1,H=!1;function ct(){const e=L.getBoundingClientRect(),o=Math.max(1,Math.round(e.width||Math.min(window.innerWidth*.95,1240))),l=n||"Ag",f=O.getContext("2d");f&&(f.textBaseline="middle");let T=100;f&&(f.font=`${i} 100px ${r}`,T=f.measureText(l).width||100);const C=Math.max(8,100*(o*a)/T);let v=C*.62,F=C*.62,P=o*a;if(f){f.font=`${i} ${C}px ${r}`;const w=f.measureText(l);P=w.width||P,w.actualBoundingBoxAscent>0&&(v=w.actualBoundingBoxAscent),w.actualBoundingBoxDescent>0&&(F=w.actualBoundingBoxDescent)}const p=Math.max(1,Math.round(2*Math.max(v,F)*1.1));let d=Math.min(window.devicePixelRatio||1,1.7);for(;o*d*p*d>9e5&&d>.4;)d-=.1;s=Math.max(1,Math.round(o*d)),x=Math.max(1,Math.round(p*d)),ee=Math.max(4,Math.round(C*d)),Ae=Math.round(s/2-P*d/2);for(const w of[O,j])w.width=s,w.height=x,w.style.height=p+"px";L.style.height=p+"px",te=c??Math.max(3,x*.0095)}function ft(){oe&&ze===s&&_e===x||(oe=document.createElement("canvas"),oe.width=s,oe.height=x,ye=oe.getContext("2d",{willReadFrequently:!0}),ze=s,_e=x)}function Xe(){const e=Math.max(7,te*2.5),o=Math.max(3.2,te*1.3);se=Math.ceil(e)+2,ce=Math.ceil(o)+2,ne=[];for(let l=0;l<20;l++){const f=.34+l/19*.82,T=document.createElement("canvas");T.width=se,T.height=ce;const C=T.getContext("2d");if(!C){ne.push(T);continue}const v=se/2,F=ce/2,P=C.createLinearGradient(0,F-o/2,0,F+o/2),p=(k,z)=>`rgba(${K(k[0]*f)},${K(k[1]*f)},${K(k[2]*f)},${z})`;P.addColorStop(0,p(D,0)),P.addColorStop(.16,p(ae,1)),P.addColorStop(.5,p(B,1)),P.addColorStop(.84,p(ae,1)),P.addColorStop(1,p(D,0)),C.fillStyle=P,C.beginPath();const d=o/2;C.moveTo(v-e/2+d,F-d),C.lineTo(v+e/2-d,F-d),C.arc(v+e/2-d,F,d,-Math.PI/2,Math.PI/2),C.lineTo(v-e/2+d,F+d),C.arc(v-e/2+d,F,d,Math.PI/2,-Math.PI/2),C.closePath(),C.fill(),C.globalCompositeOperation="destination-in";const w=C.createLinearGradient(v-e/2,0,v+e/2,0);w.addColorStop(0,"rgba(0,0,0,0)"),w.addColorStop(.22,"rgba(0,0,0,1)"),w.addColorStop(.78,"rgba(0,0,0,1)"),w.addColorStop(1,"rgba(0,0,0,0)"),C.fillStyle=w,C.fillRect(0,0,se,ce),ne.push(T)}je=te,qe=B.join(",")}function ut(){ne.length&&je===te&&qe===B.join(",")||Xe()}function dt(){if(!ye)return;const e=ye;e.clearRect(0,0,s,x),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="middle",e.font=`${i} ${ee}px ${r}`,e.fillText(n,Ae,x*.5);const o=e.getImageData(0,0,s,x).data,l=new Uint8Array(s*x);for(let g=0;g<x;g++)for(let M=0;M<s;M++){const R=g*s+M,_=o[R*4+3]/255,X=tt(M*.5,g*.5)*.22+tt(M*1.8,g*1.8)*.1;l[R]=_>.5+(X-.16)?1:0}Se=l;const f=St(l,s,x),T=new Float32Array(s*x);for(let g=1;g<x-1;g++)for(let M=1;M<s-1;M++){const R=g*s+M;T[R]=(f[R]*4+f[R-1]+f[R+1]+f[R-s]+f[R+s])/8}const C=new Float32Array(s*x),v=new Float32Array(s*x),F=new Float32Array(s*x),P=new Float32Array(s*x);for(let g=1;g<x-1;g++)for(let M=1;M<s-1;M++){const R=g*s+M;if(!l[R])continue;const _=(T[R+1]-T[R-1])*.5,X=(T[R+s]-T[R-s])*.5;F[R]=_,P[R]=X,C[R]=_*_-X*X,v[R]=2*_*X}const p=Math.max(7,Math.round(x*.05)),d=ot(C,s,x,p,2),w=ot(v,s,x,p,2);me=new Float32Array(s*x),xe=new Float32Array(s*x);for(let g=0;g<s*x;g++){if(!l[g])continue;const M=.5*Math.atan2(w[g],d[g]);me[g]=Math.cos(M),xe[g]=Math.sin(M)}const k=Math.max(9,x*.04),z=new Float32Array(s*x),de=-.45,he=-.62,ve=.64;for(let g=1;g<x-1;g++)for(let M=1;M<s-1;M++){const R=g*s+M;if(!l[R])continue;let _=F[R],X=P[R];const Qe=Math.hypot(_,X)||1;_/=Qe,X/=Qe;const Ze=T[R],We=(1-Math.min(Ze/k,1))*1.25;let Oe=-_*We,ke=-X*We;const et=1.5,Ne=Math.hypot(Oe,ke,et);Oe/=Ne,ke/=Ne;let De=Oe*de+ke*he+et/Ne*ve;De<0&&(De=0);const Et=Math.min(1,.45+.55*Math.min(Ze/(k*.7),1));z[R]=Math.min(1.12,(.5+.75*De)*Et)}Fe=z,Y=document.createElement("canvas"),Y.width=s,Y.height=x;const J=Y.getContext("2d");if(J){const g=J.createImageData(s,x);for(let M=0;M<s*x;M++)l[M]&&(g.data[M*4]=255,g.data[M*4+1]=255,g.data[M*4+2]=255,g.data[M*4+3]=255);J.putImageData(g,0,0)}}function ht(){const e=Math.max(1.6,te*.6);pe=e;const o=[];for(let l=0;l<x;l+=e)for(let f=0;f<s;f+=e){const T=(W(Math.floor(f),Math.floor(l))-.5)*e*.9,C=(W(Math.floor(l),Math.floor(f))-.5)*e*.9,v=Math.round(f+T),F=Math.round(l+C);if(v<1||F<1||v>=s-1||F>=x-1)continue;const P=F*s+v;if(!Se[P])continue;const p=Math.atan2(xe[P],me[P]),d=.86+W(v*7,F*13)*.18;let w=Fe[P]*d;w=w<0?0:w>1.12?1.12:w,o.push({x:v,y:F,ang:p,idx:Math.min(19,Math.max(0,Math.round(w/1.12*19)))})}ge=o}function Ge(e,o){e.save(),e.translate(o.x,o.y),e.rotate(o.ang),e.drawImage(ne[o.idx],-se/2,-ce/2),e.restore()}function Le(){const e=O.getContext("2d");if(e)for(const o of ge)Ge(e,o)}function $e(){const e=O.getContext("2d");e&&e.clearRect(0,0,s,x)}function mt(e){if(!e.length)return[];const o=Math.max(4,pe*1.5),l=new Map,f=(p,d)=>p+","+d;e.forEach((p,d)=>{const w=f(Math.floor(p.x/o),Math.floor(p.y/o));let k=l.get(w);k||l.set(w,k=[]),k.push(d)});const T=pe*1.8*(pe*1.8);function C(p){const d=e[p],w=Math.floor(d.x/o),k=Math.floor(d.y/o),z=[];for(let de=-1;de<=1;de++)for(let he=-1;he<=1;he++){const ve=l.get(f(w+de,k+he));if(ve)for(const J of ve){if(J===p)continue;const g=e[J].x-d.x,M=e[J].y-d.y;g*g+M*M<=T&&z.push(J)}}return z}const v=new Uint8Array(e.length),F=[],P=e.map((p,d)=>d).sort((p,d)=>e[p].x+e[p].y-(e[d].x+e[d].y));for(const p of P){if(v[p])continue;let d=[p];for(v[p]=1;d.length;){F.push(d.map(k=>e[k]));const w=[];for(const k of d)for(const z of C(k))v[z]||(v[z]=1,w.push(z));d=w}}return F}function xt(){if($e(),N||!S){Le(),$.on=!1;return}$.rows=mt(ge),$.idx=0,$.acc=0,$.rate=u,$.on=$.rows.length>0}function yt(e){const o=O.getContext("2d");if(o)for(e>$.rows.length&&(e=$.rows.length);$.idx<e;){const l=$.rows[$.idx++];for(const f of l)Ge(o,f)}}function gt(e,o){const l=j.getContext("2d");if(!l||(l.clearRect(0,0,s,x),!b||!Y))return;const f=s*.32,T=l.createRadialGradient(e,o,0,e,o,f);T.addColorStop(0,"rgba(255,250,238,0.18)"),T.addColorStop(.5,"rgba(255,250,238,0.055)"),T.addColorStop(1,"rgba(255,250,238,0)"),l.fillStyle=T,l.fillRect(0,0,s,x),l.globalCompositeOperation="destination-in",l.drawImage(Y,0,0),l.globalCompositeOperation="source-over"}function pt(){A||!E||(A=document.createElement("span"),A.className=Te.caret,A.setAttribute("aria-hidden","true"),Object.assign(A.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${K(B[0])},${K(B[1])},${K(B[2])})`}),L.appendChild(A),G.push(A))}function Ie(){if(!E||!A)return;const e=O.getContext("2d");if(!e)return;e.font=`${i} ${ee}px ${r}`;const o=e.measureText(n).width,l=(O.clientWidth||s)/s,f=ee*.7;A.style.left=(Ae+o+ee*.05)*l+"px",A.style.top=.5*(O.clientHeight||x)-f*l/2+"px",A.style.height=f*l+"px",A.style.width=Math.max(2,Math.round(ee*.02*l))+"px",A.style.background=`rgb(${K(B[0])},${K(B[1])},${K(B[2])})`}function re(){q||fe||(fe=!0,ue=0,Re=requestAnimationFrame(Ue))}function Ue(e){if(q){fe=!1;return}ue||(ue=e);const o=Math.min(.25,(e-ue)/1e3);ue=e,$.on&&($.acc+=$.rate*o,yt($.acc),$.idx>=$.rows.length&&($.on=!1)),Z&&Y&&(gt(U.set?U.x:s*.5,U.set?U.y:x*.45),Z=!1);const l=E&&Q;if(A&&(A.style.opacity=l&&Math.floor(e/530)%2===0?"1":"0"),!$.on&&!Z&&!l){fe=!1;return}Re=requestAnimationFrame(Ue)}function we(e){const o=L.getBoundingClientRect();U.x=(e.clientX-o.left)/(o.width||1)*s,U.y=(e.clientY-o.top)/(o.height||1)*x,U.set=!0,Z=!0,re()}function Me(){U.set=!1,Z=!0,re()}function wt(){y&&Ve(y.value,!0)}function Mt(e){e.key==="Enter"&&(e.preventDefault(),Be.replay())}function Ct(){Q=!0,re()}function vt(){Q=!1,A&&(A.style.opacity="0")}function Ke(e){e===E&&y||(E=e,e?(y||(y=document.createElement("input"),y.type="text",y.value=n,y.maxLength=64,y.setAttribute("aria-label","Embroidered text — type to change it"),y.setAttribute("autocomplete","off"),y.setAttribute("autocapitalize","off"),y.spellcheck=!1,Object.assign(y.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),y.addEventListener("input",wt),y.addEventListener("keydown",Mt),y.addEventListener("focus",Ct),y.addEventListener("blur",vt),L.appendChild(y),G.push(y)),pt(),Ie()):(y&&(y.remove(),y=null),Q=!1,A&&(A.style.opacity="0")))}function bt(e){if(e!==b)if(b=e,e)L.addEventListener("pointermove",we,{passive:!0}),L.addEventListener("pointerleave",Me,{passive:!0}),U.set=!1,Z=!0,re();else{L.removeEventListener("pointermove",we),L.removeEventListener("pointerleave",Me);const o=j.getContext("2d");o&&o.clearRect(0,0,s,x)}}function ie(e){ct(),ft(),ut(),dt(),ht(),e?xt():($e(),Le(),$.on=!1),y&&y.value!==n&&(y.value=n),Ie(),Z=!0,re()}function Ve(e,o){e=e??"",!(e===n&&H)&&(n=e,H&&(ie(!1),o&&m&&m(n)))}const Ce=new Set;function Ye(e,o,l){const f=`${o} 200px ${e}`;let T=!1;try{T=!!document.fonts&&document.fonts.check(f)}catch{T=!0}if(!document.fonts||T){l();return}let C=!1,v;const F=()=>{C||(C=!0,clearTimeout(v),Ce.delete(v),q||l())};document.fonts.load(f,n).then(()=>document.fonts.ready).then(F,F),v=setTimeout(F,1500),Ce.add(v)}function Tt(){q||(ie(!0),H=!0)}E&&(E=!1,Ke(!0)),b&&(L.addEventListener("pointermove",we,{passive:!0}),L.addEventListener("pointerleave",Me,{passive:!0})),Ye(I,i,Tt);let Pe,He=-1;function Je(){clearTimeout(Pe),Pe=setTimeout(()=>{if(q||!H)return;const e=Math.round(L.getBoundingClientRect().width);e!==He&&(He=e,ie(!1))},200)}window.addEventListener("resize",Je);const Be={get text(){return n},setText(e){if(!q){if(!H){n=e??"",y&&(y.value=n);return}Ve(e,!1)}},replay(){q||!H||ie(!0)},resize(){q||!H||ie(!1)},update(e){if(q)return;e.text!==void 0&&Be.setText(e.text);let o=!1,l=!1;if(e.font!==void 0&&e.font!==r&&(r=e.font,I=it(r),o=!0),e.weight!==void 0){const f=be(e.weight,1,1e3);f!==i&&(i=f,o=!0)}if(e.fill!==void 0){const f=be(e.fill,.05,1);f!==a&&(a=f,o=!0)}e.pitch!==void 0&&e.pitch!==c&&(c=e.pitch,o=!0),e.threadColor!==void 0&&(le(e.threadColor),l=!0),e.sewRate!==void 0&&(u=Math.max(1,e.sewRate)),e.animate!==void 0&&(S=e.animate),e.onTextChange!==void 0&&(m=e.onTextChange),e.sheen!==void 0&&bt(e.sheen),e.editable!==void 0&&Ke(e.editable),H&&(o?Ye(I,i,()=>{q||ie(!1)}):l&&(Xe(),$e(),Le(),Ie(),re()))},focus(){!q&&E&&(y==null||y.focus())},destroy(){if(!q){q=!0,fe=!1,cancelAnimationFrame(Re),clearTimeout(Pe);for(const e of Ce)clearTimeout(e);Ce.clear(),window.removeEventListener("resize",Je),L.removeEventListener("pointermove",we),L.removeEventListener("pointerleave",Me);for(const e of G)e.remove();ne=[],ge=[],$.rows=[],Se=new Uint8Array(0),Fe=new Float32Array(0),me=new Float32Array(0),xe=new Float32Array(0),Y=oe=null,ye=null,A=null,y=null}}};return Be}function lt(h){const t=V.useRef(null),n=V.useRef(null),r=V.useRef(h);r.current=h;const i=V.useRef(h.onTextChange);i.current=h.onTextChange;const{text:a,font:u,weight:b,threadColor:S,pitch:E,fill:c,animate:m,sewRate:I,sheen:N,editable:B,reducedMotion:ae}=h;return V.useLayoutEffect(()=>{const D=t.current;if(!D)return;const le=at(D,{...r.current,onTextChange:y=>{var A;return(A=i.current)==null?void 0:A.call(i,y)}});n.current=le;let G=0,O=0,L=!0,j;return typeof ResizeObserver<"u"&&(j=new ResizeObserver(y=>{const A=Math.round(y[0].contentRect.width);if(L){L=!1,O=A;return}A!==O&&(O=A,cancelAnimationFrame(G),G=requestAnimationFrame(()=>{var Q;return(Q=n.current)==null?void 0:Q.resize()}))}),j.observe(D)),()=>{j==null||j.disconnect(),cancelAnimationFrame(G),le.destroy(),n.current=null}},[ae]),V.useEffect(()=>{var D;(D=n.current)==null||D.update({font:u,weight:b,threadColor:S,pitch:E,fill:c,animate:m,sewRate:I,sheen:N,editable:B})},[u,b,S,E,c,m,I,N,B]),V.useEffect(()=>{var D;(D=n.current)==null||D.setText(a)},[a]),t}const st=V.forwardRef(function({className:t,style:n,as:r="div","aria-label":i,role:a,"aria-describedby":u,...b},S){const E=lt(b),c=V.useCallback(m=>{E.current=m,typeof S=="function"?S(m):S&&(S.current=m)},[E,S]);return At.jsx(r,{ref:c,className:t,style:n,role:b.editable?a:a??"img","aria-label":b.editable?i:i??b.text,"aria-describedby":u})});st.displayName="ThreadText";exports.THREAD_TEXT_CLASSES=Te;exports.ThreadText=st;exports.createThreadText=at;exports.useThreadText=lt;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { useRef as wt, useLayoutEffect as me, useEffect as Qt, forwardRef as ye, useCallback as xe } from "react";
2
- import { jsx as ge } from "react/jsx-runtime";
3
- const Bt = {
1
+ import { useRef as vt, useLayoutEffect as Te, useEffect as ee, forwardRef as Ae, useCallback as Ee } from "react";
2
+ import { jsx as Se } from "react/jsx-runtime";
3
+ const Dt = {
4
4
  /** Base canvas: the baked satin stitches (transparent ground). */
5
5
  bg: "tt-bg",
6
6
  /** Overlay canvas: cursor sheen (`mix-blend-mode: screen`). */
@@ -8,80 +8,80 @@ const Bt = {
8
8
  /** Blinking text caret shown in editable mode. */
9
9
  caret: "tt-caret"
10
10
  };
11
- function J(m, e) {
12
- let o = Math.imul(m | 0, 374761393) + Math.imul(e | 0, 668265263) | 0;
13
- return o = Math.imul(o ^ o >>> 13, 1274126177), ((o ^ o >>> 16) >>> 0) / 4294967295;
11
+ function H(h, e) {
12
+ let n = Math.imul(h | 0, 374761393) + Math.imul(e | 0, 668265263) | 0;
13
+ return n = Math.imul(n ^ n >>> 13, 1274126177), ((n ^ n >>> 16) >>> 0) / 4294967295;
14
14
  }
15
- function Zt(m, e) {
16
- const o = Math.floor(m), r = Math.floor(e), i = m - o, a = e - r, f = i * i * (3 - 2 * i), A = a * a * (3 - 2 * a), E = J(o, r), C = J(o + 1, r), c = J(o, r + 1), u = J(o + 1, r + 1);
17
- return E + (C - E) * f + (c - E) * A + (E - C - c + u) * f * A;
15
+ function ne(h, e) {
16
+ const n = Math.floor(h), r = Math.floor(e), i = h - n, a = e - r, u = i * i * (3 - 2 * i), b = a * a * (3 - 2 * a), S = H(n, r), A = H(n + 1, r), c = H(n, r + 1), m = H(n + 1, r + 1);
17
+ return S + (A - S) * u + (c - S) * b + (S - A - c + m) * u * b;
18
18
  }
19
- const pt = 1e20;
20
- function Ht(m, e, o, r, i) {
19
+ const Tt = 1e20;
20
+ function oe(h, e, n, r, i) {
21
21
  let a = 0;
22
- r[0] = 0, i[0] = -pt, i[1] = pt;
23
- for (let f = 1; f < e; f++) {
24
- let A = (m[f] + f * f - (m[r[a]] + r[a] * r[a])) / (2 * f - 2 * r[a]);
25
- for (; A <= i[a]; )
26
- a--, A = (m[f] + f * f - (m[r[a]] + r[a] * r[a])) / (2 * f - 2 * r[a]);
27
- a++, r[a] = f, i[a] = A, i[a + 1] = pt;
22
+ r[0] = 0, i[0] = -Tt, i[1] = Tt;
23
+ for (let u = 1; u < e; u++) {
24
+ let b = (h[u] + u * u - (h[r[a]] + r[a] * r[a])) / (2 * u - 2 * r[a]);
25
+ for (; b <= i[a]; )
26
+ a--, b = (h[u] + u * u - (h[r[a]] + r[a] * r[a])) / (2 * u - 2 * r[a]);
27
+ a++, r[a] = u, i[a] = b, i[a + 1] = Tt;
28
28
  }
29
29
  a = 0;
30
- for (let f = 0; f < e; f++) {
31
- for (; i[a + 1] < f; ) a++;
32
- o[f] = (f - r[a]) * (f - r[a]) + m[r[a]];
30
+ for (let u = 0; u < e; u++) {
31
+ for (; i[a + 1] < u; ) a++;
32
+ n[u] = (u - r[a]) * (u - r[a]) + h[r[a]];
33
33
  }
34
34
  }
35
- function we(m, e, o) {
36
- const r = new Float64Array(e * o);
37
- for (let c = 0; c < e * o; c++) r[c] = m[c] ? pt : 0;
38
- const i = Math.max(e, o), a = new Float64Array(i), f = new Float64Array(i), A = new Int32Array(i), E = new Float64Array(i + 1);
35
+ function Fe(h, e, n) {
36
+ const r = new Float64Array(e * n);
37
+ for (let c = 0; c < e * n; c++) r[c] = h[c] ? Tt : 0;
38
+ const i = Math.max(e, n), a = new Float64Array(i), u = new Float64Array(i), b = new Int32Array(i), S = new Float64Array(i + 1);
39
39
  for (let c = 0; c < e; c++) {
40
- for (let u = 0; u < o; u++) a[u] = r[u * e + c];
41
- Ht(a, o, f, A, E);
42
- for (let u = 0; u < o; u++) r[u * e + c] = f[u];
43
- }
44
- for (let c = 0; c < o; c++) {
45
- for (let u = 0; u < e; u++) a[u] = r[c * e + u];
46
- Ht(a, e, f, A, E);
47
- for (let u = 0; u < e; u++) r[c * e + u] = f[u];
48
- }
49
- const C = new Float32Array(e * o);
50
- for (let c = 0; c < e * o; c++) C[c] = Math.sqrt(r[c]);
51
- return C;
40
+ for (let m = 0; m < n; m++) a[m] = r[m * e + c];
41
+ oe(a, n, u, b, S);
42
+ for (let m = 0; m < n; m++) r[m * e + c] = u[m];
43
+ }
44
+ for (let c = 0; c < n; c++) {
45
+ for (let m = 0; m < e; m++) a[m] = r[c * e + m];
46
+ oe(a, e, u, b, S);
47
+ for (let m = 0; m < e; m++) r[c * e + m] = u[m];
48
+ }
49
+ const A = new Float32Array(e * n);
50
+ for (let c = 0; c < e * n; c++) A[c] = Math.sqrt(r[c]);
51
+ return A;
52
52
  }
53
- function Wt(m, e, o, r, i) {
54
- let a = Float32Array.from(m);
55
- const f = new Float32Array(e * o), A = 1 / (2 * r + 1), E = (C, c) => C < 0 ? 0 : C > c ? c : C;
56
- for (let C = 0; C < i; C++) {
57
- for (let c = 0; c < o; c++) {
58
- const u = c * e;
59
- let $ = 0;
60
- for (let D = -r; D <= r; D++) $ += a[u + E(D, e - 1)];
61
- for (let D = 0; D < e; D++)
62
- f[u + D] = $ * A, $ += a[u + E(D + r + 1, e - 1)] - a[u + E(D - r, e - 1)];
53
+ function re(h, e, n, r, i) {
54
+ let a = Float32Array.from(h);
55
+ const u = new Float32Array(e * n), b = 1 / (2 * r + 1), S = (A, c) => A < 0 ? 0 : A > c ? c : A;
56
+ for (let A = 0; A < i; A++) {
57
+ for (let c = 0; c < n; c++) {
58
+ const m = c * e;
59
+ let I = 0;
60
+ for (let O = -r; O <= r; O++) I += a[m + S(O, e - 1)];
61
+ for (let O = 0; O < e; O++)
62
+ u[m + O] = I * b, I += a[m + S(O + r + 1, e - 1)] - a[m + S(O - r, e - 1)];
63
63
  }
64
64
  for (let c = 0; c < e; c++) {
65
- let u = 0;
66
- for (let $ = -r; $ <= r; $++) u += f[E($, o - 1) * e + c];
67
- for (let $ = 0; $ < o; $++)
68
- a[$ * e + c] = u * A, u += f[E($ + r + 1, o - 1) * e + c] - f[E($ - r, o - 1) * e + c];
65
+ let m = 0;
66
+ for (let I = -r; I <= r; I++) m += u[S(I, n - 1) * e + c];
67
+ for (let I = 0; I < n; I++)
68
+ a[I * e + c] = m * b, m += u[S(I + r + 1, n - 1) * e + c] - u[S(I - r, n - 1) * e + c];
69
69
  }
70
70
  }
71
71
  return a;
72
72
  }
73
- function te(m, e) {
74
- if (!m) return e;
75
- const o = m.trim();
76
- if (o[0] === "#") {
77
- let i = o.slice(1);
73
+ function ie(h, e) {
74
+ if (!h) return e;
75
+ const n = h.trim();
76
+ if (n[0] === "#") {
77
+ let i = n.slice(1);
78
78
  if (i.length === 3 && (i = i[0] + i[0] + i[1] + i[1] + i[2] + i[2]), i.length >= 6) {
79
- const a = parseInt(i.slice(0, 2), 16), f = parseInt(i.slice(2, 4), 16), A = parseInt(i.slice(4, 6), 16);
80
- if (!Number.isNaN(a) && !Number.isNaN(f) && !Number.isNaN(A)) return [a, f, A];
79
+ const a = parseInt(i.slice(0, 2), 16), u = parseInt(i.slice(2, 4), 16), b = parseInt(i.slice(4, 6), 16);
80
+ if (!Number.isNaN(a) && !Number.isNaN(u) && !Number.isNaN(b)) return [a, u, b];
81
81
  }
82
82
  return e;
83
83
  }
84
- const r = o.match(/rgba?\(([^)]+)\)/i);
84
+ const r = n.match(/rgba?\(([^)]+)\)/i);
85
85
  if (r) {
86
86
  const i = r[1].split(",").map((a) => parseFloat(a));
87
87
  if (i.length >= 3 && i.slice(0, 3).every((a) => !Number.isNaN(a)))
@@ -89,14 +89,17 @@ function te(m, e) {
89
89
  }
90
90
  return e;
91
91
  }
92
- function K(m) {
93
- return m < 0 ? 0 : m > 255 ? 255 : Math.round(m);
92
+ function K(h) {
93
+ return h < 0 ? 0 : h > 255 ? 255 : Math.round(h);
94
94
  }
95
- function ee(m) {
96
- return (m.split(",")[0] || "serif").trim().replace(/^["']|["']$/g, "");
95
+ function bt(h, e, n) {
96
+ return h < e ? e : h > n ? n : h;
97
97
  }
98
- function pe(m, e) {
99
- if (typeof window > "u" || typeof document > "u" || !m)
98
+ function ae(h) {
99
+ return (h.split(",")[0] || "serif").trim().replace(/^["']|["']$/g, "");
100
+ }
101
+ function Le(h, e) {
102
+ if (typeof window > "u" || typeof document > "u" || !h)
100
103
  return { setText() {
101
104
  }, replay() {
102
105
  }, resize() {
@@ -106,388 +109,418 @@ function pe(m, e) {
106
109
  }, get text() {
107
110
  return e.text ?? "";
108
111
  } };
109
- let o = e.text ?? "", r = e.font ?? "Georgia, serif", i = e.weight ?? 680, a = e.fill ?? 0.9, f = e.sewRate ?? 110, A = e.sheen ?? !0, E = e.animate ?? !0, C = e.editable ?? !1, c = e.pitch, u = e.onTextChange, $ = ee(r);
110
- const D = e.reducedMotion ?? !!(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
111
- let k = te(e.threadColor ?? "#fffbf3", [255, 251, 243]), W = [0, 0, 0], N = [0, 0, 0];
112
- function tt(t) {
113
- k = te(t, [255, 251, 243]), W = [k[0] * 0.585, k[1] * 0.585, k[2] * 0.585], N = [k[0] * 0.47, k[1] * 0.47, k[2] * 0.47];
114
- }
115
- tt(e.threadColor ?? "#fffbf3");
116
- const G = [];
117
- let P, g;
118
- m instanceof HTMLCanvasElement ? (P = m, g = m.parentElement ?? m) : (g = m, P = document.createElement("canvas"), G.push(P), g.appendChild(P)), P.classList.add(Bt.bg);
119
- const O = document.createElement("canvas");
120
- G.push(O), O.classList.add(Bt.fx), g.appendChild(O), getComputedStyle(g).position === "static" && (g.style.position = "relative"), P.style.display = "block", P.style.width = "100%", Object.assign(O.style, { position: "absolute", inset: "0", width: "100%", pointerEvents: "none", mixBlendMode: "screen" });
121
- let S = null, Q = !1, s = 0, h = 0, Z = 0, Mt = 0, st = 4, et = [], nt = 0, ot = 0, bt = new Uint8Array(0), Ct = new Float32Array(0), ft = new Float32Array(0), dt = new Float32Array(0), U = null, rt = null, ut = null, ht = [], mt = 3;
122
- const R = { rows: [], idx: 0, acc: 0, rate: 0, on: !1 }, V = { x: 0, y: 0, set: !1 };
123
- let H = !0, vt = 0, Dt = !1, yt = 0, z = !1, Y = !1;
124
- function ne() {
125
- const t = g.getBoundingClientRect(), n = Math.max(1, Math.round(t.width || Math.min(window.innerWidth * 0.95, 1240))), l = o || "Ag", y = P.getContext("2d");
126
- let v = 100;
127
- y && (y.font = `${i} 100px ${r}`, v = y.measureText(l).width || 100);
128
- let b = Math.max(8, 100 * (n * a) / v), T = b * 0.7, L = b * 0.3, I = n * a;
129
- if (y) {
130
- y.font = `${i} ${b}px ${r}`;
131
- const p = y.measureText(l);
132
- I = p.width || I, p.actualBoundingBoxAscent > 0 && (T = p.actualBoundingBoxAscent), p.actualBoundingBoxDescent > 0 && (L = p.actualBoundingBoxDescent);
112
+ let n = e.text ?? "", r = e.font ?? "Georgia, serif", i = bt(e.weight ?? 680, 1, 1e3), a = bt(e.fill ?? 0.9, 0.05, 1), u = Math.max(1, e.sewRate ?? 110), b = e.sheen ?? !0, S = e.animate ?? !0, A = e.editable ?? !1, c = e.pitch, m = e.onTextChange, I = ae(r);
113
+ const O = e.reducedMotion ?? !!(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
114
+ let B = ie(e.threadColor ?? "#fffbf3", [255, 251, 243]), it = [0, 0, 0], D = [0, 0, 0];
115
+ function at(t) {
116
+ B = ie(t, [255, 251, 243]), it = [B[0] * 0.585, B[1] * 0.585, B[2] * 0.585], D = [B[0] * 0.47, B[1] * 0.47, B[2] * 0.47];
117
+ }
118
+ at(e.threadColor ?? "#fffbf3");
119
+ const U = [];
120
+ let k, R;
121
+ h instanceof HTMLCanvasElement ? (k = h, R = h.parentElement ?? h) : (R = h, k = document.createElement("canvas"), U.push(k), R.appendChild(k)), k.classList.add(Dt.bg);
122
+ const j = document.createElement("canvas");
123
+ U.push(j), j.classList.add(Dt.fx), R.appendChild(j), getComputedStyle(R).position === "static" && (R.style.position = "relative"), k.style.display = "block", k.style.width = "100%", Object.assign(j.style, { position: "absolute", inset: "0", width: "100%", pointerEvents: "none", mixBlendMode: "screen" });
124
+ let y = null, E = null, Q = !1, s = 0, x = 0, W = 0, At = 0, tt = 4, et = [], lt = 0, st = 0, jt = -1, zt = "", qt = -1, _t = -1, Et = new Uint8Array(0), St = new Float32Array(0), ht = new Float32Array(0), mt = new Float32Array(0), V = null, nt = null, xt = null, yt = [], gt = 3;
125
+ const $ = { rows: [], idx: 0, acc: 0, rate: 0, on: !1 }, X = { x: 0, y: 0, set: !1 };
126
+ let Z = !0, Ft = 0, ct = !1, ft = 0, z = !1, Y = !1;
127
+ function le() {
128
+ const t = R.getBoundingClientRect(), o = Math.max(1, Math.round(t.width || Math.min(window.innerWidth * 0.95, 1240))), l = n || "Ag", f = k.getContext("2d");
129
+ f && (f.textBaseline = "middle");
130
+ let T = 100;
131
+ f && (f.font = `${i} 100px ${r}`, T = f.measureText(l).width || 100);
132
+ const C = Math.max(8, 100 * (o * a) / T);
133
+ let v = C * 0.62, F = C * 0.62, P = o * a;
134
+ if (f) {
135
+ f.font = `${i} ${C}px ${r}`;
136
+ const w = f.measureText(l);
137
+ P = w.width || P, w.actualBoundingBoxAscent > 0 && (v = w.actualBoundingBoxAscent), w.actualBoundingBoxDescent > 0 && (F = w.actualBoundingBoxDescent);
133
138
  }
134
- const w = Math.max(1, Math.round(2 * Math.max(T, L) * 1.12));
139
+ const p = Math.max(1, Math.round(2 * Math.max(v, F) * 1.1));
135
140
  let d = Math.min(window.devicePixelRatio || 1, 1.7);
136
- for (; n * d * w * d > 9e5 && d > 0.4; ) d -= 0.1;
137
- s = Math.max(1, Math.round(n * d)), h = Math.max(1, Math.round(w * d)), Z = Math.max(4, Math.round(b * d)), Mt = Math.round(s / 2 - I * d / 2);
138
- for (const p of [P, O])
139
- p.width = s, p.height = h, p.style.height = w + "px";
140
- g.style.height = w + "px", st = c ?? Math.max(3, h * 95e-4);
141
- }
142
- function oe() {
143
- rt = document.createElement("canvas"), rt.width = s, rt.height = h, ut = rt.getContext("2d", { willReadFrequently: !0 });
144
- }
145
- function Nt() {
146
- const t = Math.max(7, st * 2.5), n = Math.max(3.2, st * 1.3);
147
- nt = Math.ceil(t) + 2, ot = Math.ceil(n) + 2, et = [];
141
+ for (; o * d * p * d > 9e5 && d > 0.4; ) d -= 0.1;
142
+ s = Math.max(1, Math.round(o * d)), x = Math.max(1, Math.round(p * d)), W = Math.max(4, Math.round(C * d)), At = Math.round(s / 2 - P * d / 2);
143
+ for (const w of [k, j])
144
+ w.width = s, w.height = x, w.style.height = p + "px";
145
+ R.style.height = p + "px", tt = c ?? Math.max(3, x * 95e-4);
146
+ }
147
+ function se() {
148
+ nt && qt === s && _t === x || (nt = document.createElement("canvas"), nt.width = s, nt.height = x, xt = nt.getContext("2d", { willReadFrequently: !0 }), qt = s, _t = x);
149
+ }
150
+ function Gt() {
151
+ const t = Math.max(7, tt * 2.5), o = Math.max(3.2, tt * 1.3);
152
+ lt = Math.ceil(t) + 2, st = Math.ceil(o) + 2, et = [];
148
153
  for (let l = 0; l < 20; l++) {
149
- const y = 0.34 + l / 19 * 0.82, v = document.createElement("canvas");
150
- v.width = nt, v.height = ot;
151
- const b = v.getContext("2d");
152
- if (!b) {
153
- et.push(v);
154
+ const f = 0.34 + l / 19 * 0.82, T = document.createElement("canvas");
155
+ T.width = lt, T.height = st;
156
+ const C = T.getContext("2d");
157
+ if (!C) {
158
+ et.push(T);
154
159
  continue;
155
160
  }
156
- const T = nt / 2, L = ot / 2, I = b.createLinearGradient(0, L - n / 2, 0, L + n / 2), w = (B, j) => `rgba(${K(B[0] * y)},${K(B[1] * y)},${K(B[2] * y)},${j})`;
157
- I.addColorStop(0, w(N, 0)), I.addColorStop(0.16, w(W, 1)), I.addColorStop(0.5, w(k, 1)), I.addColorStop(0.84, w(W, 1)), I.addColorStop(1, w(N, 0)), b.fillStyle = I, b.beginPath();
158
- const d = n / 2;
159
- b.moveTo(T - t / 2 + d, L - d), b.lineTo(T + t / 2 - d, L - d), b.arc(T + t / 2 - d, L, d, -Math.PI / 2, Math.PI / 2), b.lineTo(T - t / 2 + d, L + d), b.arc(T - t / 2 + d, L, d, Math.PI / 2, -Math.PI / 2), b.closePath(), b.fill(), b.globalCompositeOperation = "destination-in";
160
- const p = b.createLinearGradient(T - t / 2, 0, T + t / 2, 0);
161
- p.addColorStop(0, "rgba(0,0,0,0)"), p.addColorStop(0.22, "rgba(0,0,0,1)"), p.addColorStop(0.78, "rgba(0,0,0,1)"), p.addColorStop(1, "rgba(0,0,0,0)"), b.fillStyle = p, b.fillRect(0, 0, nt, ot), et.push(v);
161
+ const v = lt / 2, F = st / 2, P = C.createLinearGradient(0, F - o / 2, 0, F + o / 2), p = (N, q) => `rgba(${K(N[0] * f)},${K(N[1] * f)},${K(N[2] * f)},${q})`;
162
+ P.addColorStop(0, p(D, 0)), P.addColorStop(0.16, p(it, 1)), P.addColorStop(0.5, p(B, 1)), P.addColorStop(0.84, p(it, 1)), P.addColorStop(1, p(D, 0)), C.fillStyle = P, C.beginPath();
163
+ const d = o / 2;
164
+ C.moveTo(v - t / 2 + d, F - d), C.lineTo(v + t / 2 - d, F - d), C.arc(v + t / 2 - d, F, d, -Math.PI / 2, Math.PI / 2), C.lineTo(v - t / 2 + d, F + d), C.arc(v - t / 2 + d, F, d, Math.PI / 2, -Math.PI / 2), C.closePath(), C.fill(), C.globalCompositeOperation = "destination-in";
165
+ const w = C.createLinearGradient(v - t / 2, 0, v + t / 2, 0);
166
+ w.addColorStop(0, "rgba(0,0,0,0)"), w.addColorStop(0.22, "rgba(0,0,0,1)"), w.addColorStop(0.78, "rgba(0,0,0,1)"), w.addColorStop(1, "rgba(0,0,0,0)"), C.fillStyle = w, C.fillRect(0, 0, lt, st), et.push(T);
162
167
  }
168
+ jt = tt, zt = B.join(",");
163
169
  }
164
- function re() {
165
- if (!ut) return;
166
- const t = ut;
167
- t.clearRect(0, 0, s, h), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.font = `${i} ${Z}px ${r}`, t.fillText(o, Mt, h * 0.5);
168
- const n = t.getImageData(0, 0, s, h).data, l = new Uint8Array(s * h);
169
- for (let x = 0; x < h; x++) for (let M = 0; M < s; M++) {
170
- const F = x * s + M, q = n[F * 4 + 3] / 255, _ = Zt(M * 0.5, x * 0.5) * 0.22 + Zt(M * 1.8, x * 1.8) * 0.1;
171
- l[F] = q > 0.5 + (_ - 0.16) ? 1 : 0;
170
+ function ce() {
171
+ et.length && jt === tt && zt === B.join(",") || Gt();
172
+ }
173
+ function fe() {
174
+ if (!xt) return;
175
+ const t = xt;
176
+ t.clearRect(0, 0, s, x), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.font = `${i} ${W}px ${r}`, t.fillText(n, At, x * 0.5);
177
+ const o = t.getImageData(0, 0, s, x).data, l = new Uint8Array(s * x);
178
+ for (let g = 0; g < x; g++) for (let M = 0; M < s; M++) {
179
+ const L = g * s + M, _ = o[L * 4 + 3] / 255, G = ne(M * 0.5, g * 0.5) * 0.22 + ne(M * 1.8, g * 1.8) * 0.1;
180
+ l[L] = _ > 0.5 + (G - 0.16) ? 1 : 0;
172
181
  }
173
- bt = l;
174
- const y = we(l, s, h), v = new Float32Array(s * h);
175
- for (let x = 1; x < h - 1; x++) for (let M = 1; M < s - 1; M++) {
176
- const F = x * s + M;
177
- v[F] = (y[F] * 4 + y[F - 1] + y[F + 1] + y[F - s] + y[F + s]) / 8;
182
+ Et = l;
183
+ const f = Fe(l, s, x), T = new Float32Array(s * x);
184
+ for (let g = 1; g < x - 1; g++) for (let M = 1; M < s - 1; M++) {
185
+ const L = g * s + M;
186
+ T[L] = (f[L] * 4 + f[L - 1] + f[L + 1] + f[L - s] + f[L + s]) / 8;
178
187
  }
179
- const b = new Float32Array(s * h), T = new Float32Array(s * h), L = new Float32Array(s * h), I = new Float32Array(s * h);
180
- for (let x = 1; x < h - 1; x++) for (let M = 1; M < s - 1; M++) {
181
- const F = x * s + M;
182
- if (!l[F]) continue;
183
- const q = (v[F + 1] - v[F - 1]) * 0.5, _ = (v[F + s] - v[F - s]) * 0.5;
184
- L[F] = q, I[F] = _, b[F] = q * q - _ * _, T[F] = 2 * q * _;
188
+ const C = new Float32Array(s * x), v = new Float32Array(s * x), F = new Float32Array(s * x), P = new Float32Array(s * x);
189
+ for (let g = 1; g < x - 1; g++) for (let M = 1; M < s - 1; M++) {
190
+ const L = g * s + M;
191
+ if (!l[L]) continue;
192
+ const _ = (T[L + 1] - T[L - 1]) * 0.5, G = (T[L + s] - T[L - s]) * 0.5;
193
+ F[L] = _, P[L] = G, C[L] = _ * _ - G * G, v[L] = 2 * _ * G;
185
194
  }
186
- const w = Math.max(7, Math.round(h * 0.05)), d = Wt(b, s, h, w, 2), p = Wt(T, s, h, w, 2);
187
- ft = new Float32Array(s * h), dt = new Float32Array(s * h);
188
- for (let x = 0; x < s * h; x++) {
189
- if (!l[x]) continue;
190
- const M = 0.5 * Math.atan2(p[x], d[x]);
191
- ft[x] = Math.cos(M), dt[x] = Math.sin(M);
195
+ const p = Math.max(7, Math.round(x * 0.05)), d = re(C, s, x, p, 2), w = re(v, s, x, p, 2);
196
+ ht = new Float32Array(s * x), mt = new Float32Array(s * x);
197
+ for (let g = 0; g < s * x; g++) {
198
+ if (!l[g]) continue;
199
+ const M = 0.5 * Math.atan2(w[g], d[g]);
200
+ ht[g] = Math.cos(M), mt[g] = Math.sin(M);
192
201
  }
193
- const B = Math.max(9, h * 0.04), j = new Float32Array(s * h), lt = -0.45, ct = -0.62, gt = 0.64;
194
- for (let x = 1; x < h - 1; x++) for (let M = 1; M < s - 1; M++) {
195
- const F = x * s + M;
196
- if (!l[F]) continue;
197
- let q = L[F], _ = I[F];
198
- const Xt = Math.hypot(q, _) || 1;
199
- q /= Xt, _ /= Xt;
200
- const Vt = v[F], Yt = (1 - Math.min(Vt / B, 1)) * 1.25;
201
- let $t = -q * Yt, It = -_ * Yt;
202
- const Jt = 1.5, Pt = Math.hypot($t, It, Jt);
203
- $t /= Pt, It /= Pt;
204
- let kt = $t * lt + It * ct + Jt / Pt * gt;
205
- kt < 0 && (kt = 0);
206
- const he = Math.min(1, 0.45 + 0.55 * Math.min(Vt / (B * 0.7), 1));
207
- j[F] = Math.min(1.12, (0.5 + 0.75 * kt) * he);
202
+ const N = Math.max(9, x * 0.04), q = new Float32Array(s * x), ut = -0.45, dt = -0.62, Ct = 0.64;
203
+ for (let g = 1; g < x - 1; g++) for (let M = 1; M < s - 1; M++) {
204
+ const L = g * s + M;
205
+ if (!l[L]) continue;
206
+ let _ = F[L], G = P[L];
207
+ const Zt = Math.hypot(_, G) || 1;
208
+ _ /= Zt, G /= Zt;
209
+ const Ht = T[L], Wt = (1 - Math.min(Ht / N, 1)) * 1.25;
210
+ let Bt = -_ * Wt, kt = -G * Wt;
211
+ const te = 1.5, Nt = Math.hypot(Bt, kt, te);
212
+ Bt /= Nt, kt /= Nt;
213
+ let Ot = Bt * ut + kt * dt + te / Nt * Ct;
214
+ Ot < 0 && (Ot = 0);
215
+ const be = Math.min(1, 0.45 + 0.55 * Math.min(Ht / (N * 0.7), 1));
216
+ q[L] = Math.min(1.12, (0.5 + 0.75 * Ot) * be);
208
217
  }
209
- Ct = j, U = document.createElement("canvas"), U.width = s, U.height = h;
210
- const X = U.getContext("2d");
211
- if (X) {
212
- const x = X.createImageData(s, h);
213
- for (let M = 0; M < s * h; M++) l[M] && (x.data[M * 4] = 255, x.data[M * 4 + 1] = 255, x.data[M * 4 + 2] = 255, x.data[M * 4 + 3] = 255);
214
- X.putImageData(x, 0, 0);
218
+ St = q, V = document.createElement("canvas"), V.width = s, V.height = x;
219
+ const J = V.getContext("2d");
220
+ if (J) {
221
+ const g = J.createImageData(s, x);
222
+ for (let M = 0; M < s * x; M++) l[M] && (g.data[M * 4] = 255, g.data[M * 4 + 1] = 255, g.data[M * 4 + 2] = 255, g.data[M * 4 + 3] = 255);
223
+ J.putImageData(g, 0, 0);
215
224
  }
216
225
  }
217
- function ie() {
218
- const t = Math.max(1.6, st * 0.6);
219
- mt = t;
220
- const n = [];
221
- for (let l = 0; l < h; l += t) for (let y = 0; y < s; y += t) {
222
- const v = (J(Math.floor(y), Math.floor(l)) - 0.5) * t * 0.9, b = (J(Math.floor(l), Math.floor(y)) - 0.5) * t * 0.9, T = Math.round(y + v), L = Math.round(l + b);
223
- if (T < 1 || L < 1 || T >= s - 1 || L >= h - 1) continue;
224
- const I = L * s + T;
225
- if (!bt[I]) continue;
226
- const w = Math.atan2(dt[I], ft[I]), d = 0.86 + J(T * 7, L * 13) * 0.18;
227
- let p = Ct[I] * d;
228
- p = p < 0 ? 0 : p > 1.12 ? 1.12 : p, n.push({ x: T, y: L, ang: w, idx: Math.min(19, Math.max(0, Math.round(p / 1.12 * 19))) });
226
+ function ue() {
227
+ const t = Math.max(1.6, tt * 0.6);
228
+ gt = t;
229
+ const o = [];
230
+ for (let l = 0; l < x; l += t) for (let f = 0; f < s; f += t) {
231
+ const T = (H(Math.floor(f), Math.floor(l)) - 0.5) * t * 0.9, C = (H(Math.floor(l), Math.floor(f)) - 0.5) * t * 0.9, v = Math.round(f + T), F = Math.round(l + C);
232
+ if (v < 1 || F < 1 || v >= s - 1 || F >= x - 1) continue;
233
+ const P = F * s + v;
234
+ if (!Et[P]) continue;
235
+ const p = Math.atan2(mt[P], ht[P]), d = 0.86 + H(v * 7, F * 13) * 0.18;
236
+ let w = St[P] * d;
237
+ w = w < 0 ? 0 : w > 1.12 ? 1.12 : w, o.push({ x: v, y: F, ang: p, idx: Math.min(19, Math.max(0, Math.round(w / 1.12 * 19))) });
229
238
  }
230
- n.sort((l, y) => l.x - y.x), ht = n;
239
+ yt = o;
231
240
  }
232
- function Ot(t, n) {
233
- t.save(), t.translate(n.x, n.y), t.rotate(n.ang), t.drawImage(et[n.idx], -nt / 2, -ot / 2), t.restore();
241
+ function Ut(t, o) {
242
+ t.save(), t.translate(o.x, o.y), t.rotate(o.ang), t.drawImage(et[o.idx], -lt / 2, -st / 2), t.restore();
234
243
  }
235
- function Tt() {
236
- const t = P.getContext("2d");
244
+ function Lt() {
245
+ const t = k.getContext("2d");
237
246
  if (t)
238
- for (const n of ht) Ot(t, n);
247
+ for (const o of yt) Ut(t, o);
239
248
  }
240
- function At() {
241
- const t = P.getContext("2d");
242
- t && t.clearRect(0, 0, s, h);
249
+ function Rt() {
250
+ const t = k.getContext("2d");
251
+ t && t.clearRect(0, 0, s, x);
243
252
  }
244
- function ae(t) {
253
+ function de(t) {
245
254
  if (!t.length) return [];
246
- const n = Math.max(4, mt * 1.5), l = /* @__PURE__ */ new Map(), y = (w, d) => w + "," + d;
247
- t.forEach((w, d) => {
248
- const p = y(Math.floor(w.x / n), Math.floor(w.y / n));
249
- let B = l.get(p);
250
- B || l.set(p, B = []), B.push(d);
255
+ const o = Math.max(4, gt * 1.5), l = /* @__PURE__ */ new Map(), f = (p, d) => p + "," + d;
256
+ t.forEach((p, d) => {
257
+ const w = f(Math.floor(p.x / o), Math.floor(p.y / o));
258
+ let N = l.get(w);
259
+ N || l.set(w, N = []), N.push(d);
251
260
  });
252
- const v = mt * 1.8 * (mt * 1.8);
253
- function b(w) {
254
- const d = t[w], p = Math.floor(d.x / n), B = Math.floor(d.y / n), j = [];
255
- for (let lt = -1; lt <= 1; lt++) for (let ct = -1; ct <= 1; ct++) {
256
- const gt = l.get(y(p + lt, B + ct));
257
- if (gt)
258
- for (const X of gt) {
259
- if (X === w) continue;
260
- const x = t[X].x - d.x, M = t[X].y - d.y;
261
- x * x + M * M <= v && j.push(X);
261
+ const T = gt * 1.8 * (gt * 1.8);
262
+ function C(p) {
263
+ const d = t[p], w = Math.floor(d.x / o), N = Math.floor(d.y / o), q = [];
264
+ for (let ut = -1; ut <= 1; ut++) for (let dt = -1; dt <= 1; dt++) {
265
+ const Ct = l.get(f(w + ut, N + dt));
266
+ if (Ct)
267
+ for (const J of Ct) {
268
+ if (J === p) continue;
269
+ const g = t[J].x - d.x, M = t[J].y - d.y;
270
+ g * g + M * M <= T && q.push(J);
262
271
  }
263
272
  }
264
- return j;
273
+ return q;
265
274
  }
266
- const T = new Uint8Array(t.length), L = [], I = t.map((w, d) => d).sort((w, d) => t[w].x + t[w].y - (t[d].x + t[d].y));
267
- for (const w of I) {
268
- if (T[w]) continue;
269
- let d = [w];
270
- for (T[w] = 1; d.length; ) {
271
- L.push(d.map((B) => t[B]));
272
- const p = [];
273
- for (const B of d) for (const j of b(B)) T[j] || (T[j] = 1, p.push(j));
274
- d = p;
275
+ const v = new Uint8Array(t.length), F = [], P = t.map((p, d) => d).sort((p, d) => t[p].x + t[p].y - (t[d].x + t[d].y));
276
+ for (const p of P) {
277
+ if (v[p]) continue;
278
+ let d = [p];
279
+ for (v[p] = 1; d.length; ) {
280
+ F.push(d.map((N) => t[N]));
281
+ const w = [];
282
+ for (const N of d) for (const q of C(N)) v[q] || (v[q] = 1, w.push(q));
283
+ d = w;
275
284
  }
276
285
  }
277
- return L;
286
+ return F;
278
287
  }
279
- function le() {
280
- if (At(), D || !E) {
281
- Tt(), R.on = !1;
288
+ function he() {
289
+ if (Rt(), O || !S) {
290
+ Lt(), $.on = !1;
282
291
  return;
283
292
  }
284
- R.rows = ae(ht), R.idx = 0, R.acc = 0, R.rate = f, R.on = R.rows.length > 0;
285
- }
286
- function ce(t) {
287
- const n = P.getContext("2d");
288
- if (n)
289
- for (t > R.rows.length && (t = R.rows.length); R.idx < t; ) {
290
- const l = R.rows[R.idx++];
291
- for (const y of l) Ot(n, y);
293
+ $.rows = de(yt), $.idx = 0, $.acc = 0, $.rate = u, $.on = $.rows.length > 0;
294
+ }
295
+ function me(t) {
296
+ const o = k.getContext("2d");
297
+ if (o)
298
+ for (t > $.rows.length && (t = $.rows.length); $.idx < t; ) {
299
+ const l = $.rows[$.idx++];
300
+ for (const f of l) Ut(o, f);
292
301
  }
293
302
  }
294
- function se(t, n) {
295
- const l = O.getContext("2d");
296
- if (!l || (l.clearRect(0, 0, s, h), !A || !U)) return;
297
- const y = s * 0.32, v = l.createRadialGradient(t, n, 0, t, n, y);
298
- v.addColorStop(0, "rgba(255,250,238,0.18)"), v.addColorStop(0.5, "rgba(255,250,238,0.055)"), v.addColorStop(1, "rgba(255,250,238,0)"), l.fillStyle = v, l.fillRect(0, 0, s, h), l.globalCompositeOperation = "destination-in", l.drawImage(U, 0, 0), l.globalCompositeOperation = "source-over";
303
+ function xe(t, o) {
304
+ const l = j.getContext("2d");
305
+ if (!l || (l.clearRect(0, 0, s, x), !b || !V)) return;
306
+ const f = s * 0.32, T = l.createRadialGradient(t, o, 0, t, o, f);
307
+ T.addColorStop(0, "rgba(255,250,238,0.18)"), T.addColorStop(0.5, "rgba(255,250,238,0.055)"), T.addColorStop(1, "rgba(255,250,238,0)"), l.fillStyle = T, l.fillRect(0, 0, s, x), l.globalCompositeOperation = "destination-in", l.drawImage(V, 0, 0), l.globalCompositeOperation = "source-over";
299
308
  }
300
- function fe() {
301
- S || !C || (S = document.createElement("span"), S.className = Bt.caret, S.setAttribute("aria-hidden", "true"), Object.assign(S.style, { position: "absolute", pointerEvents: "none", borderRadius: "1px", opacity: "0", background: `rgb(${K(k[0])},${K(k[1])},${K(k[2])})` }), g.appendChild(S), G.push(S));
309
+ function ye() {
310
+ E || !A || (E = document.createElement("span"), E.className = Dt.caret, E.setAttribute("aria-hidden", "true"), Object.assign(E.style, { position: "absolute", pointerEvents: "none", borderRadius: "1px", opacity: "0", background: `rgb(${K(B[0])},${K(B[1])},${K(B[2])})` }), R.appendChild(E), U.push(E));
302
311
  }
303
- function Et() {
304
- if (!C || !S) return;
305
- const t = P.getContext("2d");
312
+ function $t() {
313
+ if (!A || !E) return;
314
+ const t = k.getContext("2d");
306
315
  if (!t) return;
307
- t.font = `${i} ${Z}px ${r}`;
308
- const n = t.measureText(o).width, l = (P.clientWidth || s) / s, y = Z * 0.7;
309
- S.style.left = (Mt + n + Z * 0.05) * l + "px", S.style.top = 0.5 * (P.clientHeight || h) - y * l / 2 + "px", S.style.height = y * l + "px", S.style.width = Math.max(2, Math.round(Z * 0.02 * l)) + "px", S.style.background = `rgb(${K(k[0])},${K(k[1])},${K(k[2])})`;
310
- }
311
- function jt(t) {
312
- if (z) return;
313
- yt || (yt = t);
314
- const n = Math.min(0.25, (t - yt) / 1e3);
315
- yt = t, R.on && (R.acc += R.rate * n, ce(R.acc), R.idx >= R.rows.length && (R.on = !1)), H && U && (se(V.set ? V.x : s * 0.5, V.set ? V.y : h * 0.34), H = !1), S && (S.style.opacity = C && Q && Math.floor(t / 530) % 2 === 0 ? "1" : "0"), vt = requestAnimationFrame(jt);
316
- }
317
- function xt(t) {
318
- const n = O.getBoundingClientRect();
319
- V.x = (t.clientX - n.left) / (n.width || 1) * s, V.y = (t.clientY - n.top) / (n.height || 1) * h, V.set = !0, H = !0;
320
- }
321
- function zt(t) {
322
- if (!(!C || t.metaKey || t.ctrlKey || t.altKey)) {
323
- if (t.key === "Backspace") {
324
- t.preventDefault(), Ft(o.slice(0, -1), !0);
325
- return;
326
- }
327
- if (t.key === "Enter") {
328
- t.preventDefault(), Rt.replay();
329
- return;
330
- }
331
- [...t.key].length === 1 && (t.preventDefault(), Ft(o + t.key, !0));
316
+ t.font = `${i} ${W}px ${r}`;
317
+ const o = t.measureText(n).width, l = (k.clientWidth || s) / s, f = W * 0.7;
318
+ E.style.left = (At + o + W * 0.05) * l + "px", E.style.top = 0.5 * (k.clientHeight || x) - f * l / 2 + "px", E.style.height = f * l + "px", E.style.width = Math.max(2, Math.round(W * 0.02 * l)) + "px", E.style.background = `rgb(${K(B[0])},${K(B[1])},${K(B[2])})`;
319
+ }
320
+ function ot() {
321
+ z || ct || (ct = !0, ft = 0, Ft = requestAnimationFrame(Xt));
322
+ }
323
+ function Xt(t) {
324
+ if (z) {
325
+ ct = !1;
326
+ return;
332
327
  }
328
+ ft || (ft = t);
329
+ const o = Math.min(0.25, (t - ft) / 1e3);
330
+ ft = t, $.on && ($.acc += $.rate * o, me($.acc), $.idx >= $.rows.length && ($.on = !1)), Z && V && (xe(X.set ? X.x : s * 0.5, X.set ? X.y : x * 0.45), Z = !1);
331
+ const l = A && Q;
332
+ if (E && (E.style.opacity = l && Math.floor(t / 530) % 2 === 0 ? "1" : "0"), !$.on && !Z && !l) {
333
+ ct = !1;
334
+ return;
335
+ }
336
+ Ft = requestAnimationFrame(Xt);
333
337
  }
334
- function qt() {
335
- Q = !0;
338
+ function pt(t) {
339
+ const o = R.getBoundingClientRect();
340
+ X.x = (t.clientX - o.left) / (o.width || 1) * s, X.y = (t.clientY - o.top) / (o.height || 1) * x, X.set = !0, Z = !0, ot();
336
341
  }
337
- function _t() {
338
- Q = !1, S && (S.style.opacity = "0");
342
+ function wt() {
343
+ X.set = !1, Z = !0, ot();
339
344
  }
340
- function Kt() {
341
- C && g.focus();
345
+ function ge() {
346
+ y && Vt(y.value, !0);
342
347
  }
343
- function St(t) {
344
- C = t, t ? (g.tabIndex = 0, g.setAttribute("role", "textbox"), g.getAttribute("aria-label") || g.setAttribute("aria-label", "Editable embroidered text — type to change it"), fe(), g.addEventListener("keydown", zt), g.addEventListener("focus", qt), g.addEventListener("blur", _t), g.addEventListener("pointerdown", Kt), Et()) : (g.removeAttribute("tabindex"), g.removeAttribute("role"), g.removeEventListener("keydown", zt), g.removeEventListener("focus", qt), g.removeEventListener("blur", _t), g.removeEventListener("pointerdown", Kt), S && (S.style.opacity = "0"));
348
+ function pe(t) {
349
+ t.key === "Enter" && (t.preventDefault(), Pt.replay());
345
350
  }
346
- function de(t) {
347
- if (t !== A)
348
- if (A = t, t)
349
- window.addEventListener("pointermove", xt, { passive: !0 }), H = !0;
351
+ function we() {
352
+ Q = !0, ot();
353
+ }
354
+ function Me() {
355
+ Q = !1, E && (E.style.opacity = "0");
356
+ }
357
+ function Kt(t) {
358
+ t === A && y || (A = t, t ? (y || (y = document.createElement("input"), y.type = "text", y.value = n, y.maxLength = 64, y.setAttribute("aria-label", "Embroidered text — type to change it"), y.setAttribute("autocomplete", "off"), y.setAttribute("autocapitalize", "off"), y.spellcheck = !1, Object.assign(y.style, { position: "absolute", inset: "0", width: "100%", height: "100%", margin: "0", padding: "0", border: "0", outline: "none", background: "transparent", color: "transparent", caretColor: "transparent", font: "inherit", textAlign: "center", cursor: "text" }), y.addEventListener("input", ge), y.addEventListener("keydown", pe), y.addEventListener("focus", we), y.addEventListener("blur", Me), R.appendChild(y), U.push(y)), ye(), $t()) : (y && (y.remove(), y = null), Q = !1, E && (E.style.opacity = "0")));
359
+ }
360
+ function Ce(t) {
361
+ if (t !== b)
362
+ if (b = t, t)
363
+ R.addEventListener("pointermove", pt, { passive: !0 }), R.addEventListener("pointerleave", wt, { passive: !0 }), X.set = !1, Z = !0, ot();
350
364
  else {
351
- window.removeEventListener("pointermove", xt);
352
- const n = O.getContext("2d");
353
- n && n.clearRect(0, 0, s, h);
365
+ R.removeEventListener("pointermove", pt), R.removeEventListener("pointerleave", wt);
366
+ const o = j.getContext("2d");
367
+ o && o.clearRect(0, 0, s, x);
354
368
  }
355
369
  }
356
- function it(t) {
357
- ne(), oe(), Nt(), re(), ie(), t ? le() : (At(), Tt(), R.on = !1), Et(), H = !0;
370
+ function rt(t) {
371
+ le(), se(), ce(), fe(), ue(), t ? he() : (Rt(), Lt(), $.on = !1), y && y.value !== n && (y.value = n), $t(), Z = !0, ot();
358
372
  }
359
- function Ft(t, n) {
360
- t = t ?? "", !(t === o && Y) && (o = t, Y && (it(!1), n && u && u(o)));
373
+ function Vt(t, o) {
374
+ t = t ?? "", !(t === n && Y) && (n = t, Y && (rt(!1), o && m && m(n)));
361
375
  }
362
- let at;
363
- function Gt(t, n, l) {
364
- const y = `${n} 200px ${t}`;
365
- let v = !1;
376
+ const Mt = /* @__PURE__ */ new Set();
377
+ function Yt(t, o, l) {
378
+ const f = `${o} 200px ${t}`;
379
+ let T = !1;
366
380
  try {
367
- v = !!document.fonts && document.fonts.check(y);
381
+ T = !!document.fonts && document.fonts.check(f);
368
382
  } catch {
369
- v = !0;
383
+ T = !0;
370
384
  }
371
- if (!document.fonts || v) {
385
+ if (!document.fonts || T) {
372
386
  l();
373
387
  return;
374
388
  }
375
- let b = !1;
376
- const T = () => {
377
- b || (b = !0, at && clearTimeout(at), l());
389
+ let C = !1, v;
390
+ const F = () => {
391
+ C || (C = !0, clearTimeout(v), Mt.delete(v), z || l());
378
392
  };
379
- document.fonts.load(y, o).then(() => document.fonts.ready).then(T, T), at = setTimeout(T, 1500);
380
- }
381
- function ue() {
382
- z || (it(!0), Y = !0, Dt || (Dt = !0, vt = requestAnimationFrame(jt)));
383
- }
384
- C && St(!0), A && window.addEventListener("pointermove", xt, { passive: !0 }), Gt($, i, ue);
385
- let Lt;
386
- function Ut() {
387
- clearTimeout(Lt), Lt = setTimeout(() => Rt.resize(), 200);
388
- }
389
- window.addEventListener("resize", Ut);
390
- const Rt = {
393
+ document.fonts.load(f, n).then(() => document.fonts.ready).then(F, F), v = setTimeout(F, 1500), Mt.add(v);
394
+ }
395
+ function ve() {
396
+ z || (rt(!0), Y = !0);
397
+ }
398
+ A && (A = !1, Kt(!0)), b && (R.addEventListener("pointermove", pt, { passive: !0 }), R.addEventListener("pointerleave", wt, { passive: !0 })), Yt(I, i, ve);
399
+ let It, Jt = -1;
400
+ function Qt() {
401
+ clearTimeout(It), It = setTimeout(() => {
402
+ if (z || !Y) return;
403
+ const t = Math.round(R.getBoundingClientRect().width);
404
+ t !== Jt && (Jt = t, rt(!1));
405
+ }, 200);
406
+ }
407
+ window.addEventListener("resize", Qt);
408
+ const Pt = {
391
409
  get text() {
392
- return o;
410
+ return n;
393
411
  },
394
412
  setText(t) {
395
413
  if (!z) {
396
414
  if (!Y) {
397
- o = t ?? "";
415
+ n = t ?? "", y && (y.value = n);
398
416
  return;
399
417
  }
400
- Ft(t, !1);
418
+ Vt(t, !1);
401
419
  }
402
420
  },
403
421
  replay() {
404
- z || !Y || it(!0);
422
+ z || !Y || rt(!0);
405
423
  },
406
424
  resize() {
407
- z || !Y || it(!1);
425
+ z || !Y || rt(!1);
408
426
  },
409
427
  update(t) {
410
428
  if (z) return;
411
- let n = !1, l = !1;
412
- t.font !== void 0 && t.font !== r && (r = t.font, $ = ee(r), n = !0), t.weight !== void 0 && t.weight !== i && (i = t.weight, n = !0), t.fill !== void 0 && t.fill !== a && (a = t.fill, n = !0), t.pitch !== void 0 && t.pitch !== c && (c = t.pitch, n = !0), t.threadColor !== void 0 && (tt(t.threadColor), l = !0), t.sewRate !== void 0 && (f = t.sewRate), t.animate !== void 0 && (E = t.animate), t.onTextChange !== void 0 && (u = t.onTextChange), t.sheen !== void 0 && de(t.sheen), t.editable !== void 0 && t.editable !== C && St(t.editable), Y && (n ? Gt($, i, () => {
413
- z || it(!1);
414
- }) : l && (Nt(), At(), Tt(), Et()), H = !0);
429
+ t.text !== void 0 && Pt.setText(t.text);
430
+ let o = !1, l = !1;
431
+ if (t.font !== void 0 && t.font !== r && (r = t.font, I = ae(r), o = !0), t.weight !== void 0) {
432
+ const f = bt(t.weight, 1, 1e3);
433
+ f !== i && (i = f, o = !0);
434
+ }
435
+ if (t.fill !== void 0) {
436
+ const f = bt(t.fill, 0.05, 1);
437
+ f !== a && (a = f, o = !0);
438
+ }
439
+ t.pitch !== void 0 && t.pitch !== c && (c = t.pitch, o = !0), t.threadColor !== void 0 && (at(t.threadColor), l = !0), t.sewRate !== void 0 && (u = Math.max(1, t.sewRate)), t.animate !== void 0 && (S = t.animate), t.onTextChange !== void 0 && (m = t.onTextChange), t.sheen !== void 0 && Ce(t.sheen), t.editable !== void 0 && Kt(t.editable), Y && (o ? Yt(I, i, () => {
440
+ z || rt(!1);
441
+ }) : l && (Gt(), Rt(), Lt(), $t(), ot()));
415
442
  },
416
443
  focus() {
417
- !z && C && g.focus();
444
+ !z && A && (y == null || y.focus());
418
445
  },
419
446
  destroy() {
420
447
  if (!z) {
421
- z = !0, cancelAnimationFrame(vt), clearTimeout(Lt), at && clearTimeout(at), window.removeEventListener("resize", Ut), window.removeEventListener("pointermove", xt), C && St(!1);
422
- for (const t of G) t.remove();
423
- et = [], ht = [], R.rows = [], bt = new Uint8Array(0), Ct = new Float32Array(0), ft = new Float32Array(0), dt = new Float32Array(0), U = rt = null, ut = null, S = null;
448
+ z = !0, ct = !1, cancelAnimationFrame(Ft), clearTimeout(It);
449
+ for (const t of Mt) clearTimeout(t);
450
+ Mt.clear(), window.removeEventListener("resize", Qt), R.removeEventListener("pointermove", pt), R.removeEventListener("pointerleave", wt);
451
+ for (const t of U) t.remove();
452
+ et = [], yt = [], $.rows = [], Et = new Uint8Array(0), St = new Float32Array(0), ht = new Float32Array(0), mt = new Float32Array(0), V = nt = null, xt = null, E = null, y = null;
424
453
  }
425
454
  }
426
455
  };
427
- return Rt;
456
+ return Pt;
428
457
  }
429
- function Me(m) {
430
- const e = wt(null), o = wt(null), r = wt(m);
431
- r.current = m;
432
- const i = wt(m.onTextChange);
433
- i.current = m.onTextChange;
434
- const { text: a, font: f, weight: A, threadColor: E, pitch: C, fill: c, animate: u, sewRate: $, sheen: D, editable: k, reducedMotion: W } = m;
435
- return me(() => {
436
- const N = e.current;
437
- if (!N) return;
438
- const tt = pe(N, {
458
+ function Re(h) {
459
+ const e = vt(null), n = vt(null), r = vt(h);
460
+ r.current = h;
461
+ const i = vt(h.onTextChange);
462
+ i.current = h.onTextChange;
463
+ const { text: a, font: u, weight: b, threadColor: S, pitch: A, fill: c, animate: m, sewRate: I, sheen: O, editable: B, reducedMotion: it } = h;
464
+ return Te(() => {
465
+ const D = e.current;
466
+ if (!D) return;
467
+ const at = Le(D, {
439
468
  ...r.current,
440
469
  // Stable callback wrapper so typing edits always reach the latest handler.
441
- onTextChange: (O) => {
442
- var S;
443
- return (S = i.current) == null ? void 0 : S.call(i, O);
470
+ onTextChange: (y) => {
471
+ var E;
472
+ return (E = i.current) == null ? void 0 : E.call(i, y);
444
473
  }
445
474
  });
446
- o.current = tt;
447
- let G = 0, P = 0, g;
448
- return typeof ResizeObserver < "u" && (g = new ResizeObserver((O) => {
449
- const S = Math.round(O[0].contentRect.width);
450
- S !== P && (P = S, cancelAnimationFrame(G), G = requestAnimationFrame(() => {
475
+ n.current = at;
476
+ let U = 0, k = 0, R = !0, j;
477
+ return typeof ResizeObserver < "u" && (j = new ResizeObserver((y) => {
478
+ const E = Math.round(y[0].contentRect.width);
479
+ if (R) {
480
+ R = !1, k = E;
481
+ return;
482
+ }
483
+ E !== k && (k = E, cancelAnimationFrame(U), U = requestAnimationFrame(() => {
451
484
  var Q;
452
- return (Q = o.current) == null ? void 0 : Q.resize();
485
+ return (Q = n.current) == null ? void 0 : Q.resize();
453
486
  }));
454
- }), g.observe(N)), () => {
455
- g == null || g.disconnect(), cancelAnimationFrame(G), tt.destroy(), o.current = null;
487
+ }), j.observe(D)), () => {
488
+ j == null || j.disconnect(), cancelAnimationFrame(U), at.destroy(), n.current = null;
456
489
  };
457
- }, [W]), Qt(() => {
458
- var N;
459
- (N = o.current) == null || N.update({ font: f, weight: A, threadColor: E, pitch: C, fill: c, animate: u, sewRate: $, sheen: D, editable: k });
460
- }, [f, A, E, C, c, u, $, D, k]), Qt(() => {
461
- var N;
462
- (N = o.current) == null || N.setText(a);
490
+ }, [it]), ee(() => {
491
+ var D;
492
+ (D = n.current) == null || D.update({ font: u, weight: b, threadColor: S, pitch: A, fill: c, animate: m, sewRate: I, sheen: O, editable: B });
493
+ }, [u, b, S, A, c, m, I, O, B]), ee(() => {
494
+ var D;
495
+ (D = n.current) == null || D.setText(a);
463
496
  }, [a]), e;
464
497
  }
465
- const be = ye(
466
- function({ className: e, style: o, as: r = "div", "aria-label": i, role: a, "aria-describedby": f, ...A }, E) {
467
- const C = Me(A), c = xe(
468
- (u) => {
469
- C.current = u, typeof E == "function" ? E(u) : E && (E.current = u);
498
+ const $e = Ae(
499
+ function({ className: e, style: n, as: r = "div", "aria-label": i, role: a, "aria-describedby": u, ...b }, S) {
500
+ const A = Re(b), c = Ee(
501
+ (m) => {
502
+ A.current = m, typeof S == "function" ? S(m) : S && (S.current = m);
470
503
  },
471
504
  // eslint-disable-next-line react-hooks/exhaustive-deps
472
- [C, E]
505
+ [A, S]
473
506
  );
474
- return /* @__PURE__ */ ge(
507
+ return /* @__PURE__ */ Se(
475
508
  r,
476
509
  {
477
510
  ref: c,
478
511
  className: e,
479
- style: o,
480
- role: a ?? "img",
481
- "aria-label": i ?? A.text,
482
- "aria-describedby": f
512
+ style: n,
513
+ role: b.editable ? a : a ?? "img",
514
+ "aria-label": b.editable ? i : i ?? b.text,
515
+ "aria-describedby": u
483
516
  }
484
517
  );
485
518
  }
486
519
  );
487
- be.displayName = "ThreadText";
520
+ $e.displayName = "ThreadText";
488
521
  export {
489
- Bt as THREAD_TEXT_CLASSES,
490
- be as ThreadText,
491
- pe as createThreadText,
492
- Me as useThreadText
522
+ Dt as THREAD_TEXT_CLASSES,
523
+ $e as ThreadText,
524
+ Le as createThreadText,
525
+ Re as useThreadText
493
526
  };
@@ -1 +1 @@
1
- var ThreadText=(function(rt){"use strict";const gt={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function U(a,n){let e=Math.imul(a|0,374761393)+Math.imul(n|0,668265263)|0;return e=Math.imul(e^e>>>13,1274126177),((e^e>>>16)>>>0)/4294967295}function Bt(a,n){const e=Math.floor(a),o=Math.floor(n),r=a-e,s=n-o,h=r*r*(3-2*r),F=s*s*(3-2*s),R=U(e,o),A=U(e+1,o),d=U(e,o+1),y=U(e+1,o+1);return R+(A-R)*h+(d-R)*F+(R-A-d+y)*h*F}const it=1e20;function Ot(a,n,e,o,r){let s=0;o[0]=0,r[0]=-it,r[1]=it;for(let h=1;h<n;h++){let F=(a[h]+h*h-(a[o[s]]+o[s]*o[s]))/(2*h-2*o[s]);for(;F<=r[s];)s--,F=(a[h]+h*h-(a[o[s]]+o[s]*o[s]))/(2*h-2*o[s]);s++,o[s]=h,r[s]=F,r[s+1]=it}s=0;for(let h=0;h<n;h++){for(;r[s+1]<h;)s++;e[h]=(h-o[s])*(h-o[s])+a[o[s]]}}function re(a,n,e){const o=new Float64Array(n*e);for(let d=0;d<n*e;d++)o[d]=a[d]?it:0;const r=Math.max(n,e),s=new Float64Array(r),h=new Float64Array(r),F=new Int32Array(r),R=new Float64Array(r+1);for(let d=0;d<n;d++){for(let y=0;y<e;y++)s[y]=o[y*n+d];Ot(s,e,h,F,R);for(let y=0;y<e;y++)o[y*n+d]=h[y]}for(let d=0;d<e;d++){for(let y=0;y<n;y++)s[y]=o[d*n+y];Ot(s,n,h,F,R);for(let y=0;y<n;y++)o[d*n+y]=h[y]}const A=new Float32Array(n*e);for(let d=0;d<n*e;d++)A[d]=Math.sqrt(o[d]);return A}function _t(a,n,e,o,r){let s=Float32Array.from(a);const h=new Float32Array(n*e),F=1/(2*o+1),R=(A,d)=>A<0?0:A>d?d:A;for(let A=0;A<r;A++){for(let d=0;d<e;d++){const y=d*n;let I=0;for(let k=-o;k<=o;k++)I+=s[y+R(k,n-1)];for(let k=0;k<n;k++)h[y+k]=I*F,I+=s[y+R(k+o+1,n-1)]-s[y+R(k-o,n-1)]}for(let d=0;d<n;d++){let y=0;for(let I=-o;I<=o;I++)y+=h[R(I,e-1)*n+d];for(let I=0;I<e;I++)s[I*n+d]=y*F,y+=h[R(I+o+1,e-1)*n+d]-h[R(I-o,e-1)*n+d]}}return s}function jt(a,n){if(!a)return n;const e=a.trim();if(e[0]==="#"){let r=e.slice(1);if(r.length===3&&(r=r[0]+r[0]+r[1]+r[1]+r[2]+r[2]),r.length>=6){const s=parseInt(r.slice(0,2),16),h=parseInt(r.slice(2,4),16),F=parseInt(r.slice(4,6),16);if(!Number.isNaN(s)&&!Number.isNaN(h)&&!Number.isNaN(F))return[s,h,F]}return n}const o=e.match(/rgba?\(([^)]+)\)/i);if(o){const r=o[1].split(",").map(s=>parseFloat(s));if(r.length>=3&&r.slice(0,3).every(s=>!Number.isNaN(s)))return[Math.round(r[0]),Math.round(r[1]),Math.round(r[2])]}return n}function q(a){return a<0?0:a>255?255:Math.round(a)}function qt(a){return(a.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function ie(a,n){if(typeof window>"u"||typeof document>"u"||!a)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let e=n.text??"",o=n.font??"Georgia, serif",r=n.weight??680,s=n.fill??.9,h=n.sewRate??110,F=n.sheen??!0,R=n.animate??!0,A=n.editable??!1,d=n.pitch,y=n.onTextChange,I=qt(o);const k=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let D=jt(n.threadColor??"#fffbf3",[255,251,243]),pt=[0,0,0],Mt=[0,0,0];function zt(t){D=jt(t,[255,251,243]),pt=[D[0]*.585,D[1]*.585,D[2]*.585],Mt=[D[0]*.47,D[1]*.47,D[2]*.47]}zt(n.threadColor??"#fffbf3");const lt=[];let P,v;a instanceof HTMLCanvasElement?(P=a,v=a.parentElement??a):(v=a,P=document.createElement("canvas"),lt.push(P),v.appendChild(P)),P.classList.add(gt.bg);const K=document.createElement("canvas");lt.push(K),K.classList.add(gt.fx),v.appendChild(K),getComputedStyle(v).position==="static"&&(v.style.position="relative"),P.style.display="block",P.style.width="100%",Object.assign(K.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let L=null,Ct=!1,c=0,u=0,V=0,bt=0,st=4,J=[],Q=0,Z=0,vt=new Uint8Array(0),Tt=new Float32Array(0),ct=new Float32Array(0),ft=new Float32Array(0),z=null,W=null,dt=null,ut=[],ht=3;const E={rows:[],idx:0,acc:0,rate:0,on:!1},X={x:0,y:0,set:!1};let Y=!0,At=0,Gt=!1,mt=0,O=!1,H=!1;function fe(){const t=v.getBoundingClientRect(),i=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),l=e||"Ag",m=P.getContext("2d");let C=100;m&&(m.font=`${r} 100px ${o}`,C=m.measureText(l).width||100);let M=Math.max(8,100*(i*s)/C),b=M*.7,S=M*.3,N=i*s;if(m){m.font=`${r} ${M}px ${o}`;const w=m.measureText(l);N=w.width||N,w.actualBoundingBoxAscent>0&&(b=w.actualBoundingBoxAscent),w.actualBoundingBoxDescent>0&&(S=w.actualBoundingBoxDescent)}const g=Math.max(1,Math.round(2*Math.max(b,S)*1.12));let f=Math.min(window.devicePixelRatio||1,1.7);for(;i*f*g*f>9e5&&f>.4;)f-=.1;c=Math.max(1,Math.round(i*f)),u=Math.max(1,Math.round(g*f)),V=Math.max(4,Math.round(M*f)),bt=Math.round(c/2-N*f/2);for(const w of[P,K])w.width=c,w.height=u,w.style.height=g+"px";v.style.height=g+"px",st=d??Math.max(3,u*.0095)}function de(){W=document.createElement("canvas"),W.width=c,W.height=u,dt=W.getContext("2d",{willReadFrequently:!0})}function Ut(){const t=Math.max(7,st*2.5),i=Math.max(3.2,st*1.3);Q=Math.ceil(t)+2,Z=Math.ceil(i)+2,J=[];for(let l=0;l<20;l++){const m=.34+l/19*.82,C=document.createElement("canvas");C.width=Q,C.height=Z;const M=C.getContext("2d");if(!M){J.push(C);continue}const b=Q/2,S=Z/2,N=M.createLinearGradient(0,S-i/2,0,S+i/2),g=($,B)=>`rgba(${q($[0]*m)},${q($[1]*m)},${q($[2]*m)},${B})`;N.addColorStop(0,g(Mt,0)),N.addColorStop(.16,g(pt,1)),N.addColorStop(.5,g(D,1)),N.addColorStop(.84,g(pt,1)),N.addColorStop(1,g(Mt,0)),M.fillStyle=N,M.beginPath();const f=i/2;M.moveTo(b-t/2+f,S-f),M.lineTo(b+t/2-f,S-f),M.arc(b+t/2-f,S,f,-Math.PI/2,Math.PI/2),M.lineTo(b-t/2+f,S+f),M.arc(b-t/2+f,S,f,Math.PI/2,-Math.PI/2),M.closePath(),M.fill(),M.globalCompositeOperation="destination-in";const w=M.createLinearGradient(b-t/2,0,b+t/2,0);w.addColorStop(0,"rgba(0,0,0,0)"),w.addColorStop(.22,"rgba(0,0,0,1)"),w.addColorStop(.78,"rgba(0,0,0,1)"),w.addColorStop(1,"rgba(0,0,0,0)"),M.fillStyle=w,M.fillRect(0,0,Q,Z),J.push(C)}}function ue(){if(!dt)return;const t=dt;t.clearRect(0,0,c,u),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${r} ${V}px ${o}`,t.fillText(e,bt,u*.5);const i=t.getImageData(0,0,c,u).data,l=new Uint8Array(c*u);for(let x=0;x<u;x++)for(let p=0;p<c;p++){const T=x*c+p,_=i[T*4+3]/255,j=Bt(p*.5,x*.5)*.22+Bt(p*1.8,x*1.8)*.1;l[T]=_>.5+(j-.16)?1:0}vt=l;const m=re(l,c,u),C=new Float32Array(c*u);for(let x=1;x<u-1;x++)for(let p=1;p<c-1;p++){const T=x*c+p;C[T]=(m[T]*4+m[T-1]+m[T+1]+m[T-c]+m[T+c])/8}const M=new Float32Array(c*u),b=new Float32Array(c*u),S=new Float32Array(c*u),N=new Float32Array(c*u);for(let x=1;x<u-1;x++)for(let p=1;p<c-1;p++){const T=x*c+p;if(!l[T])continue;const _=(C[T+1]-C[T-1])*.5,j=(C[T+c]-C[T-c])*.5;S[T]=_,N[T]=j,M[T]=_*_-j*j,b[T]=2*_*j}const g=Math.max(7,Math.round(u*.05)),f=_t(M,c,u,g,2),w=_t(b,c,u,g,2);ct=new Float32Array(c*u),ft=new Float32Array(c*u);for(let x=0;x<c*u;x++){if(!l[x])continue;const p=.5*Math.atan2(w[x],f[x]);ct[x]=Math.cos(p),ft[x]=Math.sin(p)}const $=Math.max(9,u*.04),B=new Float32Array(c*u),nt=-.45,ot=-.62,xt=.64;for(let x=1;x<u-1;x++)for(let p=1;p<c-1;p++){const T=x*c+p;if(!l[T])continue;let _=S[T],j=N[T];const te=Math.hypot(_,j)||1;_/=te,j/=te;const ee=C[T],ne=(1-Math.min(ee/$,1))*1.25;let $t=-_*ne,Pt=-j*ne;const oe=1.5,Dt=Math.hypot($t,Pt,oe);$t/=Dt,Pt/=Dt;let kt=$t*nt+Pt*ot+oe/Dt*xt;kt<0&&(kt=0);const Ce=Math.min(1,.45+.55*Math.min(ee/($*.7),1));B[T]=Math.min(1.12,(.5+.75*kt)*Ce)}Tt=B,z=document.createElement("canvas"),z.width=c,z.height=u;const G=z.getContext("2d");if(G){const x=G.createImageData(c,u);for(let p=0;p<c*u;p++)l[p]&&(x.data[p*4]=255,x.data[p*4+1]=255,x.data[p*4+2]=255,x.data[p*4+3]=255);G.putImageData(x,0,0)}}function he(){const t=Math.max(1.6,st*.6);ht=t;const i=[];for(let l=0;l<u;l+=t)for(let m=0;m<c;m+=t){const C=(U(Math.floor(m),Math.floor(l))-.5)*t*.9,M=(U(Math.floor(l),Math.floor(m))-.5)*t*.9,b=Math.round(m+C),S=Math.round(l+M);if(b<1||S<1||b>=c-1||S>=u-1)continue;const N=S*c+b;if(!vt[N])continue;const g=Math.atan2(ft[N],ct[N]),f=.86+U(b*7,S*13)*.18;let w=Tt[N]*f;w=w<0?0:w>1.12?1.12:w,i.push({x:b,y:S,ang:g,idx:Math.min(19,Math.max(0,Math.round(w/1.12*19)))})}i.sort((l,m)=>l.x-m.x),ut=i}function Xt(t,i){t.save(),t.translate(i.x,i.y),t.rotate(i.ang),t.drawImage(J[i.idx],-Q/2,-Z/2),t.restore()}function St(){const t=P.getContext("2d");if(t)for(const i of ut)Xt(t,i)}function Et(){const t=P.getContext("2d");t&&t.clearRect(0,0,c,u)}function me(t){if(!t.length)return[];const i=Math.max(4,ht*1.5),l=new Map,m=(g,f)=>g+","+f;t.forEach((g,f)=>{const w=m(Math.floor(g.x/i),Math.floor(g.y/i));let $=l.get(w);$||l.set(w,$=[]),$.push(f)});const C=ht*1.8*(ht*1.8);function M(g){const f=t[g],w=Math.floor(f.x/i),$=Math.floor(f.y/i),B=[];for(let nt=-1;nt<=1;nt++)for(let ot=-1;ot<=1;ot++){const xt=l.get(m(w+nt,$+ot));if(xt)for(const G of xt){if(G===g)continue;const x=t[G].x-f.x,p=t[G].y-f.y;x*x+p*p<=C&&B.push(G)}}return B}const b=new Uint8Array(t.length),S=[],N=t.map((g,f)=>f).sort((g,f)=>t[g].x+t[g].y-(t[f].x+t[f].y));for(const g of N){if(b[g])continue;let f=[g];for(b[g]=1;f.length;){S.push(f.map($=>t[$]));const w=[];for(const $ of f)for(const B of M($))b[B]||(b[B]=1,w.push(B));f=w}}return S}function ye(){if(Et(),k||!R){St(),E.on=!1;return}E.rows=me(ut),E.idx=0,E.acc=0,E.rate=h,E.on=E.rows.length>0}function xe(t){const i=P.getContext("2d");if(i)for(t>E.rows.length&&(t=E.rows.length);E.idx<t;){const l=E.rows[E.idx++];for(const m of l)Xt(i,m)}}function ge(t,i){const l=K.getContext("2d");if(!l||(l.clearRect(0,0,c,u),!F||!z))return;const m=c*.32,C=l.createRadialGradient(t,i,0,t,i,m);C.addColorStop(0,"rgba(255,250,238,0.18)"),C.addColorStop(.5,"rgba(255,250,238,0.055)"),C.addColorStop(1,"rgba(255,250,238,0)"),l.fillStyle=C,l.fillRect(0,0,c,u),l.globalCompositeOperation="destination-in",l.drawImage(z,0,0),l.globalCompositeOperation="source-over"}function we(){L||!A||(L=document.createElement("span"),L.className=gt.caret,L.setAttribute("aria-hidden","true"),Object.assign(L.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${q(D[0])},${q(D[1])},${q(D[2])})`}),v.appendChild(L),lt.push(L))}function Ft(){if(!A||!L)return;const t=P.getContext("2d");if(!t)return;t.font=`${r} ${V}px ${o}`;const i=t.measureText(e).width,l=(P.clientWidth||c)/c,m=V*.7;L.style.left=(bt+i+V*.05)*l+"px",L.style.top=.5*(P.clientHeight||u)-m*l/2+"px",L.style.height=m*l+"px",L.style.width=Math.max(2,Math.round(V*.02*l))+"px",L.style.background=`rgb(${q(D[0])},${q(D[1])},${q(D[2])})`}function Ht(t){if(O)return;mt||(mt=t);const i=Math.min(.25,(t-mt)/1e3);mt=t,E.on&&(E.acc+=E.rate*i,xe(E.acc),E.idx>=E.rows.length&&(E.on=!1)),Y&&z&&(ge(X.set?X.x:c*.5,X.set?X.y:u*.34),Y=!1),L&&(L.style.opacity=A&&Ct&&Math.floor(t/530)%2===0?"1":"0"),At=requestAnimationFrame(Ht)}function yt(t){const i=K.getBoundingClientRect();X.x=(t.clientX-i.left)/(i.width||1)*c,X.y=(t.clientY-i.top)/(i.height||1)*u,X.set=!0,Y=!0}function Vt(t){if(!(!A||t.metaKey||t.ctrlKey||t.altKey)){if(t.key==="Backspace"){t.preventDefault(),Nt(e.slice(0,-1),!0);return}if(t.key==="Enter"){t.preventDefault(),It.replay();return}[...t.key].length===1&&(t.preventDefault(),Nt(e+t.key,!0))}}function Yt(){Ct=!0}function Jt(){Ct=!1,L&&(L.style.opacity="0")}function Qt(){A&&v.focus()}function Lt(t){A=t,t?(v.tabIndex=0,v.setAttribute("role","textbox"),v.getAttribute("aria-label")||v.setAttribute("aria-label","Editable embroidered text — type to change it"),we(),v.addEventListener("keydown",Vt),v.addEventListener("focus",Yt),v.addEventListener("blur",Jt),v.addEventListener("pointerdown",Qt),Ft()):(v.removeAttribute("tabindex"),v.removeAttribute("role"),v.removeEventListener("keydown",Vt),v.removeEventListener("focus",Yt),v.removeEventListener("blur",Jt),v.removeEventListener("pointerdown",Qt),L&&(L.style.opacity="0"))}function pe(t){if(t!==F)if(F=t,t)window.addEventListener("pointermove",yt,{passive:!0}),Y=!0;else{window.removeEventListener("pointermove",yt);const i=K.getContext("2d");i&&i.clearRect(0,0,c,u)}}function tt(t){fe(),de(),Ut(),ue(),he(),t?ye():(Et(),St(),E.on=!1),Ft(),Y=!0}function Nt(t,i){t=t??"",!(t===e&&H)&&(e=t,H&&(tt(!1),i&&y&&y(e)))}let et;function Zt(t,i,l){const m=`${i} 200px ${t}`;let C=!1;try{C=!!document.fonts&&document.fonts.check(m)}catch{C=!0}if(!document.fonts||C){l();return}let M=!1;const b=()=>{M||(M=!0,et&&clearTimeout(et),l())};document.fonts.load(m,e).then(()=>document.fonts.ready).then(b,b),et=setTimeout(b,1500)}function Me(){O||(tt(!0),H=!0,Gt||(Gt=!0,At=requestAnimationFrame(Ht)))}A&&Lt(!0),F&&window.addEventListener("pointermove",yt,{passive:!0}),Zt(I,r,Me);let Rt;function Wt(){clearTimeout(Rt),Rt=setTimeout(()=>It.resize(),200)}window.addEventListener("resize",Wt);const It={get text(){return e},setText(t){if(!O){if(!H){e=t??"";return}Nt(t,!1)}},replay(){O||!H||tt(!0)},resize(){O||!H||tt(!1)},update(t){if(O)return;let i=!1,l=!1;t.font!==void 0&&t.font!==o&&(o=t.font,I=qt(o),i=!0),t.weight!==void 0&&t.weight!==r&&(r=t.weight,i=!0),t.fill!==void 0&&t.fill!==s&&(s=t.fill,i=!0),t.pitch!==void 0&&t.pitch!==d&&(d=t.pitch,i=!0),t.threadColor!==void 0&&(zt(t.threadColor),l=!0),t.sewRate!==void 0&&(h=t.sewRate),t.animate!==void 0&&(R=t.animate),t.onTextChange!==void 0&&(y=t.onTextChange),t.sheen!==void 0&&pe(t.sheen),t.editable!==void 0&&t.editable!==A&&Lt(t.editable),H&&(i?Zt(I,r,()=>{O||tt(!1)}):l&&(Ut(),Et(),St(),Ft()),Y=!0)},focus(){!O&&A&&v.focus()},destroy(){if(!O){O=!0,cancelAnimationFrame(At),clearTimeout(Rt),et&&clearTimeout(et),window.removeEventListener("resize",Wt),window.removeEventListener("pointermove",yt),A&&Lt(!1);for(const t of lt)t.remove();J=[],ut=[],E.rows=[],vt=new Uint8Array(0),Tt=new Float32Array(0),ct=new Float32Array(0),ft=new Float32Array(0),z=W=null,dt=null,L=null}}};return It}const ae="data-threadtext",wt=new WeakMap;function le(a,n){const e=a.dataset,o={text:e.ttText??n};if(e.ttFont&&(o.font=e.ttFont),e.ttWeight!==void 0){const r=parseFloat(e.ttWeight);isNaN(r)||(o.weight=r)}if(e.ttThreadColor&&(o.threadColor=e.ttThreadColor),e.ttPitch!==void 0){const r=parseFloat(e.ttPitch);isNaN(r)||(o.pitch=r)}if(e.ttFill!==void 0){const r=parseFloat(e.ttFill);isNaN(r)||(o.fill=r)}if(e.ttSewRate!==void 0){const r=parseFloat(e.ttSewRate);isNaN(r)||(o.sewRate=r)}return e.ttSheen==="false"&&(o.sheen=!1),e.ttAnimate==="false"&&(o.animate=!1),e.ttEditable==="true"&&(o.editable=!0),o}function se(a){Kt(a);const n=a.innerHTML,e=(a.dataset.ttText??a.textContent??"").trim();if(!e)return;const o=le(a,e);a.setAttribute("role","img"),a.setAttribute("aria-label",e),a.innerHTML="";const r=ie(a,o);wt.set(a,{instance:r,originalHTML:n})}function Kt(a){const n=wt.get(a);n&&(n.instance.destroy(),a.removeAttribute("role"),a.removeAttribute("aria-label"),a.innerHTML=n.originalHTML,wt.delete(a))}function at(a=document){a.querySelectorAll(`[${ae}]`).forEach(se)}function ce(){const a=()=>{var n;typeof document<"u"&&((n=document.fonts)!=null&&n.ready)?document.fonts.ready.then(()=>at()).catch(()=>at()):at()};typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",a,{once:!0}):a()}return ce(),rt.destroy=Kt,rt.init=at,Object.defineProperty(rt,Symbol.toStringTag,{value:"Module"}),rt})({});
1
+ var ThreadText=(function(ct){"use strict";const bt={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function K(r,n){let e=Math.imul(r|0,374761393)+Math.imul(n|0,668265263)|0;return e=Math.imul(e^e>>>13,1274126177),((e^e>>>16)>>>0)/4294967295}function _t(r,n){const e=Math.floor(r),o=Math.floor(n),i=r-e,c=n-o,m=i*i*(3-2*i),F=c*c*(3-2*c),$=K(e,o),E=K(e+1,o),u=K(e,o+1),y=K(e+1,o+1);return $+(E-$)*m+(u-$)*F+($-E-u+y)*m*F}const ft=1e20;function qt(r,n,e,o,i){let c=0;o[0]=0,i[0]=-ft,i[1]=ft;for(let m=1;m<n;m++){let F=(r[m]+m*m-(r[o[c]]+o[c]*o[c]))/(2*m-2*o[c]);for(;F<=i[c];)c--,F=(r[m]+m*m-(r[o[c]]+o[c]*o[c]))/(2*m-2*o[c]);c++,o[c]=m,i[c]=F,i[c+1]=ft}c=0;for(let m=0;m<n;m++){for(;i[c+1]<m;)c++;e[m]=(m-o[c])*(m-o[c])+r[o[c]]}}function ce(r,n,e){const o=new Float64Array(n*e);for(let u=0;u<n*e;u++)o[u]=r[u]?ft:0;const i=Math.max(n,e),c=new Float64Array(i),m=new Float64Array(i),F=new Int32Array(i),$=new Float64Array(i+1);for(let u=0;u<n;u++){for(let y=0;y<e;y++)c[y]=o[y*n+u];qt(c,e,m,F,$);for(let y=0;y<e;y++)o[y*n+u]=m[y]}for(let u=0;u<e;u++){for(let y=0;y<n;y++)c[y]=o[u*n+y];qt(c,n,m,F,$);for(let y=0;y<n;y++)o[u*n+y]=m[y]}const E=new Float32Array(n*e);for(let u=0;u<n*e;u++)E[u]=Math.sqrt(o[u]);return E}function zt(r,n,e,o,i){let c=Float32Array.from(r);const m=new Float32Array(n*e),F=1/(2*o+1),$=(E,u)=>E<0?0:E>u?u:E;for(let E=0;E<i;E++){for(let u=0;u<e;u++){const y=u*n;let I=0;for(let D=-o;D<=o;D++)I+=c[y+$(D,n-1)];for(let D=0;D<n;D++)m[y+D]=I*F,I+=c[y+$(D+o+1,n-1)]-c[y+$(D-o,n-1)]}for(let u=0;u<n;u++){let y=0;for(let I=-o;I<=o;I++)y+=m[$(I,e-1)*n+u];for(let I=0;I<e;I++)c[I*n+u]=y*F,y+=m[$(I+o+1,e-1)*n+u]-m[$(I-o,e-1)*n+u]}}return c}function Gt(r,n){if(!r)return n;const e=r.trim();if(e[0]==="#"){let i=e.slice(1);if(i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),i.length>=6){const c=parseInt(i.slice(0,2),16),m=parseInt(i.slice(2,4),16),F=parseInt(i.slice(4,6),16);if(!Number.isNaN(c)&&!Number.isNaN(m)&&!Number.isNaN(F))return[c,m,F]}return n}const o=e.match(/rgba?\(([^)]+)\)/i);if(o){const i=o[1].split(",").map(c=>parseFloat(c));if(i.length>=3&&i.slice(0,3).every(c=>!Number.isNaN(c)))return[Math.round(i[0]),Math.round(i[1]),Math.round(i[2])]}return n}function z(r){return r<0?0:r>255?255:Math.round(r)}function dt(r,n,e){return r<n?n:r>e?e:r}function Ut(r){return(r.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function fe(r,n){if(typeof window>"u"||typeof document>"u"||!r)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let e=n.text??"",o=n.font??"Georgia, serif",i=dt(n.weight??680,1,1e3),c=dt(n.fill??.9,.05,1),m=Math.max(1,n.sewRate??110),F=n.sheen??!0,$=n.animate??!0,E=n.editable??!1,u=n.pitch,y=n.onTextChange,I=Ut(o);const D=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let P=Gt(n.threadColor??"#fffbf3",[255,251,243]),St=[0,0,0],At=[0,0,0];function Ht(t){P=Gt(t,[255,251,243]),St=[P[0]*.585,P[1]*.585,P[2]*.585],At=[P[0]*.47,P[1]*.47,P[2]*.47]}Ht(n.threadColor??"#fffbf3");const nt=[];let O,L;r instanceof HTMLCanvasElement?(O=r,L=r.parentElement??r):(L=r,O=document.createElement("canvas"),nt.push(O),L.appendChild(O)),O.classList.add(bt.bg);const V=document.createElement("canvas");nt.push(V),V.classList.add(bt.fx),L.appendChild(V),getComputedStyle(L).position==="static"&&(L.style.position="relative"),O.style.display="block",O.style.width="100%",Object.assign(V.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let g=null,R=null,ht=!1,s=0,h=0,J=0,Et=0,Q=4,Z=[],ot=0,it=0,Kt=-1,Vt="",Yt=-1,Jt=-1,Ft=new Uint8Array(0),Lt=new Float32Array(0),mt=new Float32Array(0),yt=new Float32Array(0),U=null,W=null,xt=null,gt=[],pt=3;const A={rows:[],idx:0,acc:0,rate:0,on:!1},G={x:0,y:0,set:!1};let Y=!0,Rt=0,rt=!1,at=0,k=!1,X=!1;function ye(){const t=L.getBoundingClientRect(),a=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),l=e||"Ag",f=O.getContext("2d");f&&(f.textBaseline="middle");let b=100;f&&(f.font=`${i} 100px ${o}`,b=f.measureText(l).width||100);const v=Math.max(8,100*(a*c)/b);let C=v*.62,T=v*.62,N=a*c;if(f){f.font=`${i} ${v}px ${o}`;const w=f.measureText(l);N=w.width||N,w.actualBoundingBoxAscent>0&&(C=w.actualBoundingBoxAscent),w.actualBoundingBoxDescent>0&&(T=w.actualBoundingBoxDescent)}const p=Math.max(1,Math.round(2*Math.max(C,T)*1.1));let d=Math.min(window.devicePixelRatio||1,1.7);for(;a*d*p*d>9e5&&d>.4;)d-=.1;s=Math.max(1,Math.round(a*d)),h=Math.max(1,Math.round(p*d)),J=Math.max(4,Math.round(v*d)),Et=Math.round(s/2-N*d/2);for(const w of[O,V])w.width=s,w.height=h,w.style.height=p+"px";L.style.height=p+"px",Q=u??Math.max(3,h*.0095)}function xe(){W&&Yt===s&&Jt===h||(W=document.createElement("canvas"),W.width=s,W.height=h,xt=W.getContext("2d",{willReadFrequently:!0}),Yt=s,Jt=h)}function Qt(){const t=Math.max(7,Q*2.5),a=Math.max(3.2,Q*1.3);ot=Math.ceil(t)+2,it=Math.ceil(a)+2,Z=[];for(let l=0;l<20;l++){const f=.34+l/19*.82,b=document.createElement("canvas");b.width=ot,b.height=it;const v=b.getContext("2d");if(!v){Z.push(b);continue}const C=ot/2,T=it/2,N=v.createLinearGradient(0,T-a/2,0,T+a/2),p=(B,j)=>`rgba(${z(B[0]*f)},${z(B[1]*f)},${z(B[2]*f)},${j})`;N.addColorStop(0,p(At,0)),N.addColorStop(.16,p(St,1)),N.addColorStop(.5,p(P,1)),N.addColorStop(.84,p(St,1)),N.addColorStop(1,p(At,0)),v.fillStyle=N,v.beginPath();const d=a/2;v.moveTo(C-t/2+d,T-d),v.lineTo(C+t/2-d,T-d),v.arc(C+t/2-d,T,d,-Math.PI/2,Math.PI/2),v.lineTo(C-t/2+d,T+d),v.arc(C-t/2+d,T,d,Math.PI/2,-Math.PI/2),v.closePath(),v.fill(),v.globalCompositeOperation="destination-in";const w=v.createLinearGradient(C-t/2,0,C+t/2,0);w.addColorStop(0,"rgba(0,0,0,0)"),w.addColorStop(.22,"rgba(0,0,0,1)"),w.addColorStop(.78,"rgba(0,0,0,1)"),w.addColorStop(1,"rgba(0,0,0,0)"),v.fillStyle=w,v.fillRect(0,0,ot,it),Z.push(b)}Kt=Q,Vt=P.join(",")}function ge(){Z.length&&Kt===Q&&Vt===P.join(",")||Qt()}function pe(){if(!xt)return;const t=xt;t.clearRect(0,0,s,h),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${i} ${J}px ${o}`,t.fillText(e,Et,h*.5);const a=t.getImageData(0,0,s,h).data,l=new Uint8Array(s*h);for(let x=0;x<h;x++)for(let M=0;M<s;M++){const S=x*s+M,_=a[S*4+3]/255,q=_t(M*.5,x*.5)*.22+_t(M*1.8,x*1.8)*.1;l[S]=_>.5+(q-.16)?1:0}Ft=l;const f=ce(l,s,h),b=new Float32Array(s*h);for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const S=x*s+M;b[S]=(f[S]*4+f[S-1]+f[S+1]+f[S-s]+f[S+s])/8}const v=new Float32Array(s*h),C=new Float32Array(s*h),T=new Float32Array(s*h),N=new Float32Array(s*h);for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const S=x*s+M;if(!l[S])continue;const _=(b[S+1]-b[S-1])*.5,q=(b[S+s]-b[S-s])*.5;T[S]=_,N[S]=q,v[S]=_*_-q*q,C[S]=2*_*q}const p=Math.max(7,Math.round(h*.05)),d=zt(v,s,h,p,2),w=zt(C,s,h,p,2);mt=new Float32Array(s*h),yt=new Float32Array(s*h);for(let x=0;x<s*h;x++){if(!l[x])continue;const M=.5*Math.atan2(w[x],d[x]);mt[x]=Math.cos(M),yt[x]=Math.sin(M)}const B=Math.max(9,h*.04),j=new Float32Array(s*h),lt=-.45,st=-.62,Ct=.64;for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const S=x*s+M;if(!l[S])continue;let _=T[S],q=N[S];const re=Math.hypot(_,q)||1;_/=re,q/=re;const ae=b[S],le=(1-Math.min(ae/B,1))*1.25;let Ot=-_*le,kt=-q*le;const se=1.5,Dt=Math.hypot(Ot,kt,se);Ot/=Dt,kt/=Dt;let jt=Ot*lt+kt*st+se/Dt*Ct;jt<0&&(jt=0);const Ne=Math.min(1,.45+.55*Math.min(ae/(B*.7),1));j[S]=Math.min(1.12,(.5+.75*jt)*Ne)}Lt=j,U=document.createElement("canvas"),U.width=s,U.height=h;const H=U.getContext("2d");if(H){const x=H.createImageData(s,h);for(let M=0;M<s*h;M++)l[M]&&(x.data[M*4]=255,x.data[M*4+1]=255,x.data[M*4+2]=255,x.data[M*4+3]=255);H.putImageData(x,0,0)}}function we(){const t=Math.max(1.6,Q*.6);pt=t;const a=[];for(let l=0;l<h;l+=t)for(let f=0;f<s;f+=t){const b=(K(Math.floor(f),Math.floor(l))-.5)*t*.9,v=(K(Math.floor(l),Math.floor(f))-.5)*t*.9,C=Math.round(f+b),T=Math.round(l+v);if(C<1||T<1||C>=s-1||T>=h-1)continue;const N=T*s+C;if(!Ft[N])continue;const p=Math.atan2(yt[N],mt[N]),d=.86+K(C*7,T*13)*.18;let w=Lt[N]*d;w=w<0?0:w>1.12?1.12:w,a.push({x:C,y:T,ang:p,idx:Math.min(19,Math.max(0,Math.round(w/1.12*19)))})}gt=a}function Zt(t,a){t.save(),t.translate(a.x,a.y),t.rotate(a.ang),t.drawImage(Z[a.idx],-ot/2,-it/2),t.restore()}function Nt(){const t=O.getContext("2d");if(t)for(const a of gt)Zt(t,a)}function $t(){const t=O.getContext("2d");t&&t.clearRect(0,0,s,h)}function Me(t){if(!t.length)return[];const a=Math.max(4,pt*1.5),l=new Map,f=(p,d)=>p+","+d;t.forEach((p,d)=>{const w=f(Math.floor(p.x/a),Math.floor(p.y/a));let B=l.get(w);B||l.set(w,B=[]),B.push(d)});const b=pt*1.8*(pt*1.8);function v(p){const d=t[p],w=Math.floor(d.x/a),B=Math.floor(d.y/a),j=[];for(let lt=-1;lt<=1;lt++)for(let st=-1;st<=1;st++){const Ct=l.get(f(w+lt,B+st));if(Ct)for(const H of Ct){if(H===p)continue;const x=t[H].x-d.x,M=t[H].y-d.y;x*x+M*M<=b&&j.push(H)}}return j}const C=new Uint8Array(t.length),T=[],N=t.map((p,d)=>d).sort((p,d)=>t[p].x+t[p].y-(t[d].x+t[d].y));for(const p of N){if(C[p])continue;let d=[p];for(C[p]=1;d.length;){T.push(d.map(B=>t[B]));const w=[];for(const B of d)for(const j of v(B))C[j]||(C[j]=1,w.push(j));d=w}}return T}function ve(){if($t(),D||!$){Nt(),A.on=!1;return}A.rows=Me(gt),A.idx=0,A.acc=0,A.rate=m,A.on=A.rows.length>0}function Ce(t){const a=O.getContext("2d");if(a)for(t>A.rows.length&&(t=A.rows.length);A.idx<t;){const l=A.rows[A.idx++];for(const f of l)Zt(a,f)}}function be(t,a){const l=V.getContext("2d");if(!l||(l.clearRect(0,0,s,h),!F||!U))return;const f=s*.32,b=l.createRadialGradient(t,a,0,t,a,f);b.addColorStop(0,"rgba(255,250,238,0.18)"),b.addColorStop(.5,"rgba(255,250,238,0.055)"),b.addColorStop(1,"rgba(255,250,238,0)"),l.fillStyle=b,l.fillRect(0,0,s,h),l.globalCompositeOperation="destination-in",l.drawImage(U,0,0),l.globalCompositeOperation="source-over"}function Te(){R||!E||(R=document.createElement("span"),R.className=bt.caret,R.setAttribute("aria-hidden","true"),Object.assign(R.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${z(P[0])},${z(P[1])},${z(P[2])})`}),L.appendChild(R),nt.push(R))}function It(){if(!E||!R)return;const t=O.getContext("2d");if(!t)return;t.font=`${i} ${J}px ${o}`;const a=t.measureText(e).width,l=(O.clientWidth||s)/s,f=J*.7;R.style.left=(Et+a+J*.05)*l+"px",R.style.top=.5*(O.clientHeight||h)-f*l/2+"px",R.style.height=f*l+"px",R.style.width=Math.max(2,Math.round(J*.02*l))+"px",R.style.background=`rgb(${z(P[0])},${z(P[1])},${z(P[2])})`}function tt(){k||rt||(rt=!0,at=0,Rt=requestAnimationFrame(Wt))}function Wt(t){if(k){rt=!1;return}at||(at=t);const a=Math.min(.25,(t-at)/1e3);at=t,A.on&&(A.acc+=A.rate*a,Ce(A.acc),A.idx>=A.rows.length&&(A.on=!1)),Y&&U&&(be(G.set?G.x:s*.5,G.set?G.y:h*.45),Y=!1);const l=E&&ht;if(R&&(R.style.opacity=l&&Math.floor(t/530)%2===0?"1":"0"),!A.on&&!Y&&!l){rt=!1;return}Rt=requestAnimationFrame(Wt)}function wt(t){const a=L.getBoundingClientRect();G.x=(t.clientX-a.left)/(a.width||1)*s,G.y=(t.clientY-a.top)/(a.height||1)*h,G.set=!0,Y=!0,tt()}function Mt(){G.set=!1,Y=!0,tt()}function Se(){g&&ee(g.value,!0)}function Ae(t){t.key==="Enter"&&(t.preventDefault(),Bt.replay())}function Ee(){ht=!0,tt()}function Fe(){ht=!1,R&&(R.style.opacity="0")}function te(t){t===E&&g||(E=t,t?(g||(g=document.createElement("input"),g.type="text",g.value=e,g.maxLength=64,g.setAttribute("aria-label","Embroidered text — type to change it"),g.setAttribute("autocomplete","off"),g.setAttribute("autocapitalize","off"),g.spellcheck=!1,Object.assign(g.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),g.addEventListener("input",Se),g.addEventListener("keydown",Ae),g.addEventListener("focus",Ee),g.addEventListener("blur",Fe),L.appendChild(g),nt.push(g)),Te(),It()):(g&&(g.remove(),g=null),ht=!1,R&&(R.style.opacity="0")))}function Le(t){if(t!==F)if(F=t,t)L.addEventListener("pointermove",wt,{passive:!0}),L.addEventListener("pointerleave",Mt,{passive:!0}),G.set=!1,Y=!0,tt();else{L.removeEventListener("pointermove",wt),L.removeEventListener("pointerleave",Mt);const a=V.getContext("2d");a&&a.clearRect(0,0,s,h)}}function et(t){ye(),xe(),ge(),pe(),we(),t?ve():($t(),Nt(),A.on=!1),g&&g.value!==e&&(g.value=e),It(),Y=!0,tt()}function ee(t,a){t=t??"",!(t===e&&X)&&(e=t,X&&(et(!1),a&&y&&y(e)))}const vt=new Set;function ne(t,a,l){const f=`${a} 200px ${t}`;let b=!1;try{b=!!document.fonts&&document.fonts.check(f)}catch{b=!0}if(!document.fonts||b){l();return}let v=!1,C;const T=()=>{v||(v=!0,clearTimeout(C),vt.delete(C),k||l())};document.fonts.load(f,e).then(()=>document.fonts.ready).then(T,T),C=setTimeout(T,1500),vt.add(C)}function Re(){k||(et(!0),X=!0)}E&&(E=!1,te(!0)),F&&(L.addEventListener("pointermove",wt,{passive:!0}),L.addEventListener("pointerleave",Mt,{passive:!0})),ne(I,i,Re);let Pt,oe=-1;function ie(){clearTimeout(Pt),Pt=setTimeout(()=>{if(k||!X)return;const t=Math.round(L.getBoundingClientRect().width);t!==oe&&(oe=t,et(!1))},200)}window.addEventListener("resize",ie);const Bt={get text(){return e},setText(t){if(!k){if(!X){e=t??"",g&&(g.value=e);return}ee(t,!1)}},replay(){k||!X||et(!0)},resize(){k||!X||et(!1)},update(t){if(k)return;t.text!==void 0&&Bt.setText(t.text);let a=!1,l=!1;if(t.font!==void 0&&t.font!==o&&(o=t.font,I=Ut(o),a=!0),t.weight!==void 0){const f=dt(t.weight,1,1e3);f!==i&&(i=f,a=!0)}if(t.fill!==void 0){const f=dt(t.fill,.05,1);f!==c&&(c=f,a=!0)}t.pitch!==void 0&&t.pitch!==u&&(u=t.pitch,a=!0),t.threadColor!==void 0&&(Ht(t.threadColor),l=!0),t.sewRate!==void 0&&(m=Math.max(1,t.sewRate)),t.animate!==void 0&&($=t.animate),t.onTextChange!==void 0&&(y=t.onTextChange),t.sheen!==void 0&&Le(t.sheen),t.editable!==void 0&&te(t.editable),X&&(a?ne(I,i,()=>{k||et(!1)}):l&&(Qt(),$t(),Nt(),It(),tt()))},focus(){!k&&E&&(g==null||g.focus())},destroy(){if(!k){k=!0,rt=!1,cancelAnimationFrame(Rt),clearTimeout(Pt);for(const t of vt)clearTimeout(t);vt.clear(),window.removeEventListener("resize",ie),L.removeEventListener("pointermove",wt),L.removeEventListener("pointerleave",Mt);for(const t of nt)t.remove();Z=[],gt=[],A.rows=[],Ft=new Uint8Array(0),Lt=new Float32Array(0),mt=new Float32Array(0),yt=new Float32Array(0),U=W=null,xt=null,R=null,g=null}}};return Bt}const de="data-threadtext",Tt=new WeakMap;function ue(r,n){const e=r.dataset,o={text:e.ttText??n};if(e.ttFont&&(o.font=e.ttFont),e.ttWeight!==void 0){const i=parseFloat(e.ttWeight);isNaN(i)||(o.weight=i)}if(e.ttThreadColor&&(o.threadColor=e.ttThreadColor),e.ttPitch!==void 0){const i=parseFloat(e.ttPitch);isNaN(i)||(o.pitch=i)}if(e.ttFill!==void 0){const i=parseFloat(e.ttFill);isNaN(i)||(o.fill=i)}if(e.ttSewRate!==void 0){const i=parseFloat(e.ttSewRate);isNaN(i)||(o.sewRate=i)}return e.ttSheen==="false"&&(o.sheen=!1),e.ttAnimate==="false"&&(o.animate=!1),e.ttEditable==="true"&&(o.editable=!0),o}function he(r){Xt(r);const n=r.innerHTML,e=(r.dataset.ttText??r.textContent??"").trim();if(!e)return;const o=ue(r,e);r.innerHTML="",o.editable||(r.setAttribute("role","img"),r.setAttribute("aria-label",e));const i=fe(r,o);Tt.set(r,{instance:i,originalHTML:n})}function Xt(r){const n=Tt.get(r);n&&(n.instance.destroy(),r.removeAttribute("role"),r.removeAttribute("aria-label"),r.innerHTML=n.originalHTML,Tt.delete(r))}function ut(r=document){r.querySelectorAll(`[${de}]`).forEach(he)}function me(){const r=()=>{var n;typeof document<"u"&&((n=document.fonts)!=null&&n.ready)?document.fonts.ready.then(()=>ut()).catch(()=>ut()):ut()};typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",r,{once:!0}):r()}return me(),ct.destroy=Xt,ct.init=ut,Object.defineProperty(ct,Symbol.toStringTag,{value:"Module"}),ct})({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liiift-studio/threadtext",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Render any text as photorealistic procedural satin-stitch embroidery, in real time in the browser, from the font's glyph geometry",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",