textmode.export.js 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/textmode.export.esm.js +461 -457
- package/dist/textmode.export.umd.js +2 -3
- package/dist/types/overlay/core/OverlayController.d.ts +2 -0
- package/dist/types/overlay/core/OverlayController.d.ts.map +1 -1
- package/dist/types/overlay/index.d.ts +0 -1
- package/dist/types/overlay/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
(function(){
|
|
2
|
-
(function(Q,j){typeof exports=="object"&&typeof module<"u"?j(exports):typeof define=="function"&&define.amd?define(["exports"],j):j((Q=typeof globalThis<"u"?globalThis:Q||self).TextmodeExport={})})(this,function(Q){"use strict";class j{$extractFramebufferData(t){const e=t.readPixels(0),i=t.readPixels(1),r=t.readPixels(2),s=t.readPixels(3);return{characterPixels:e,primaryColorPixels:i,secondaryColorPixels:r,transformPixels:t.readPixels(4),rotationPixels:s}}$getCharacterIndex(t,e){return t[e]+(t[e+1]<<8)}}class X{$downloadFile(t,e){try{const i=this._sanitizeFilename(e),r=URL.createObjectURL(t),s=document.createElement("a");s.href=r,s.download=i,s.style.display="none",s.rel="noopener",document.body.appendChild(s),s.click(),document.body.removeChild(s),URL.revokeObjectURL(r)}catch(i){console.error("[textmode-export] Failed to download file:",i)}}_sanitizeFilename(t){if(!t)return this._generateDefaultFilename();const e=t.trim();return e?e.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)||this._generateDefaultFilename():this._generateDefaultFilename()}_generateDefaultFilename(){return`textmode-export-${new Date().toISOString().slice(0,19).replace(/:/g,"-")}`}}function bt(c,t){return{r:c[t],g:c[t+1],b:c[t+2],a:c[t+3]}}class ne extends j{_extractTransformData(t,e,i){const r=t[i]===255,s=t[i+1]===255,n=t[i+2]===255,u=e[i]+e[i+1]/255;return{isInverted:r,flipHorizontal:s,flipVertical:n,rotation:Math.round(360*u/255*100)/100}}_calculateCellPosition(t,e,i){return{x:t,y:e,cellX:t*i.cellWidth,cellY:e*i.cellHeight}}$extractSVGCellData(t,e){const i=[];let r=0;for(let s=0;s<e.rows;s++)for(let n=0;n<e.cols;n++){const u=4*r,l=this.$getCharacterIndex(t.characterPixels,u);let p=bt(t.primaryColorPixels,u),a=bt(t.secondaryColorPixels,u);const o=this._extractTransformData(t.transformPixels,t.rotationPixels,u);if(o.isInverted){const m=p;p=a,a=m}const d=this._calculateCellPosition(n,s,e);i.push({charIndex:l,primaryColor:p,secondaryColor:a,transform:o,position:d}),r++}return i}}class oe{_createGlyphPath(t,e,i,r,s){const n=s/t.head.unitsPerEm;return{getBoundingBox:()=>({x1:i+e.xMin*n,y1:r+-e.yMax*n,x2:i+e.xMax*n,y2:r+-e.yMin*n}),toSVG:()=>this._glyphToSVGPath(e,i,r,n)}}_glyphToSVGPath(t,e,i,r){if(!t||!t.xs)return"";const{xs:s,ys:n,endPts:u,flags:l}=t;if(!(s&&n&&u&&l))return"";let p="",a=0;for(let o=0;o<u.length;o++){const d=u[o];if(!(d<a)){if(d>=a){const m=e+s[a]*r,y=i-n[a]*r;p+=`M${m.toFixed(2)},${y.toFixed(2)}`;let h=a+1;for(;h<=d;)if(1&l[h]){const v=e+s[h]*r,E=i-n[h]*r;p+=`L${v.toFixed(2)},${E.toFixed(2)}`,h++}else{const v=e+s[h]*r,E=i-n[h]*r;let w=h+1>d?a:h+1;if(1&l[w]){const g=e+s[w]*r,B=i-n[w]*r;p+=`Q${v.toFixed(2)},${E.toFixed(2)} ${g.toFixed(2)},${B.toFixed(2)}`,h=w+1}else{const g=(v+(e+s[w]*r))/2,B=(E+(i-n[w]*r))/2;p+=`Q${v.toFixed(2)},${E.toFixed(2)} ${g.toFixed(2)},${B.toFixed(2)}`,h=w}}p+="Z"}a=d+1}}return p}_generateCharacterPath(t,e,i,r,s){const n=t.codePointAt(0)??0,u=e.getGlyphData(n);return u?this._createGlyphPath(e.font,u,i,r,s):null}$generatePositionedCharacterPath(t,e,i,r,s,n,u,l){const p=i+(s-l*(u/e.font.head.unitsPerEm))/2,a=r+(n+.7*u)/2,o=this._generateCharacterPath(t,e,p,a,u);return o&&o.toSVG()||null}}class le{_pathGenerator;constructor(){this._pathGenerator=new oe}$generateSVGHeader(t){const{width:e,height:i}=t;return`<?xml version="1.0" encoding="UTF-8"?><svg width="${e}" height="${i}" viewBox="0 0 ${e} ${i}" xmlns="http://www.w3.org/2000/svg"><title>textmode.js sketch</title>`}$generateSVGFooter(){return"</g></svg>"}_generateTransformAttribute(t,e){const{transform:i,position:r}=t;if(!i.flipHorizontal&&!i.flipVertical&&!i.rotation)return"";const s=r.cellX+e.cellWidth/2,n=r.cellY+e.cellHeight/2,u=[];if(i.flipHorizontal||i.flipVertical){const l=i.flipHorizontal?-1:1,p=i.flipVertical?-1:1;u.push(`translate(${s} ${n})scale(${l} ${p})translate(${-s} ${-n})`)}return i.rotation&&u.push(`rotate(${i.rotation} ${s} ${n})`),` transform="${u.join(" ")}"`}_generateCellBackground(t,e,i){if(!i.includeBackgroundRectangles||t.secondaryColor.a===0)return"";const{position:r}=t,{r:s,g:n,b:u,a:l}=t.secondaryColor,p=`rgba(${s},${n},${u},${l/255})`;return i.drawMode==="stroke"?`<rect x="${r.cellX}" y="${r.cellY}" width="${e.cellWidth}" height="${e.cellHeight}" stroke="${p}" fill="none" stroke-width="${i.strokeWidth}"/>`:`<rect x="${r.cellX}" y="${r.cellY}" width="${e.cellWidth}" height="${e.cellHeight}" fill="${p}"/>`}_generateCharacterPath(t,e,i,r){const s=i.characters[t.charIndex];if(!s)return"";const n=this._pathGenerator.$generatePositionedCharacterPath(s.character,i,t.position.cellX,t.position.cellY,e.cellWidth,e.cellHeight,i.fontSize,s.advanceWidth);if(!n)return"";const{r:u,g:l,b:p,a}=t.primaryColor,o=`rgba(${u},${l},${p},${a/255})`;return r.drawMode==="stroke"?`<path d="${n}" stroke="${o}" stroke-width="${r.strokeWidth}" fill="none"/>`:`<path d="${n}" fill="${o}"/>`}$generateCellContent(t,e,i,r){const s=[],n=this._generateCellBackground(t,e,r);n&&s.push(n);const u=this._generateCharacterPath(t,e,i,r);if(u){const l=this._generateTransformAttribute(t,e);s.push(l?`<g${l}>${u}</g>`:u)}return s.join("")}$generateSVGContent(t,e,i,r){const s=[this.$generateSVGHeader(e),'<g id="ascii-cells">'];for(const n of t)s.push(this.$generateCellContent(n,e,i,r));return s.push(this.$generateSVGFooter()),s.join("")}$optimizeSVGContent(t){return t.replace(/<path[^>]*d=""[^>]*\/>/g,"").replace(/\s+/g," ").replace(/> </g,"><")}}class wt{_applyDefaultOptions(t){return{includeBackgroundRectangles:t.includeBackgroundRectangles??!0,drawMode:t.drawMode??"fill",strokeWidth:t.strokeWidth??1,filename:t.filename}}$generateSVG(t,e={}){const i=new ne,r=new le,s=i.$extractSVGCellData(i.$extractFramebufferData(t.drawFramebuffer),t.grid),n=r.$generateSVGContent(s,t.grid,t.font,this._applyDefaultOptions(e));return r.$optimizeSVGContent(n)}$saveSVG(t,e={}){new X().$downloadFile(new Blob([this.$generateSVG(t,e)],{type:"image/svg+xml;charset=utf-8"}),e.filename)}}const nt={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},de=".png",ce=".jpg",ue=".webp";class yt{_applyDefaultOptions(t){return{format:t.format??"png",scale:Math.abs(t.scale??1),filename:t.filename}}_validateOptions(t){if(!(t.format in nt))throw new Error(`Saving '${t.format}' files is not supported`)}async $generateImageBlob(t,e){const i=t,r=document.createElement("canvas"),s=r.getContext("2d"),n=Math.round(i.width*e.scale),u=Math.round(i.height*e.scale);return r.width=n,r.height=u,s.imageSmoothingEnabled=!1,s.clearRect(0,0,n,u),s.drawImage(i,0,0,i.width,i.height,0,0,n,u),await new Promise((l,p)=>{r.toBlob(a=>{a?l(a):p(new Error(`Failed to generate ${e.format.toUpperCase()} blob`))},nt[e.format])})}async $saveImage(t,e={}){const i=this._applyDefaultOptions(e);this._validateOptions(i);const r=await this.$generateImageBlob(t,i);new X().$downloadFile(r,i.filename)}async $copyImageToClipboard(t,e={}){if(typeof navigator>"u"||!navigator.clipboard||typeof navigator.clipboard.write!="function")throw new Error("Clipboard API is not available in this environment");const i=this._applyDefaultOptions(e);this._validateOptions(i);const r=await this.$generateImageBlob(t,i),s=new ClipboardItem({[nt[i.format]]:r});await navigator.clipboard.write([s])}}class xt{_applyDefaultOptions(t){return{preserveTrailingSpaces:t.preserveTrailingSpaces??!1,emptyCharacter:t.emptyCharacter??" ",filename:t.filename}}_createTXTContent(t,e){const i=new j;let r=i.$extractFramebufferData(t.drawFramebuffer);const s=[];let n=0;for(let l=0;l<t.grid.rows;l++){const p=[];for(let a=0;a<t.grid.cols;a++){const o=4*n,d=i.$getCharacterIndex(r.characterPixels,o),m=t.font.characters[d]?.character||e.emptyCharacter;p.push(m),n++}s.push(p)}const u=[];for(const l of s){let p=l.join("");e.preserveTrailingSpaces||(p=p.replace(/\s+$/,"")),u.push(p)}return u.join(`
|
|
3
|
-
`)}$generateTXT(t,e={}){return this._createTXTContent(t,this._applyDefaultOptions(e))}$saveTXT(t,e={}){const i=this._applyDefaultOptions(e),r=this._createTXTContent(t,i),s=new Blob([r],{type:"text/plain;charset=utf-8"});new X().$downloadFile(s,i.filename)}}class he{_canvas;_ctx;async $record(t,e,i,r){const s=Math.max(1,Math.round(e.frameRate)),n=Math.round(1e3/s),u=Math.max(1,Math.round(e.frameCount));return await new Promise((l,p)=>{const a=[];let o,d=0,m=!1;const y=()=>{o&&(o(),o=void 0)},h=E=>{m||(m=!0,y(),l(E))},v=()=>{if(d>=u)h(a);else try{const E=e.scale,w=Math.max(1,Math.round(t.width*E)),g=Math.max(1,Math.round(t.height*E));this._canvas||(this._canvas=document.createElement("canvas")),this._canvas.width===w&&this._canvas.height===g||(this._canvas.width=w,this._canvas.height=g),this._ctx||(this._ctx=this._canvas.getContext("2d"));const B=this._ctx;B.imageSmoothingEnabled=!1,B.clearRect(0,0,w,g),B.drawImage(t,0,0,t.width,t.height,0,0,w,g);const $={imageData:B.getImageData(0,0,w,g),width:w,height:g,delayMs:n};a.push($),d+=1,r?.({state:"recording",frameIndex:d,totalFrames:u}),d>=u&&h(a)}catch(E){(w=>{if(m)return;m=!0,y();const g=w instanceof Error?w.message:"GIF recording failed";r?.({state:"error",message:g}),p(w instanceof Error?w:new Error(String(w)))})(E)}};o=i(()=>{v()}),r?.({state:"recording",frameIndex:0,totalFrames:u})})}}var _t,tt,Ct=Object.defineProperty,pe=(_t=c=>{function t(o,d,m){return .29889531*o+.58662247*d+.11448223*m}function e(o,d,m){return .59597799*o-.2741761*d-.32180189*m}function i(o,d,m){return .21147017*o-.52261711*d+.31114694*m}function r(o,d){let m=o[0]-d[0],y=o[1]-d[1],h=o[2]-d[2],v=s(o)-s(d);return m*m*.5053+y*y*.299+h*h*.1957+v*v}function s(o){return o[3]!=null?o[3]:255}function n(o,d){return Math.sqrt(r(o,d))}function u(o,d){let[m,y,h]=o,[v,E,w]=d,g=t(m,y,h)-t(v,E,w),B=e(m,y,h)-e(v,E,w),$=i(m,y,h)-i(v,E,w),I=s(o)-s(d);return g*g*.5053+B*B*.299+$*$*.1957+I*I}function l(o,d){return Math.sqrt(u(o,d))}function p(o,d){var m,y=0;for(m=0;m<o.length;m++){let h=o[m]-d[m];y+=h*h}return y}function a(o,d){return Math.sqrt(p(o,d))}Ct(c,"__esModule",{value:!0}),((o,d)=>{for(var m in d)Ct(o,m,{get:d[m],enumerable:!0})})(c,{colorDifferenceRGBToYIQ:()=>l,colorDifferenceRGBToYIQSquared:()=>u,colorDifferenceYIQ:()=>n,colorDifferenceYIQSquared:()=>r,euclideanDistance:()=>a,euclideanDistanceSquared:()=>p})},()=>(tt||_t((tt={exports:{}}).exports,tt),tt.exports)),me=59;function Et(c=256){let t=0,e=new Uint8Array(c);return{get buffer(){return e.buffer},reset(){t=0},bytesView:()=>e.subarray(0,t),bytes:()=>e.slice(0,t),writeByte(r){i(t+1),e[t]=r,t++},writeBytes(r,s=0,n=r.length){i(t+n);for(let u=0;u<n;u++)e[t++]=r[u+s]},writeBytesView(r,s=0,n=r.byteLength){i(t+n),e.set(r.subarray(s,s+n),t),t+=n}};function i(r){var s=e.length;if(s>=r)return;r=Math.max(r,s*(s<1048576?2:1.125)>>>0),s!=0&&(r=Math.max(r,256));let n=e;e=new Uint8Array(r),t>0&&e.set(n.subarray(0,t),0)}}var fe=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],ge=function(c,t,e,i,r,s,n,u){r=r||Et(512),s=s||new Uint8Array(256),n=n||new Int32Array(5003),u=u||new Int32Array(5003);let l=n.length,p=Math.max(2,i);s.fill(0),u.fill(0),k();let a=0,o=0,d=p+1,m=d,y=!1,h=m,v=S(h),E=1<<d-1,w=E+1,g=E+2,B=0,$=e[0],I=0;for(let b=l;b<65536;b*=2)++I;I=8-I,r.writeByte(p),V(E);for(let b=1;b<e.length;b++)L(e[b]);return V($),V(w),r.writeByte(0),r.bytesView();function C(b){s[B++]=b,B>=254&&_()}function k(){n.fill(-1)}function L(b){let D=(b<<12)+$,f=b<<I^$;if(n[f]===D)$=u[f];else{if(n[f]>=0){let x=f===0?1:l-f;do if(f-=x,f<0&&(f+=l),n[f]===D)return void($=u[f]);while(n[f]>=0)}V($),$=b,g<4096?(u[f]=g++,n[f]=D):(k(),g=E+2,y=!0,V(E))}}function _(){B>0&&(r.writeByte(B),r.writeBytesView(s,0,B),B=0)}function S(b){return(1<<b)-1}function V(b){for(a&=fe[o],o>0?a|=b<<o:a=b,o+=h;o>=8;)C(255&a),a>>=8,o-=8;if((g>v||y)&&(y?(h=m,v=S(h),y=!1):(++h,v=h==12?4096:S(h))),b==w){for(;o>0;)C(255&a),a>>=8,o-=8;_()}}};function Bt(c,t,e){return c<<8&63488|t<<2&992|e>>3&31}function It(c,t,e,i){return c>>4|240&t|(240&e)<<4|(240&i)<<8}function Ft(c,t,e){return c>>4<<8|t>>4<<4|e>>4}function et(c,t,e){return c<t?t:c>e?e:c}function it(c){return c*c}function kt(c,t,e){for(var i=0,r=1e100,s=c[t],n=s.cnt,u=(s.ac,s.rc),l=s.gc,p=s.bc,a=s.fw;a!=0;a=c[a].fw){var o=c[a].cnt,d=n*o/(n+o);if(!(d>=r)){var m=0;!((m+=d*it(c[a].rc-u))>=r)&&!((m+=d*it(c[a].gc-l))>=r)&&!((m+=d*it(c[a].bc-p))>=r)&&(r=m,i=a)}}s.err=r,s.nn=i}function ot(){return{ac:0,rc:0,gc:0,bc:0,cnt:0,nn:0,fw:0,bk:0,tm:0,mtm:0,err:0}}function ve(c,t,e){let{format:i="rgb565",clearAlpha:r=!0,clearAlphaColor:s=0,clearAlphaThreshold:n=0,oneBitAlpha:u=!1}=e||{},l=e.useSqrt!==!1,p=i==="rgba4444",a=(function(b,D){let f=new Array(D==="rgb444"?4096:65536),x=b.length;if(D==="rgba4444")for(let M=0;M<x;++M){let P=b[M],A=P>>24&255,O=P>>16&255,F=P>>8&255,T=255&P,U=It(T,F,O,A),W=U in f?f[U]:f[U]=ot();W.rc+=T,W.gc+=F,W.bc+=O,W.ac+=A,W.cnt++}else if(D==="rgb444")for(let M=0;M<x;++M){let P=b[M],A=P>>16&255,O=P>>8&255,F=255&P,T=Ft(F,O,A),U=T in f?f[T]:f[T]=ot();U.rc+=F,U.gc+=O,U.bc+=A,U.cnt++}else for(let M=0;M<x;++M){let P=b[M],A=P>>16&255,O=P>>8&255,F=255&P,T=Bt(F,O,A),U=T in f?f[T]:f[T]=ot();U.rc+=F,U.gc+=O,U.bc+=A,U.cnt++}return f})(c,i),o=a.length,d=o-1,m=new Uint32Array(o+1);for(var y=0,h=0;h<a.length;++h){let b=a[h];if(b!=null){var v=1/b.cnt;p&&(b.ac*=v),b.rc*=v,b.gc*=v,b.bc*=v,a[y++]=b}}for(it(t)/y<.022&&(l=!1),h=0;h<y-1;++h)a[h].fw=h+1,a[h+1].bk=h,l&&(a[h].cnt=Math.sqrt(a[h].cnt));var E,w,g;for(l&&(a[h].cnt=Math.sqrt(a[h].cnt)),h=0;h<y;++h){kt(a,h);var B=a[h].err;for(w=++m[0];w>1&&!(a[E=m[g=w>>1]].err<=B);w=g)m[w]=E;m[w]=h}var $=y-t;for(h=0;h<$;){for(var I;;){var C=m[1];if((I=a[C]).tm>=I.mtm&&a[I.nn].mtm<=I.tm)break;for(I.mtm==d?C=m[1]=m[m[0]--]:(kt(a,C),I.tm=h),B=a[C].err,w=1;(g=w+w)<=m[0]&&(g<m[0]&&a[m[g]].err>a[m[g+1]].err&&g++,!(B<=a[E=m[g]].err));w=g)m[w]=E;m[w]=C}var k=a[I.nn],L=I.cnt,_=k.cnt;v=1/(L+_),p&&(I.ac=v*(L*I.ac+_*k.ac)),I.rc=v*(L*I.rc+_*k.rc),I.gc=v*(L*I.gc+_*k.gc),I.bc=v*(L*I.bc+_*k.bc),I.cnt+=k.cnt,I.mtm=++h,a[k.bk].fw=k.fw,a[k.fw].bk=k.bk,k.mtm=d}let S=[];var V=0;for(h=0;;++V){let b=et(Math.round(a[h].rc),0,255),D=et(Math.round(a[h].gc),0,255),f=et(Math.round(a[h].bc),0,255),x=255;p&&(x=et(Math.round(a[h].ac),0,255),u&&(x=x<=(typeof u=="number"?u:127)?0:255),r&&x<=n&&(b=D=f=s,x=0));let M=p?[b,D,f,x]:[b,D,f];if(be(S,M)||S.push(M),(h=a[h].fw)==0)break}return S}function be(c,t){for(let e=0;e<c.length;e++){let i=c[e],r=i[0]===t[0]&&i[1]===t[1]&&i[2]===t[2],s=!(i.length>=4&&t.length>=4)||i[3]===t[3];if(r&&s)return!0}return!1}function we(c,t,e,i,r){let s=0,n=1e100;for(let u=0;u<r.length;u++){let l=r[u],p=l[0],a=l[1],o=l[2],d=H(l[3]-i);d>n||(d+=H(p-c),!(d>n)&&(d+=H(a-t),!(d>n)&&(d+=H(o-e),!(d>n)&&(n=d,s=u))))}return s}function ye(c,t,e,i){let r=0,s=1e100;for(let n=0;n<i.length;n++){let u=i[n],l=u[0],p=u[1],a=u[2],o=H(l-c);o>s||(o+=H(p-t),!(o>s)&&(o+=H(a-e),!(o>s)&&(s=o,r=n)))}return r}function H(c){return c*c}function xe(c={}){let{initialCapacity:t=4096,auto:e=!0}=c,i=Et(t),r=new Uint8Array(256),s=new Int32Array(5003),n=new Int32Array(5003),u=!1;return{reset(){i.reset(),u=!1},finish(){i.writeByte(me)},bytes:()=>i.bytes(),bytesView:()=>i.bytesView(),get buffer(){return i.buffer},get stream(){return i},writeHeader:l,writeFrame(p,a,o,d={}){let{transparent:m=!1,transparentIndex:y=0,delay:h=0,palette:v=null,repeat:E=0,colorDepth:w=8,dispose:g=-1}=d,B=!1;if(e?u||(B=!0,l(),u=!0):B=!!d.first,a=Math.max(0,Math.floor(a)),o=Math.max(0,Math.floor(o)),B){if(!v)throw new Error("First frame must include a { palette } option");(function(C,k,L,_,S=8){let V=1,b=0,D=lt(_.length)-1,f=V<<7|S-1<<4|b<<3|D;z(C,k),z(C,L),C.writeBytes([f,0,0])})(i,a,o,v,w),Mt(i,v),E>=0&&(function(C,k){C.writeByte(33),C.writeByte(255),C.writeByte(11),St(C,"NETSCAPE2.0"),C.writeByte(3),C.writeByte(1),z(C,k),C.writeByte(0)})(i,E)}let $=Math.round(h/10);(function(C,k,L,_,S){var V,b;C.writeByte(33),C.writeByte(249),C.writeByte(4),S<0&&(S=0,_=!1),_?(V=1,b=2):(V=0,b=0),k>=0&&(b=7&k),b<<=2,C.writeByte(0|b|0|V),z(C,L),C.writeByte(S||0),C.writeByte(0)})(i,g,$,m,y);let I=!!v&&!B;(function(C,k,L,_){if(C.writeByte(44),z(C,0),z(C,0),z(C,k),z(C,L),_){let S=0,V=0,b=lt(_.length)-1;C.writeByte(128|S|V|b)}else C.writeByte(0)})(i,a,o,I?v:null),I&&Mt(i,v),(function(C,k,L,_,S=8,V,b,D){ge(L,_,k,S,C,V,b,D)})(i,p,a,o,w,r,s,n)}};function l(){St(i,"GIF89a")}}function Mt(c,t){let e=1<<lt(t.length);for(let i=0;i<e;i++){let r=[0,0,0];i<t.length&&(r=t[i]),c.writeByte(r[0]),c.writeByte(r[1]),c.writeByte(r[2])}}function z(c,t){c.writeByte(255&t),c.writeByte(t>>8&255)}function St(c,t){for(var e=0;e<t.length;e++)c.writeByte(t.charCodeAt(e))}function lt(c){return Math.max(Math.ceil(Math.log2(c)),1)}pe();class _e{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new he,this._textmodifier=t,this._registerPostDrawHook=e}async $saveGIF(t={}){const e=this._textmodifier.canvas,i=this._applyDefaultOptions(t),r=t.onProgress;try{const s=await this._recorder.$record(e,i,this._registerPostDrawHook,r),n=xe(),{repeat:u}=t;s.forEach((a,o)=>{const{width:d,height:m,imageData:y,delayMs:h}=a,v=new Uint32Array(y.data.buffer.slice(0)),E=ve(v,256,{}),w=(function(g,B,$){let I=($=$||"rgb565")==="rgb444"?4096:65536,C=new Uint8Array(g.length),k=new Array(I);if($==="rgba4444")for(let L=0;L<g.length;L++){let _,S=g[L],V=S>>24&255,b=S>>16&255,D=S>>8&255,f=255&S,x=It(f,D,b,V);k[x]!=null?_=k[x]:(_=we(f,D,b,V,B),k[x]=_),C[L]=_}else for(let L=0;L<g.length;L++){let _,S=g[L],V=S>>16&255,b=S>>8&255,D=255&S,f=$==="rgb444"?Ft(D,b,V):Bt(D,b,V);k[f]!=null?_=k[f]:(_=ye(D,b,V,B),k[f]=_),C[L]=_}return C})(v,E);n.writeFrame(w,d,m,{palette:E,delay:h,repeat:o===0?u:-1})}),n.finish();const l=n.bytes(),p=l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength);new X().$downloadFile(new Blob([p],{type:"image/gif"}),i.filename),r?.({state:"completed",totalFrames:i.frameCount})}catch(s){throw r?.({state:"error",message:s instanceof Error?s.message:"GIF export failed"}),s}}_applyDefaultOptions(t){const e=Math.abs(Math.round(t.frameCount??300)),i=Math.abs(t.frameRate??60),r=Math.abs(t.scale??1),s=Math.max(-1,Math.round(t.repeat??0));return{filename:t.filename,frameCount:e,frameRate:i,scale:r,repeat:s}}}function Ce(c){return c&&c.__esModule&&Object.prototype.hasOwnProperty.call(c,"default")?c.default:c}var $t,Lt={exports:{}};function Ee(){return $t||($t=1,(function(c){(function(){function t(l,p){return(function(a){if(typeof a!="string"||!a.match(/^data:image\/webp;base64,/i))throw new Error("Failed to decode WebP Base64 URL");return window.atob(a.substring(23))})(typeof l=="string"&&/^data:image\/webp/.test(l)?l:l.toDataURL("image/webp",p))}function e(l){return(l.charCodeAt(0)|l.charCodeAt(1)<<8|l.charCodeAt(2)<<16|l.charCodeAt(3)<<24)>>>0}function i(l){let p=l.indexOf("VP8",12);if(p===-1)throw new Error("Bad image format, does this browser support WebP?");let a=!1;for(;p<l.length-8;){let o,d;switch(d=l.substring(p,p+4),p+=4,o=e(l.substring(p,p+4)),p+=4,d){case"VP8 ":return{frame:l.substring(p,p+o),hasAlpha:a};case"ALPH":a=!0}p+=o,1&o&&p++}throw new Error("Failed to find VP8 keyframe in WebP image, is this image mistakenly encoded in the Lossless WebP format?")}function r(l){this.value=l}function s(l){this.value=l}function n(l,p,a){if(Array.isArray(a))for(let o=0;o<a.length;o++)n(l,p,a[o]);else if(typeof a=="string")l.writeString(a);else if(a instanceof Uint8Array)l.writeBytes(a);else{if(!a.id)throw new Error("Bad EBML datatype "+typeof a.data);if(a.offset=l.pos+p,l.writeUnsignedIntBE(a.id),Array.isArray(a.data)){let o,d,m;a.size===-1?l.writeByte(255):a.size===-2?(o=l.pos,l.writeBytes([15,255,255,255,255])):(o=l.pos,l.writeBytes([0,0,0,0])),d=l.pos,a.dataOffset=d+p,n(l,p,a.data),a.size!==-1&&a.size!==-2&&(m=l.pos,a.size=m-d,l.seek(o),l.writeEBMLVarIntWidth(a.size,4),l.seek(m))}else if(typeof a.data=="string")l.writeEBMLVarInt(a.data.length),a.dataOffset=l.pos+p,l.writeString(a.data);else if(typeof a.data=="number")a.size||(a.size=l.measureUnsignedInt(a.data)),l.writeEBMLVarInt(a.size),a.dataOffset=l.pos+p,l.writeUnsignedIntBE(a.data,a.size);else if(a.data instanceof s)l.writeEBMLVarInt(8),a.dataOffset=l.pos+p,l.writeDoubleBE(a.data.value);else if(a.data instanceof r)l.writeEBMLVarInt(4),a.dataOffset=l.pos+p,l.writeFloatBE(a.data.value);else{if(!(a.data instanceof Uint8Array))throw new Error("Bad EBML datatype "+typeof a.data);l.writeEBMLVarInt(a.data.byteLength),a.dataOffset=l.pos+p,l.writeBytes(a.data)}}}let u=function(l,p){return function(a){let o,d,m=!1,y=0,h=0,v=null,E=null,w=null,g=[],B=0,$=0,I={quality:.95,transparent:!1,alphaQuality:void 0,fileWriter:null,fd:null,frameDuration:null,frameRate:null},C={Cues:{id:new Uint8Array([28,83,187,107]),positionEBML:null},SegmentInfo:{id:new Uint8Array([21,73,169,102]),positionEBML:null},Tracks:{id:new Uint8Array([22,84,174,107]),positionEBML:null}},k={id:17545,data:new s(0)},L=[],_=new p(a.fileWriter||a.fd);function S(f){return f-o.dataOffset}function V(){d=(function(){let A={id:21420,size:5,data:0},O={id:290298740,data:[]};for(let F in C){let T=C[F];T.positionEBML=Object.create(A),O.data.push({id:19899,data:[{id:21419,data:T.id},T.positionEBML]})}return O})();let f={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:"webm-writer-js"},{id:22337,data:"webm-writer-js"},k]},x=[{id:176,data:y},{id:186,data:h}];a.transparent&&x.push({id:21440,data:1});let M={id:374648427,data:[{id:174,data:[{id:215,data:1},{id:29637,data:1},{id:156,data:0},{id:2274716,data:"und"},{id:134,data:"V_VP8"},{id:2459272,data:"VP8"},{id:131,data:1},{id:224,data:x}]}]};o={id:408125543,size:-2,data:[d,f,M]};let P=new l(256);n(P,_.pos,[{id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:"webm"},{id:17031,data:2},{id:17029,data:2}]},o]),_.write(P.getAsDataArray()),C.SegmentInfo.positionEBML.data=S(f.offset),C.Tracks.positionEBML.data=S(M.offset),m=!0}function b(f){return f.alpha?(function(x){let M,P,A=new l(4);if(!(x.trackNumber>0&&x.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return A.writeEBMLVarInt(x.trackNumber),A.writeU16BE(x.timecode),A.writeByte(0),M={id:161,data:[A.getAsDataArray(),x.frame]},P={id:30113,data:[{id:166,data:[{id:238,data:1},{id:165,data:x.alpha}]}]},{id:160,data:[M,P]}})(f):(function(x){let M=new l(4);if(!(x.trackNumber>0&&x.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return M.writeEBMLVarInt(x.trackNumber),M.writeU16BE(x.timecode),M.writeByte(128),{id:163,data:[M.getAsDataArray(),x.frame]}})(f)}function D(){if(g.length===0)return;let f=0;for(let F=0;F<g.length;F++)f+=g[F].frame.length+(g[F].alpha?g[F].alpha.length:0);let x=new l(f+64*g.length),M=(function(F){return{id:524531317,data:[{id:231,data:Math.round(F.timecode)}]}})({timecode:Math.round(B)});for(let F=0;F<g.length;F++)M.data.push(b(g[F]));var P,A,O;n(x,_.pos,M),_.write(x.getAsDataArray()),P=1,A=Math.round(B),O=M.offset,L.push({id:187,data:[{id:179,data:A},{id:183,data:[{id:247,data:P},{id:241,data:S(O)}]}]}),g=[],B+=$,$=0}this.addFrame=function(f,x,M){m||(y=f.width||0,h=f.height||0,V());let P,A=i(t(f,a.quality)),O=null;P=M||(typeof x=="number"?x:a.frameDuration),a.transparent&&(x instanceof HTMLCanvasElement||typeof x=="string"?O=x:A.hasAlpha&&(O=(function(F){v!==null&&v.width===F.width&&v.height===F.height||(v=document.createElement("canvas"),v.width=F.width,v.height=F.height,E=v.getContext("2d"),w=E.createImageData(v.width,v.height));let T=F.getContext("2d").getImageData(0,0,F.width,F.height).data,U=w.data,W=0,mi=F.width*F.height*4;for(let gt=3;gt<mi;gt+=4){let vt=T[gt];U[W++]=vt,U[W++]=vt,U[W++]=vt,U[W++]=255}return E.putImageData(w,0,0),v})(f))),(function(F){F.trackNumber=1,F.timecode=Math.round($),g.push(F),$+=F.duration,$>=5e3&&D()})({frame:A.frame,duration:P,alpha:O?i(t(O,a.alphaQuality)).frame:null})},this.complete=function(){return m||V(),D(),(function(){let f={id:475249515,data:L},x=new l(16+32*L.length);n(x,_.pos,f),_.write(x.getAsDataArray()),C.Cues.positionEBML.data=S(f.offset)})(),(function(){let f=new l(d.size),x=_.pos;n(f,d.dataOffset,d.data),_.seek(d.dataOffset),_.write(f.getAsDataArray()),_.seek(x)})(),(function(){let f=new l(8),x=_.pos;f.writeDoubleBE(B),_.seek(k.dataOffset),_.write(f.getAsDataArray()),_.seek(x)})(),(function(){let f=new l(10),x=_.pos;f.writeUnsignedIntBE(o.id),f.writeEBMLVarIntWidth(_.pos-o.dataOffset,5),_.seek(o.offset),_.write(f.getAsDataArray()),_.seek(x)})(),_.complete("video/webm")},this.getWrittenSize=function(){return _.length},a=(function(f,x){let M={};return[f,x].forEach(function(P){for(let A in P)Object.prototype.hasOwnProperty.call(P,A)&&(M[A]=P[A])}),M})(I,a||{}),(function(){if(!a.frameDuration){if(!a.frameRate)throw new Error("Missing required frameDuration or frameRate setting");a.frameDuration=1e3/a.frameRate}a.quality=Math.max(Math.min(a.quality,.99999),0),a.alphaQuality===void 0?a.alphaQuality=a.quality:a.alphaQuality=Math.max(Math.min(a.alphaQuality,.99999),0)})()}};c.exports=u})()})(Lt)),Lt.exports}var Pt,Vt={exports:{}};function Be(){return Pt||(Pt=1,(function(c){(function(){let t=function(e){this.data=new Uint8Array(e),this.pos=0};t.prototype.seek=function(e){this.pos=e},t.prototype.writeBytes=function(e){for(let i=0;i<e.length;i++)this.data[this.pos++]=e[i]},t.prototype.writeByte=function(e){this.data[this.pos++]=e},t.prototype.writeU8=t.prototype.writeByte,t.prototype.writeU16BE=function(e){this.data[this.pos++]=e>>8,this.data[this.pos++]=e},t.prototype.writeDoubleBE=function(e){let i=new Uint8Array(new Float64Array([e]).buffer);for(let r=i.length-1;r>=0;r--)this.writeByte(i[r])},t.prototype.writeFloatBE=function(e){let i=new Uint8Array(new Float32Array([e]).buffer);for(let r=i.length-1;r>=0;r--)this.writeByte(i[r])},t.prototype.writeString=function(e){for(let i=0;i<e.length;i++)this.data[this.pos++]=e.charCodeAt(i)},t.prototype.writeEBMLVarIntWidth=function(e,i){switch(i){case 1:this.writeU8(128|e);break;case 2:this.writeU8(64|e>>8),this.writeU8(e);break;case 3:this.writeU8(32|e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 4:this.writeU8(16|e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 5:this.writeU8(8|e/4294967296&7),this.writeU8(e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;default:throw new Error("Bad EBML VINT size "+i)}},t.prototype.measureEBMLVarInt=function(e){if(e<127)return 1;if(e<16383)return 2;if(e<2097151)return 3;if(e<268435455)return 4;if(e<34359738367)return 5;throw new Error("EBML VINT size not supported "+e)},t.prototype.writeEBMLVarInt=function(e){this.writeEBMLVarIntWidth(e,this.measureEBMLVarInt(e))},t.prototype.writeUnsignedIntBE=function(e,i){switch(i===void 0&&(i=this.measureUnsignedInt(e)),i){case 5:this.writeU8(Math.floor(e/4294967296));case 4:this.writeU8(e>>24);case 3:this.writeU8(e>>16);case 2:this.writeU8(e>>8);case 1:this.writeU8(e);break;default:throw new Error("Bad UINT size "+i)}},t.prototype.measureUnsignedInt=function(e){return e<256?1:e<65536?2:e<1<<24?3:e<4294967296?4:5},t.prototype.getAsDataArray=function(){if(this.pos<this.data.byteLength)return this.data.subarray(0,this.pos);if(this.pos==this.data.byteLength)return this.data;throw new Error("ArrayBufferDataStream's pos lies beyond end of buffer")},c.exports=t})()})(Vt)),Vt.exports}var Dt,At,Ot,Ut={exports:{}};function Ie(){return Dt||(Dt=1,(function(c){(function(){let t=function(e){return function(i){let r=[],s=Promise.resolve(),n=null,u=null;function l(o){return new Promise(function(d,m){let y=new FileReader;y.addEventListener("loadend",function(){d(y.result)}),y.readAsArrayBuffer(o)})}function p(o){return new Promise(function(d,m){o instanceof Uint8Array?d(o):o instanceof ArrayBuffer||ArrayBuffer.isView(o)?d(new Uint8Array(o)):o instanceof Blob?d(l(o).then(function(y){return new Uint8Array(y)})):d(l(new Blob([o])).then(function(y){return new Uint8Array(y)}))})}function a(o){let d=o.byteLength||o.length||o.size;if(!Number.isInteger(d))throw new Error("Failed to determine size of element");return d}i&&i.constructor.name==="FileWriter"?n=i:e&&i&&(u=i),this.pos=0,this.length=0,this.seek=function(o){if(o<0)throw new Error("Offset may not be negative");if(isNaN(o))throw new Error("Offset may not be NaN");if(o>this.length)throw new Error("Seeking beyond the end of file is not allowed");this.pos=o},this.write=function(o){let d={offset:this.pos,data:o,length:a(o)},m=d.offset>=this.length;this.pos+=d.length,this.length=Math.max(this.length,this.pos),s=s.then(function(){if(u)return new Promise(function(y,h){p(d.data).then(function(v){let E=0,w=Buffer.from(v.buffer),g=function(B,$,I){E+=$,E>=I.length?y():e.write(u,I,E,I.length-E,d.offset+E,g)};e.write(u,w,0,w.length,d.offset,g)})});if(n)return new Promise(function(y,h){n.onwriteend=y,n.seek(d.offset),n.write(new Blob([d.data]))});if(!m)for(let y=0;y<r.length;y++){let h=r[y];if(!(d.offset+d.length<=h.offset||d.offset>=h.offset+h.length)){if(d.offset<h.offset||d.offset+d.length>h.offset+h.length)throw new Error("Overwrite crosses blob boundaries");return d.offset==h.offset&&d.length==h.length?void(h.data=d.data):p(h.data).then(function(v){return h.data=v,p(d.data)}).then(function(v){d.data=v,h.data.set(d.data,d.offset-h.offset)})}}r.push(d)})},this.complete=function(o){return s=u||n?s.then(function(){return null}):s.then(function(){let d=[];for(let m=0;m<r.length;m++)d.push(r[m].data);return new Blob(d,{type:o})}),s}}};c.exports=t})()})(Ut)),Ut.exports}function Fe(){return Ot?At:(Ot=1,At=Ee()(Be(),Ie()(null)))}const ke=Ce(Fe());class Me{async $record(t,e,i,r){const s=Math.max(1,Math.round(e.frameRate)),n=Math.max(1,Math.round(e.frameCount)),u=new ke({quality:e.quality,alphaQuality:e.transparent?e.quality:void 0,transparent:e.transparent,frameRate:s}),l=this._createSnapshotSurface();return await new Promise((p,a)=>{let o,d="capturing",m=!1,y=0;const h=()=>{o&&(o(),o=void 0)},v=()=>{r?.({state:"recording",frameIndex:y,totalFrames:n})},E=g=>{if(m)return;m=!0,h();const B=g instanceof Error?g.message:"WEBM export failed";r?.({state:"error",message:B}),a(g instanceof Error?g:new Error(String(g)))},w=()=>{d!=="capturing"||m||(d="encoding",h(),u.complete().then(g=>{(B=>{m||(m=!0,r?.({state:"completed",frameIndex:Math.min(n,y),totalFrames:n}),p(B))})(g)}).catch(E))};o=i(()=>{(()=>{if(d==="capturing")if(y>=n)w();else try{const g=l(t);u.addFrame(g),y+=1,v(),y>=n&&w()}catch(g){E(g)}})()}),v()})}_createSnapshotSurface(){let t=null,e=null;return i=>{const r=Math.max(1,i.width),s=Math.max(1,i.height),n=((u,l)=>(t||(t=document.createElement("canvas")),t.width!==u||t.height!==l?(t.width=u,t.height=l,e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)):e||(e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)),e?t:null))(r,s);return n&&e?(e.clearRect(0,0,r,s),e.drawImage(i,0,0,r,s),n):i}}}class Se{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new Me,this._textmodifier=t,this._registerPostDrawHook=e}async $saveWEBM(t={}){const e=this._textmodifier.canvas,i=this._applyDefaultOptions(t);try{const r=await this._recorder.$record(e,i,this._registerPostDrawHook,t.onProgress);new X().$downloadFile(r,i.filename)}catch(r){throw t.onProgress?.({state:"error",message:r instanceof Error?r.message:"WEBM export failed"}),r}}_applyDefaultOptions(t){return{filename:t.filename,frameRate:Math.abs(Math.round(t.frameRate??60)),frameCount:Math.abs(Math.round(t.frameCount??300)),quality:Math.abs(Math.min(Math.max(t.quality??1,0),1)),transparent:!!t.transparent,debugLogging:!!t.debugLogging}}}const $e="textmode-export-overlay",G="textmode-export-overlay__stack",dt="textmode-export-overlay__stack--dense",Tt="textmode-export-overlay__stack--compact",Nt="textmode-export-overlay__section",Le="textmode-export-overlay__header",Pe="textmode-export-overlay__header-title-row",Ve="textmode-export-overlay__header-links",De="textmode-export-overlay__row",Rt="textmode-export-overlay__label",Gt="textmode-export-overlay__field",Wt="textmode-export-overlay__field--compact",zt="textmode-export-overlay__field--dense",qt="textmode-export-overlay__field--full",Ht="textmode-export-overlay__field--channel",jt="textmode-export-overlay__input",Ae="textmode-export-overlay__checkbox",Qt="textmode-export-overlay__muted",Oe="textmode-export-overlay__status",Ue="textmode-export-overlay__status--gif",Te="textmode-export-overlay__status--video",Ne="textmode-export-overlay__status-title",Re="textmode-export-overlay__status-value",Ge="textmode-export-overlay__divider",We="textmode-export-overlay__title",ze="textmode-export-overlay__button",ct="textmode-export-overlay__button--primary",ut="textmode-export-overlay__button--secondary",Xt="textmode-export-overlay__button--full",qe="textmode-export-overlay__support-link",He="textmode-export-overlay__support-icon",je="textmode-export-overlay__link-icon";class R{element;mounted=!1;destroyed=!1;mount(t){if(this.destroyed)throw new Error("Cannot mount a destroyed component");if(this.mounted)return;const e=this.render();t.appendChild(e),this.element=e,this.onMount(),this.mounted=!0}unmount(){this.mounted&&this.element&&(this._onUnmount(),this.element.remove(),this.element=void 0,this.mounted=!1)}destroy(){this.destroyed||(this.unmount(),this._onDestroy(),this.destroyed=!0)}update(t){this.mounted&&this.onUpdate(t)}onMount(){}_onUnmount(){}_onDestroy(){}onUpdate(t){}get root(){if(!this.element)throw new Error("Component is not mounted yet");return this.element}isMounted(){return this.mounted}}class Y extends R{static _iconNamespace="http://www.w3.org/2000/svg";render(){const t=document.createElement("div");t.classList.add(G,dt,Le);const e=document.createElement("div");e.classList.add(Pe);const i=document.createElement("strong");i.textContent="textmode.export.js",i.classList.add(We);const r=document.createElement("div");r.classList.add(Ve);const s=this._createLink("https://github.com/humanbydefinition/textmode.export.js","View repository on GitHub",je,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5"}]),n=this._createLink("https://code.textmode.art/support.html","Support textmode.export.js",He,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M3 14c.83 .642 2.077 1.017 3.5 1c1.423 .017 2.67 -.358 3.5 -1c.83 -.642 2.077 -1.017 3.5 -1c1.423 -.017 2.67 .358 3.5 1"},{d:"M8 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M12 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M3 10h14v5a6 6 0 0 1 -6 6h-2a6 6 0 0 1 -6 -6v-5z"},{d:"M16.746 16.726a3 3 0 1 0 .252 -5.555"}]);r.appendChild(s),r.appendChild(n),e.appendChild(i),e.appendChild(r);const u=document.createElement("div");return u.classList.add(Ge),t.appendChild(e),t.appendChild(u),t}_createLink(t,e,i,r){const s=document.createElement("a");return s.href=t,s.target="_blank",s.rel="noopener noreferrer",s.classList.add(qe),s.setAttribute("aria-label",e),s.appendChild(this._createIcon(i,r)),s}_createIcon(t,e){const i=document.createElementNS(Y._iconNamespace,"svg");i.setAttribute("xmlns",Y._iconNamespace),i.setAttribute("width","18"),i.setAttribute("height","18"),i.setAttribute("viewBox","0 0 24 24"),i.setAttribute("fill","none"),i.setAttribute("stroke","currentColor"),i.setAttribute("stroke-width","2"),i.setAttribute("stroke-linecap","round"),i.setAttribute("stroke-linejoin","round"),i.classList.add(t);for(const r of e){const s=document.createElementNS(Y._iconNamespace,"path");for(const[n,u]of Object.entries(r))s.setAttribute(n,u);i.appendChild(s)}return i}}class N extends R{props;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.classList.add(Gt),this.applyVariant(t,this.props.variant);const e=document.createElement("label");if(e.classList.add(Rt),e.textContent=this.props.label,this.props.labelFor&&(e.htmlFor=this.props.labelFor),t.appendChild(e),this.props.description){const i=document.createElement("span");i.classList.add(Qt),i.textContent=this.props.description,t.appendChild(i)}return t}attachControl(t){this.root.appendChild(t)}update(t){this.props=t,super.update(t)}onUpdate(t){const e=this.root;for(;e.firstChild;)e.removeChild(e.firstChild);this.props=t,e.classList.add(Gt),this.applyVariant(e,t.variant);const i=document.createElement("label");if(i.classList.add(Rt),i.textContent=t.label,t.labelFor&&(i.htmlFor=t.labelFor),e.appendChild(i),t.description){const r=document.createElement("span");r.classList.add(Qt),r.textContent=t.description,e.appendChild(r)}}applyVariant(t,e){switch(t.classList.remove(Wt,zt,qt,Ht),e){case"compact":t.classList.add(Wt);break;case"dense":t.classList.add(zt);break;case"full":t.classList.add(qt);break;case"channel":t.classList.add(Ht)}}}class ht extends R{props;select;handleChange=()=>{this.props.defaultValue=this.select.value};constructor(t){super(),this.props=t}render(){return this.select=document.createElement("select"),this.select.classList.add(jt),this.props.id&&(this.select.id=this.props.id),this.populateOptions(),this.select.addEventListener("change",this.handleChange),this.select}get selectElement(){return this.select}get value(){return this.select.value}set value(t){this.select&&(this.select.value=t),this.props.defaultValue=t}_onUnmount(){this.select.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,this.populateOptions(),t.defaultValue&&(this.select.value=t.defaultValue)}update(t){this.props={...this.props,...t},this.select&&(t.id&&(this.select.id=t.id),t.options&&this.populateOptions(),t.defaultValue!==void 0&&(this.select.value=t.defaultValue))}populateOptions(){if(this.select){this.select.innerHTML="";for(const t of this.props.options){const e=document.createElement("option");e.value=t.value,e.textContent=t.label,this.select.appendChild(e)}this.props.defaultValue&&(this.select.value=this.props.defaultValue)}}}class Yt extends R{props;button;constructor(t){super(),this.props=t}render(){return this.button=document.createElement("button"),this.button.type="button",this.button.textContent=this.props.label,this.button.classList.add(ze),this.props.variant==="secondary"?this.button.classList.add(ut):this.button.classList.add(ct),this.props.fullWidth&&this.button.classList.add(Xt),this.button.disabled=!!this.props.disabled,this.button}get buttonElement(){return this.button}setLabel(t){this.props.label=t,this.button.textContent=t}setDisabled(t){this.props.disabled=t,this.button.disabled=t}onUpdate(t){this.props=t,this.button.textContent=t.label,this.button.disabled=!!t.disabled,t.variant==="secondary"?(this.button.classList.add(ut),this.button.classList.remove(ct)):(this.button.classList.add(ct),this.button.classList.remove(ut)),this.button.classList.toggle(Xt,!!t.fullWidth)}}class Qe{api;constructor(t){this.api=t}async $copy(t,e){switch(t){case"txt":{const i=this.api.toString(e);await navigator.clipboard.writeText(i);break}case"svg":{const i=this.api.toSVG(e);await navigator.clipboard.writeText(i);break}case"image":await this.api.copyCanvas(e);break;default:throw new Error(`Clipboard not supported for ${t}`)}}}class Xe{api;events;constructor(t,e){this.api=t,this.events=e}async $requestExport(t,e,i={}){this.events.$emit("export:request",{format:t});try{const r={onGIFProgress:i.onGIFProgress?s=>{i.onGIFProgress?.(s),this.events.$emit("export:progress",{format:t,progress:s})}:t==="gif"?s=>this.events.$emit("export:progress",{format:t,progress:s}):void 0,onVideoProgress:i.onVideoProgress?s=>{i.onVideoProgress?.(s),this.events.$emit("export:progress",{format:t,progress:s})}:t==="video"?s=>this.events.$emit("export:progress",{format:t,progress:s}):void 0};await this._execute(t,e,r),this.events.$emit("export:success",{format:t})}catch(r){throw this.events.$emit("export:error",{format:t,error:r}),r}}_execute(t,e,i){switch(t){case"txt":return Promise.resolve(this.api.saveStrings(e));case"image":return this.api.saveCanvas(e);case"svg":return Promise.resolve(this.api.saveSVG(e));case"gif":{const r={...e,onProgress:i.onGIFProgress};return this.api.saveGIF(r)}case"video":{const r={...e,onProgress:i.onVideoProgress};return this.api.saveWEBM(r)}}}}class Ye{modifier;overlay;animationFrameId=null;handleUpdate;bound=!1;constructor(t,e){this.modifier=t,this.overlay=e,this.handleUpdate=()=>this.scheduleUpdate()}scheduleUpdate(){this.animationFrameId!==null&&cancelAnimationFrame(this.animationFrameId),this.animationFrameId=requestAnimationFrame(()=>this.update())}bind(){this.bound||(window.addEventListener("resize",this.handleUpdate),window.addEventListener("scroll",this.handleUpdate,!0),this.bound=!0,this.handleUpdate())}update(){this.animationFrameId=null;const t=this.modifier.canvas.getBoundingClientRect();this.overlay.style.top=`${t.top+window.scrollY+8}px`,this.overlay.style.left=`${t.left+window.scrollX+8}px`}dispose(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.bound&&(window.removeEventListener("resize",this.handleUpdate),window.removeEventListener("scroll",this.handleUpdate,!0),this.bound=!1)}}const J="textmode-export-number-input",Je=`${J}__field`,Ze=`${J}__controls`,Ke=`${J}__control`,Jt=`${J}__display`,rt=`${Jt}--visible`,Zt=c=>{const t=document.createElement("button");return t.type="button",t.className=Ke,t.textContent=c>0?"▲":"▼",t};class q extends R{props;input;display;incrementButton;decrementButton;suppressClickAfterPointer=new WeakMap;holdTimeoutId;holdIntervalId;activePointerId;disabledObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.className=J,this.input=document.createElement("input"),this.input.type="number",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=Je,this.display=document.createElement("div"),this.display.className=Jt;const e=document.createElement("div");return e.className=Ze,this.incrementButton=Zt(1),this.decrementButton=Zt(-1),e.appendChild(this.incrementButton),e.appendChild(this.decrementButton),t.appendChild(this.input),t.appendChild(this.display),t.appendChild(e),this.bindStepControls(),this.bindHoldBehavior(),this.bindInputListeners(),this.observeDisabledState(t),this.updateDisplay(),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateDisplay()}refresh(){this.updateDisplay()}_onDestroy(){this.clearHoldTimers(),this.disabledObserver?.disconnect()}bindStepControls(){const t=s=>()=>{if(this.input.disabled)return;const n=this.input.value,u=this.input.getAttribute("step");if(u&&u!=="any")s>0?this.input.stepUp():this.input.stepDown();else{const p=s>0?1:-1,a=Number.parseFloat(this.input.value||"0"),o=Number.isFinite(a)?a+p:p;this.input.value=String(o)}var l;this.input.value!==n&&((l=this.input).dispatchEvent(new Event("input",{bubbles:!0})),l.dispatchEvent(new Event("change",{bubbles:!0}))),this.updateDisplay(),this.input.focus({preventScroll:!0})},e=t(1),i=t(-1),r=(s,n)=>u=>{if(this.suppressClickAfterPointer.get(s))return this.suppressClickAfterPointer.set(s,!1),void u.preventDefault();n()};this.incrementButton.addEventListener("click",r(this.incrementButton,e)),this.decrementButton.addEventListener("click",r(this.decrementButton,i))}bindHoldBehavior(){const t=(e,i)=>{const r=i>0?()=>this.incrementButton.click():()=>this.decrementButton.click();e.addEventListener("pointerdown",u=>{if(u.button===0){u.preventDefault(),this.suppressClickAfterPointer.set(e,!0),this.activePointerId=u.pointerId;try{e.setPointerCapture(u.pointerId)}catch{}r(),this.holdTimeoutId=window.setTimeout(()=>{this.holdIntervalId=window.setInterval(r,80)},380)}});const s=()=>{if(this.activePointerId!==void 0){try{e.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}},n=()=>{this.clearHoldTimers(),s()};e.addEventListener("pointerup",n),e.addEventListener("pointerleave",n),e.addEventListener("pointercancel",n)};t(this.incrementButton,1),t(this.decrementButton,-1)}bindInputListeners(){const t=()=>{this.props.defaultValue=this.input.value,this.updateDisplay()};this.input.addEventListener("input",t),this.input.addEventListener("change",t)}observeDisabledState(t){const e=()=>{const i=this.input.disabled;this.incrementButton.disabled=i,this.decrementButton.disabled=i,t.classList.toggle("is-disabled",i),i?(this.display.classList.remove(rt),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor")):this.updateDisplay()};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}updateDisplay(){const t=this.props.formatDisplay;if(!t)return this.display.textContent="",this.display.classList.remove(rt),this.input.style.removeProperty("color"),void this.input.style.removeProperty("caretColor");const e=this.input.value,i=Number.parseFloat(e),r=t(Number.isFinite(i)?i:Number.NaN,e,this.input);r?(this.display.textContent=r,this.display.classList.add(rt),this.input.style.color="transparent",this.input.style.caretColor="#f8fafc"):(this.display.textContent="",this.display.classList.remove(rt),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor"))}clearHoldTimers(){this.holdTimeoutId!==void 0&&(window.clearTimeout(this.holdTimeoutId),this.holdTimeoutId=void 0),this.holdIntervalId!==void 0&&(window.clearInterval(this.holdIntervalId),this.holdIntervalId=void 0)}}class Z extends R{variant;additionalClasses;constructor(t="stack",e=[]){super(),this.variant=t,this.additionalClasses=e}render(){const t=document.createElement("div"),e=[this.variant==="stack"?G:void 0,this.variant==="stackDense"?dt:void 0,this.variant==="stackCompact"?Tt:void 0,this.variant==="row"?De:void 0,this.variant==="section"?Nt:void 0,...this.additionalClasses].filter(Boolean);return t.classList.add(...e),t}}const Kt={neutral:"textmode-export-overlay__status-value--neutral",active:"textmode-export-overlay__status-value--active",alert:"textmode-export-overlay__status-value--alert"};class te extends R{props;container;messageElement;constructor(t){super(),this.props=t}render(){this.container=document.createElement("div"),this.container.classList.add(Oe),this.props.context==="gif"?this.container.classList.add(Ue):this.props.context==="video"&&this.container.classList.add(Te);const t=document.createElement("span");return t.classList.add(Ne),t.textContent=this.props.title,this.messageElement=document.createElement("span"),this.messageElement.classList.add(Re),this.messageElement.textContent=this.props.message,this.applyVariant(this.props.variant??"neutral"),this.container.appendChild(t),this.container.appendChild(this.messageElement),this.container}setMessage(t,e="neutral"){this.messageElement.textContent=t,this.applyVariant(e)}onUpdate(t){this.props=t,this.setMessage(t.message,t.variant??"neutral")}applyVariant(t){this.messageElement.classList.remove(...Object.values(Kt)),this.messageElement.classList.add(Kt[t])}}class K extends R{_config;_managedComponents=new Set;constructor(t){super(),this._config=t}_manageComponent(t){return this._managedComponents.add(t),t}_onUnmount(){for(const t of this._managedComponents)t.unmount()}_onDestroy(){for(const t of this._managedComponents)t.destroy();this._managedComponents.clear()}}const ee=300,ie=60,re=1,ti=0;class pt extends K{frameCountInput=this._manageComponent(new q({defaultValue:String(ee),attributes:{min:"1",max:"600",step:"1"}}));frameRateInput=this._manageComponent(new q({defaultValue:String(ie),attributes:{min:"1",max:"60",step:"1"}}));scaleInput=this._manageComponent(new q({defaultValue:String(re),attributes:{min:"0.1",max:"8",step:"0.1"}}));repeatInput=this._manageComponent(new q({defaultValue:"0",attributes:{min:"0",max:"50",step:"1"},formatDisplay:(t,e)=>Number.isFinite(t)?t===0?"∞":null:e.trim()===""?null:e}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"gif"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(G);const e=new Z("row");e.mount(t);const i=new N({label:"number of frames",labelFor:"textmode-export-gif-frame-count",variant:"dense"});i.mount(e.root),this.frameCountInput.mount(i.root),this.frameCountInput.inputElement.id="textmode-export-gif-frame-count";const r=new N({label:"frame rate (fps)",labelFor:"textmode-export-gif-frame-rate",variant:"dense"});r.mount(e.root),this.frameRateInput.mount(r.root),this.frameRateInput.inputElement.id="textmode-export-gif-frame-rate";const s=new Z("row");s.mount(t);const n=new N({label:"scale",labelFor:"textmode-export-gif-scale",variant:"dense"});n.mount(s.root),this.scaleInput.mount(n.root),this.scaleInput.inputElement.id="textmode-export-gif-scale";const u=new N({label:"loop count",labelFor:"textmode-export-gif-repeat",variant:"dense"});return u.mount(s.root),this.repeatInput.mount(u.root),this.repeatInput.inputElement.id="textmode-export-gif-repeat",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{};return{frameCount:this.safeParseInt(this.frameCountInput.value,t.frameCount??300),frameRate:this.safeParseInt(this.frameRateInput.value,t.frameRate??60),scale:this.safeParseFloat(this.scaleInput.value,t.scale??1),repeat:this.safeParseInt(this.repeatInput.value,t.repeat??0)}}reset(){this.recordingState="idle",this.applyDefaults(),this.setRecordingState("idle")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseInt(this.frameRateInput.value,10),i=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&Number.isFinite(i)&&i>0}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const i=t==="recording";switch(this.frameCountInput.inputElement.disabled=i,this.frameRateInput.inputElement.disabled=i,this.scaleInput.inputElement.disabled=i,this.repeatInput.inputElement.disabled=i,t){case"recording":if(e?.totalFrames){const r=e.frameIndex??0;this.status.setMessage(`recording ${r}/${e.totalFrames}`,"active")}else this.status.setMessage("recording…","active");break;case"completed":this.status.setMessage("GIF saved successfully","active");break;case"error":this.status.setMessage(e?.message??"failed to export GIF","alert");break;default:this.status.setMessage("ready to record","neutral")}}handleProgress(t){t.state==="recording"&&t.totalFrames?this.status.setMessage(`recording ${t.frameIndex??0}/${t.totalFrames}`,"active"):t.state==="completed"?this.status.setMessage("GIF saved successfully","active"):t.state==="error"&&this.status.setMessage(t.message??"failed to export GIF","alert")}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??ee,i=t.frameRate??ie,r=t.scale??re,s=t.repeat??ti;this.frameCountInput.value=String(e),this.frameRateInput.value=String(i),this.scaleInput.value=String(r),this.repeatInput.value=String(s),this.frameCountInput.refresh(),this.frameRateInput.refresh(),this.scaleInput.refresh(),this.repeatInput.refresh()}safeParseInt(t,e){const i=Number.parseInt(t,10);return Number.isFinite(i)?i:e}safeParseFloat(t,e){const i=Number.parseFloat(t);return Number.isFinite(i)?i:e}}const st="textmode-export-range-input",ei=`${st}__field`,ii=`${st}__tooltip`,mt=`${st}__tooltip--visible`,at=(c,t)=>{if(typeof c!="string"||c.length===0)return t;const e=Number.parseFloat(c);return Number.isFinite(e)?e:t};class ri extends R{props;input;tooltip;hoverActive=!1;focusActive=!1;pointerActive=!1;suppressFocusFromPointer=!1;activePointerId;disabledObserver;resizeObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");return t.className=st,this.input=document.createElement("input"),this.input.type="range",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=ei,this.tooltip=document.createElement("div"),this.tooltip.className=ii,t.appendChild(this.input),t.appendChild(this.tooltip),this.bindEvents(t),this.updateTooltip(),this.syncDisabledState(t),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateTooltip()}_onDestroy(){this.disabledObserver?.disconnect(),this.resizeObserver?.disconnect()}bindEvents(t){this.input.addEventListener("pointerenter",()=>{this.hoverActive=!0,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerleave",()=>{this.hoverActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("focus",()=>{let i=!1;try{i=this.input.matches(":focus-visible")}catch{i=!this.suppressFocusFromPointer}this.suppressFocusFromPointer||!i||this.input.disabled?this.focusActive=!1:this.focusActive=!0,this.suppressFocusFromPointer=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("blur",()=>{this.focusActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerdown",i=>{this.pointerActive=!0,this.suppressFocusFromPointer=!0,this.hoverActive=!0,this.refreshTooltipVisibility();try{this.input.setPointerCapture(i.pointerId),this.activePointerId=i.pointerId}catch{this.activePointerId=void 0}});const e=()=>{this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.hoverActive=this.input.matches(":hover"),this.releasePointerCapture(),this.refreshTooltipVisibility()};this.input.addEventListener("pointerup",e),this.input.addEventListener("pointercancel",e),this.input.addEventListener("lostpointercapture",e),this.input.addEventListener("input",()=>{(this.hoverActive||this.focusActive||this.pointerActive)&&this.updateTooltip(),this.props.defaultValue=this.input.value}),this.input.addEventListener("change",()=>{this.pointerActive||this.updateTooltip(),this.props.defaultValue=this.input.value}),typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>{this.tooltip.classList.contains(mt)&&this.updateTooltipPosition()}),this.resizeObserver.observe(t))}refreshTooltipVisibility(){const t=(this.hoverActive||this.focusActive||this.pointerActive)&&!this.input.disabled;t&&this.updateTooltip(),this.tooltip.classList.toggle(mt,t)}syncDisabledState(t){const e=()=>{const i=this.input.disabled;t.classList.toggle("is-disabled",i),i&&(this.hoverActive=!1,this.focusActive=!1,this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.releasePointerCapture(),this.tooltip.classList.remove(mt))};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}releasePointerCapture(){if(this.activePointerId!==void 0){try{this.input.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}}updateTooltip(){this.updateTooltipContent(),this.updateTooltipPosition()}updateTooltipContent(){const t=this.props.formatValue??(i=>`${i}`),e=this.getCurrentValue();this.tooltip.textContent=t(e,this.input)}updateTooltipPosition(){const t=this.getMin(),e=this.getMax(),i=((n,u,l)=>Math.min(l,Math.max(u,n)))(this.getCurrentValue(),t,e),r=e-t,s=r===0?0:(i-t)/r;this.tooltip.style.left=100*s+"%"}getMin(){return at(this.input.min,0)}getMax(){return at(this.input.max,100)}getCurrentValue(){return at(this.input.value,at(this.props.defaultValue,0))}}function si(c){return`${(function(e){if(!Number.isFinite(e))return"default quality";const i=Math.max(0,Math.min(1,e));return i>=.995?"near-lossless":i>=.98?"maximum detail":i>=.88?"ultra quality":i>=.7?"high quality":i>=.5?"balanced":i>=.25?"compact":i>=.1?"lightweight":"draft"})(c)} (quality ≈ ${c.toFixed(3)})`}class ft extends K{frameRateInput=this._manageComponent(new q({defaultValue:String(60),attributes:{min:String(1),max:String(60),step:"1"},formatDisplay:t=>Number.isFinite(t)?`${t} fps`:null}));frameCountInput=this._manageComponent(new q({defaultValue:String(480),attributes:{min:String(1),max:String(3600),step:"1"}}));qualityInput=this._manageComponent(new ri({defaultValue:String(.7),attributes:{min:String(0),max:String(1),step:"0.001"},formatValue:t=>si(t)}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"video"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(G);const e=new Z("row");e.mount(t);const i=new N({label:"number of frames",labelFor:"textmode-export-video-frame-count",variant:"compact"});i.mount(e.root),this.frameCountInput.mount(i.root),this.frameCountInput.inputElement.id="textmode-export-video-frame-count";const r=new N({label:"frame rate (fps)",labelFor:"textmode-export-video-frame-rate",variant:"compact"});r.mount(e.root),this.frameRateInput.mount(r.root),this.frameRateInput.inputElement.id="textmode-export-video-frame-rate";const s=new N({label:"quality",labelFor:"textmode-export-video-quality",variant:"full"});return s.mount(t),this.qualityInput.mount(s.root),this.qualityInput.inputElement.id="textmode-export-video-quality",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{},e=Number.parseInt(this.frameCountInput.value,10),i=Number.parseFloat(this.frameRateInput.value),r=Number.parseFloat(this.qualityInput.value);return{frameCount:Number.isFinite(e)?e:t.frameCount??480,frameRate:Number.isFinite(i)?i:t.frameRate??60,quality:Number.isFinite(r)?r:t.quality??.7}}reset(){this.recordingState="idle",this.applyDefaults(),this.status.setMessage("ready to record","neutral")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseFloat(this.frameRateInput.value);return Number.isFinite(t)&&t>=1&&Number.isFinite(e)&&e>=1}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const i=t==="recording";this.frameCountInput.inputElement.disabled=i,this.frameRateInput.inputElement.disabled=i,this.qualityInput.inputElement.disabled=i,this.syncStatus(t,e)}handleProgress(t){this.syncStatus(t.state,t)}syncStatus(t,e){switch(t){case"recording":{const i=e?.frameIndex??0,r=e?.totalFrames??this.resolvePlannedFrameCount();if(r){const s=Math.min(Math.max(0,Math.round(i)),r);this.status.setMessage(`recording ${s}/${r} frames`,"active")}else this.status.setMessage(`recording ${Math.max(0,Math.round(i))} frames`,"active");break}case"completed":this.status.setMessage("saved to disk","active");break;case"error":this.status.setMessage(e?.message?`error: ${e.message}`:"recording failed","alert");break;default:this.status.setMessage("ready to record","neutral")}}resolvePlannedFrameCount(){const t=Number.parseInt(this.frameCountInput.value,10);return Number.isFinite(t)&&t>0?Math.round(t):void 0}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??480,i=t.frameRate??60,r=t.quality??.7;this.frameCountInput.value=String(e),this.frameRateInput.value=String(i),this.qualityInput.value=String(r),this.frameCountInput.refresh(),this.frameRateInput.refresh()}}class ai{_textmodifier;_state;_events;_exportService;_clipboardService;_definitions;_formats=new Map;_eventUnsubscribers=[];_overlayElement;_optionsContainer;_copyButtonContainer;_positionService;_header=new Y;_formatField=new N({label:"export format",labelFor:"textmode-export-format",variant:"full"});_formatSelect=new ht({id:"textmode-export-format",options:[]});_exportButton=new Yt({label:"download file",fullWidth:!0,variant:"primary"});_copyButton=new Yt({label:"copy to clipboard",fullWidth:!0,variant:"primary"});_currentFormat;_currentBlade;_handleFormatSelectChange=()=>{this._handleFormatChange(this._formatSelect.value)};_handleExportClickSafe=()=>{this._handleExportClick().catch(t=>{console.error("[textmode-export] Export failed",t)})};_handleCopyClickSafe=()=>{this._handleCopyClick().catch(t=>{console.error("[textmode-export] Copy failed",t)})};constructor(t,e,i,r,s){this._textmodifier=t,this._state=i,this._events=r,this._exportService=new Xe(e,r),this._clipboardService=new Qe(e),this._definitions=s,this._currentFormat=i.snapshot.format,this._initializeFormatMap(),this._registerEventHandlers()}$mount(){this._createOverlay(),this._renderStaticContent(),this._positionService=new Ye(this._textmodifier,this._overlayElement),this._positionService.bind(),this._switchFormat(this._currentFormat)}$dispose(){this._formatSelect.isMounted()&&this._formatSelect.selectElement.removeEventListener("change",this._handleFormatSelectChange),this._exportButton.isMounted()&&this._exportButton.buttonElement.removeEventListener("click",this._handleExportClickSafe),this._copyButton.isMounted()&&this._copyButton.buttonElement.removeEventListener("click",this._handleCopyClickSafe);for(const t of this._eventUnsubscribers)t();this._eventUnsubscribers.length=0,this._events.$clear();for(const t of this._formats.values())t.blade.destroy();this._formats.clear(),this._currentBlade=void 0,this._overlayElement?.isConnected&&this._overlayElement.remove(),this._positionService?.dispose()}_initializeFormatMap(){for(const t of this._definitions){const e=t.createBlade();this._formats.set(t.format,{definition:t,blade:e,initialized:!1})}}_createOverlay(){this._overlayElement=document.createElement("div"),this._overlayElement.dataset.plugin="textmode-export-overlay",this._overlayElement.classList.add($e,G),document.body.appendChild(this._overlayElement)}_renderStaticContent(){this._header.mount(this._overlayElement);const t=document.createElement("div");t.classList.add(Nt),this._overlayElement.appendChild(t),this._formatField.mount(t),this._prepareFormatOptions(),this._formatSelect.mount(this._formatField.root),this._formatSelect.selectElement.addEventListener("change",this._handleFormatSelectChange),this._optionsContainer=document.createElement("div"),this._optionsContainer.classList.add(G,Tt),this._overlayElement.appendChild(this._optionsContainer),this._exportButton.mount(this._overlayElement),this._exportButton.buttonElement.addEventListener("click",this._handleExportClickSafe),this._copyButtonContainer=document.createElement("div"),this._copyButtonContainer.classList.add(G,dt),this._overlayElement.appendChild(this._copyButtonContainer),this._copyButton.mount(this._copyButtonContainer),this._copyButton.buttonElement.dataset.defaultLabel="copy to clipboard",this._copyButton.buttonElement.addEventListener("click",this._handleCopyClickSafe)}_prepareFormatOptions(){const t=this._definitions.map(e=>({value:e.format,label:e.label}));this._formatSelect.update({options:t,defaultValue:this._currentFormat})}_registerEventHandlers(){this._eventUnsubscribers.push(this._events.$on("export:request",({format:t})=>{t===this._currentFormat&&(this._state.$set({isBusy:!0,error:void 0}),this._updateExportButton())}),this._events.$on("export:success",({format:t})=>{if(t===this._currentFormat){const e={isBusy:!1};t==="gif"&&(e.gifProgress=void 0),t==="video"&&(e.videoProgress=void 0),this._state.$set(e),this._updateExportButton()}}),this._events.$on("export:error",({format:t,error:e})=>{t===this._currentFormat&&(this._state.$set({isBusy:!1,error:e}),this._updateExportButton())}),this._events.$on("export:progress",({format:t,progress:e})=>{if(e){if(t==="gif"&&this._currentBlade?.blade instanceof pt){const i=e;this._state.$set({gifProgress:i}),this._currentBlade.blade.handleProgress(i)}else if(t==="video"&&this._currentBlade?.blade instanceof ft){const i=e;this._state.$set({videoProgress:i}),this._currentBlade.blade.handleProgress(i)}this._updateExportButton()}}))}_handleFormatChange(t){this._currentFormat=t,this._state.$set({format:t}),this._switchFormat(t),this._events.$emit("format:change",{format:t})}_switchFormat(t){const e=this._formats.get(t);if(!e)throw new Error(`Unknown export format: ${t}`);this._currentBlade&&this._currentBlade.blade.unmount(),this._optionsContainer.innerHTML="",e.blade.mount(this._optionsContainer),e.initialized||(e.blade.reset(),e.initialized=!0),this._currentBlade=e,this._formatSelect.value=t,this._updateCopyButtonState(),this._updateExportButton(),this._positionService?.scheduleUpdate()}_updateCopyButtonState(){const t=this._currentBlade?.definition.supportsClipboard??!1;this._copyButtonContainer.style.display=t?"flex":"none",this._copyButton.setDisabled(!t)}async _handleExportClick(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions();if(this._currentBlade.blade.validate()){if(t==="gif"){const i=this._currentBlade.blade;if(i.isRecording())return;i.setRecordingState("recording");try{await this._exportService.$requestExport("gif",e,{onGIFProgress:r=>{i.setRecordingState(r.state,r)}})}catch(r){throw i.setRecordingState("error"),r}return void window.setTimeout(()=>{i.setRecordingState("idle"),this._updateExportButton()},1600)}if(t==="video"){const i=this._currentBlade.blade;if(i.isRecording())return;i.setRecordingState("recording");try{await this._exportService.$requestExport("video",e,{onVideoProgress:r=>{i.setRecordingState(r.state,r)}})}catch(r){throw i.setRecordingState("error"),r}return void window.setTimeout(()=>{i.setRecordingState("idle"),this._updateExportButton()},1600)}this._exportButton.setDisabled(!0),this._exportButton.setLabel("exporting…");try{await this._exportService.$requestExport(t,e)}finally{this._exportButton.setDisabled(!1),this._exportButton.setLabel("download file")}}else console.warn("[textmode-export] Export options failed validation")}async _handleCopyClick(){if(!this._currentBlade||!this._currentBlade.definition.supportsClipboard)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions(),i=this._copyButton.buttonElement.dataset.defaultLabel??"copy to clipboard";this._copyButton.setDisabled(!0),this._copyButton.setLabel("copying…");try{await this._clipboardService.$copy(t,e),this._copyButton.setLabel("copied!")}catch(r){console.error("[textmode-export] Failed to copy to clipboard",r),this._copyButton.setLabel("copy failed!")}finally{window.setTimeout(()=>{this._copyButton.setLabel(i),this._copyButton.setDisabled(!1)},1200)}}_updateExportButton(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format;if(t==="gif"&&this._currentBlade.blade instanceof pt){const i=this._currentBlade.blade,r=this._state.snapshot.gifProgress;if(i.isRecording())if(this._exportButton.setDisabled(!0),r?.totalFrames){const s=r.frameIndex??0;this._exportButton.setLabel(`recording ${s}/${r.totalFrames}`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}if(t==="video"&&this._currentBlade.blade instanceof ft){const i=this._currentBlade.blade,r=this._state.snapshot.videoProgress;if(i.isRecording())if(this._exportButton.setDisabled(!0),r?.totalFrames){const s=r.frameIndex??0;this._exportButton.setLabel(`recording ${s}/${r.totalFrames} frames`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}const e=this._state.snapshot.isBusy;this._exportButton.setDisabled(e),this._exportButton.setLabel(e?"exporting…":"download file")}}class ni{_listeners=new Map;$on(t,e){this._listeners.has(t)||this._listeners.set(t,new Set);const i=this._listeners.get(t);return i.add(e),()=>{i.delete(e),i.size===0&&this._listeners.delete(t)}}$emit(t,e){const i=this._listeners.get(t);if(i)for(const r of[...i])try{r(e)}catch(s){console.error("[textmode-export] Event handler failed",s)}}$clear(){this._listeners.clear()}}class oi{_state;_listeners=new Set;constructor(t){this._state=t}get snapshot(){return Object.freeze({...this._state})}$set(t){this._state=Object.assign({},this._state,t);const e=this.snapshot;for(const i of[...this._listeners])try{i(e)}catch(r){console.error("[textmode-export] State listener failed",r)}}$subscribe(t){return this._listeners.add(t),t(this.snapshot),()=>{this._listeners.delete(t)}}$reset(t){this._state=t;const e=this.snapshot;for(const i of[...this._listeners])i(e)}}class se extends R{props;checkbox;labelElement;handleChange=()=>{this.props.defaultChecked=this.checkbox.checked};constructor(t){super(),this.props=t}render(){this.labelElement=document.createElement("label"),this.labelElement.classList.add(Ae),this.checkbox=document.createElement("input"),this.checkbox.type="checkbox",this.props.id&&(this.checkbox.id=this.props.id),this.checkbox.checked=!!this.props.defaultChecked,this.checkbox.addEventListener("change",this.handleChange);const t=document.createElement("span");return t.textContent=this.props.label,this.labelElement.htmlFor=this.props.id??"",this.labelElement.appendChild(this.checkbox),this.labelElement.appendChild(t),this.labelElement}get inputElement(){return this.checkbox}get checked(){return this.checkbox.checked}set checked(t){this.checkbox.checked=t}_onUnmount(){this.checkbox.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,t.id&&(this.checkbox.id=t.id,this.labelElement.htmlFor=t.id),this.checkbox.checked=!!t.defaultChecked,this.labelElement.lastElementChild&&(this.labelElement.lastElementChild.textContent=t.label)}}class li extends R{props;input;handleInput=()=>{this.props.defaultValue=this.input.value};constructor(t){super(),this.props=t}render(){return this.input=document.createElement("input"),this.input.type="text",this.input.classList.add(jt),this.props.id&&(this.input.id=this.props.id),this.props.maxLength!==void 0&&(this.input.maxLength=this.props.maxLength),this.props.defaultValue!==void 0&&(this.input.value=this.props.defaultValue),this.input.addEventListener("input",this.handleInput),this.input}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t}_onUnmount(){this.input.removeEventListener("input",this.handleInput)}onUpdate(t){this.props=t,t.id&&(this.input.id=t.id),t.maxLength!==void 0&&(this.input.maxLength=t.maxLength),t.defaultValue!==void 0&&(this.input.value=t.defaultValue)}}class di extends K{trailingSpaces=this._manageComponent(new se({label:"preserve trailing spaces",defaultChecked:!1}));emptyCharacter=this._manageComponent(new li({id:"textmode-export-empty-character",defaultValue:" ",maxLength:1}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(G),this.trailingSpaces.mount(t);const e=new N({label:"empty character",labelFor:"textmode-export-empty-character",variant:"full"});return e.mount(t),this.emptyCharacter.mount(e.root),t}getOptions(){const t=this._config.defaultOptions??{},e=this.emptyCharacter.value||t.emptyCharacter||" ";return{preserveTrailingSpaces:this.trailingSpaces.checked,emptyCharacter:e}}reset(){this.applyDefaults()}validate(){return this.emptyCharacter.value.length<=1}applyDefaults(){const t=this._config.defaultOptions??{};this.trailingSpaces.checked=t.preserveTrailingSpaces??!1,this.emptyCharacter.value=t.emptyCharacter??" "}}class ci extends K{formatSelect=this._manageComponent(new ht({id:"textmode-export-image-format",options:[{value:"png",label:`PNG (${de})`},{value:"jpg",label:`JPG (${ce})`},{value:"webp",label:`WEBP (${ue})`}],defaultValue:"png"}));scaleInput=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0.1",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(G);const e=new Z("row");e.mount(t);const i=new N({label:"image format",labelFor:"textmode-export-image-format",variant:"compact"});i.mount(e.root),this.formatSelect.mount(i.root);const r=new N({label:"scale",labelFor:"textmode-export-image-scale",variant:"dense"});return r.mount(e.root),this.scaleInput.mount(r.root),this.scaleInput.inputElement.id="textmode-export-image-scale",t}getOptions(){const t=Number.parseFloat(this.scaleInput.value);return{format:this.formatSelect.value,scale:Number.isFinite(t)?t:this._config.defaultOptions?.scale??1}}reset(){this.applyDefaults(),this.scaleInput.refresh()}validate(){const t=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0}applyDefaults(){const t=this._config.defaultOptions??{};this.formatSelect.value=t.format??"png";const e=t.scale??1;this.scaleInput.value=String(e)}}class ui extends K{includeBackground=this._manageComponent(new se({id:"textmode-export-svg-include-backgrounds",label:"include cell backgrounds",defaultChecked:!0}));drawMode=this._manageComponent(new ht({id:"textmode-export-svg-draw-mode",options:[{value:"fill",label:"fill"},{value:"stroke",label:"stroke"}],defaultValue:"fill"}));strokeWidth=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(G),this.includeBackground.mount(t);const e=new Z("row");e.mount(t);const i=new N({label:"draw mode",labelFor:"textmode-export-svg-draw-mode",variant:"compact"});i.mount(e.root),this.drawMode.mount(i.root);const r=new N({label:"stroke width",labelFor:"textmode-export-svg-stroke-width",variant:"compact"});return r.mount(e.root),this.strokeWidth.mount(r.root),this.strokeWidth.inputElement.id="textmode-export-svg-stroke-width",this.drawMode.selectElement.addEventListener("change",()=>this.updateStrokeControls()),this.updateStrokeControls(),t}getOptions(){return{includeBackgroundRectangles:this.includeBackground.checked,drawMode:this.drawMode.value,strokeWidth:Number.parseFloat(this.strokeWidth.value)}}reset(){this.applyDefaults(),this.updateStrokeControls()}validate(){const t=Number.parseFloat(this.strokeWidth.value);return this.drawMode.value!=="stroke"||Number.isFinite(t)&&t>=0}updateStrokeControls(){const t=this.drawMode.value==="stroke";this.strokeWidth.inputElement.disabled=!t,this.strokeWidth.refresh()}applyDefaults(){const t=this._config.defaultOptions??{};this.includeBackground.checked=t.includeBackgroundRectangles??!0,this.drawMode.value=t.drawMode??"fill";const e=t.strokeWidth??1;this.strokeWidth.value=String(e),this.strokeWidth.refresh()}}const hi=[{format:"txt",label:"plain text (.txt)",supportsClipboard:!0,createBlade:()=>new di({format:"txt",label:"plain text (.txt)",supportsClipboard:!0,defaultOptions:{preserveTrailingSpaces:!1,emptyCharacter:" "}})},{format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,createBlade:()=>new ci({format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,defaultOptions:{format:"png",scale:1}})},{format:"svg",label:"vector (.svg)",supportsClipboard:!0,createBlade:()=>new ui({format:"svg",label:"vector (.svg)",supportsClipboard:!0,defaultOptions:{includeBackgroundRectangles:!0,drawMode:"fill",strokeWidth:1}})},{format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,createBlade:()=>new pt({format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,defaultOptions:{frameCount:300,frameRate:60,scale:1,repeat:0}})},{format:"video",label:"video (.webm)",supportsClipboard:!1,createBlade:()=>new ft({format:"video",label:"video (.webm)",supportsClipboard:!1,defaultOptions:{frameCount:480,frameRate:60,quality:.7}})}];function pi(c,t){const e=hi,i=e[0]?.format,r=new oi((u=>({format:u,isBusy:!1}))(i)),s=new ni,n=new ai(c,t,r,s,e);return n.$mount(),n}const ae=(c={})=>{const t=c.overlay??!0;let e;return{name:"textmode-export",version:"1.0.0",async install(i,r){const s={saveCanvas:async(n={})=>(r.flushDrawCommands(),new yt().$saveImage(i.canvas,n)),copyCanvas:async(n={})=>(r.flushDrawCommands(),new yt().$copyImageToClipboard(i.canvas,n)),saveSVG:(n={})=>{r.flushDrawCommands(),new wt().$saveSVG(i,n)},saveStrings:(n={})=>{r.flushDrawCommands(),new xt().$saveTXT(i,n)},toSVG:(n={})=>(r.flushDrawCommands(),new wt().$generateSVG(i,n)),toString:(n={})=>(r.flushDrawCommands(),new xt().$generateTXT(i,n)),saveGIF:async(n={})=>(r.flushDrawCommands(),new _e(i,r.registerPostDrawHook).$saveGIF(n)),saveWEBM:async(n={})=>(r.flushDrawCommands(),new Se(i,r.registerPostDrawHook).$saveWEBM(n))};Object.assign(i,s),t&&(e=pi(i,s))},async uninstall(i){e?.$dispose(),e=void 0;const r=["saveCanvas","copyCanvas","saveSVG","saveStrings","toSVG","toString","saveGIF","saveWEBM"];for(const s of r)delete i[s]}}};typeof window<"u"&&(window.createTextmodeExportPlugin=ae),Q.createTextmodeExportPlugin=ae,Object.defineProperty(Q,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(Q,j){typeof exports=="object"&&typeof module<"u"?j(exports):typeof define=="function"&&define.amd?define(["exports"],j):j((Q=typeof globalThis<"u"?globalThis:Q||self).TextmodeExport={})})(this,function(Q){"use strict";class j{$extractFramebufferData(t){const e=t.readPixels(0),r=t.readPixels(1),a=t.readPixels(2),i=t.readPixels(3);return{characterPixels:e,primaryColorPixels:r,secondaryColorPixels:a,transformPixels:t.readPixels(4),rotationPixels:i}}$getCharacterIndex(t,e){return t[e]+(t[e+1]<<8)}}class X{$downloadFile(t,e){try{const r=this._sanitizeFilename(e),a=URL.createObjectURL(t),i=document.createElement("a");i.href=a,i.download=r,i.style.display="none",i.rel="noopener",document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(a)}catch(r){console.error("[textmode-export] Failed to download file:",r)}}_sanitizeFilename(t){if(!t)return this._generateDefaultFilename();const e=t.trim();return e?e.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)||this._generateDefaultFilename():this._generateDefaultFilename()}_generateDefaultFilename(){return`textmode-export-${new Date().toISOString().slice(0,19).replace(/:/g,"-")}`}}function vt(c,t){return{r:c[t],g:c[t+1],b:c[t+2],a:c[t+3]}}class ne extends j{_extractTransformData(t,e,r){const a=t[r]===255,i=t[r+1]===255,n=t[r+2]===255,u=e[r]+e[r+1]/255;return{isInverted:a,flipHorizontal:i,flipVertical:n,rotation:Math.round(360*u/255*100)/100}}_calculateCellPosition(t,e,r){return{x:t,y:e,cellX:t*r.cellWidth,cellY:e*r.cellHeight}}$extractSVGCellData(t,e){const r=[];let a=0;for(let i=0;i<e.rows;i++)for(let n=0;n<e.cols;n++){const u=4*a,l=this.$getCharacterIndex(t.characterPixels,u);let h=vt(t.primaryColorPixels,u),o=vt(t.secondaryColorPixels,u);const s=this._extractTransformData(t.transformPixels,t.rotationPixels,u);if(s.isInverted){const m=h;h=o,o=m}const d=this._calculateCellPosition(n,i,e);r.push({charIndex:l,primaryColor:h,secondaryColor:o,transform:s,position:d}),a++}return r}}class se{_createGlyphPath(t,e,r,a,i){const n=i/t.head.unitsPerEm;return{getBoundingBox:()=>({x1:r+e.xMin*n,y1:a+-e.yMax*n,x2:r+e.xMax*n,y2:a+-e.yMin*n}),toSVG:()=>this._glyphToSVGPath(e,r,a,n)}}_glyphToSVGPath(t,e,r,a){if(!t||!t.xs)return"";const{xs:i,ys:n,endPts:u,flags:l}=t;if(!(i&&n&&u&&l))return"";let h="",o=0;for(let s=0;s<u.length;s++){const d=u[s];if(!(d<o)){if(d>=o){const m=e+i[o]*a,y=r-n[o]*a;h+=`M${m.toFixed(2)},${y.toFixed(2)}`;let p=o+1;for(;p<=d;)if(1&l[p]){const b=e+i[p]*a,E=r-n[p]*a;h+=`L${b.toFixed(2)},${E.toFixed(2)}`,p++}else{const b=e+i[p]*a,E=r-n[p]*a;let x=p+1>d?o:p+1;if(1&l[x]){const g=e+i[x]*a,B=r-n[x]*a;h+=`Q${b.toFixed(2)},${E.toFixed(2)} ${g.toFixed(2)},${B.toFixed(2)}`,p=x+1}else{const g=(b+(e+i[x]*a))/2,B=(E+(r-n[x]*a))/2;h+=`Q${b.toFixed(2)},${E.toFixed(2)} ${g.toFixed(2)},${B.toFixed(2)}`,p=x}}h+="Z"}o=d+1}}return h}_generateCharacterPath(t,e,r,a,i){const n=t.codePointAt(0)??0,u=e.getGlyphData(n);return u?this._createGlyphPath(e.font,u,r,a,i):null}$generatePositionedCharacterPath(t,e,r,a,i,n,u,l){const h=r+(i-l*(u/e.font.head.unitsPerEm))/2,o=a+(n+.7*u)/2,s=this._generateCharacterPath(t,e,h,o,u);return s&&s.toSVG()||null}}class le{_pathGenerator;constructor(){this._pathGenerator=new se}$generateSVGHeader(t){const{width:e,height:r}=t;return`<?xml version="1.0" encoding="UTF-8"?><svg width="${e}" height="${r}" viewBox="0 0 ${e} ${r}" xmlns="http://www.w3.org/2000/svg"><title>textmode.js sketch</title>`}$generateSVGFooter(){return"</g></svg>"}_generateTransformAttribute(t,e){const{transform:r,position:a}=t;if(!r.flipHorizontal&&!r.flipVertical&&!r.rotation)return"";const i=a.cellX+e.cellWidth/2,n=a.cellY+e.cellHeight/2,u=[];if(r.flipHorizontal||r.flipVertical){const l=r.flipHorizontal?-1:1,h=r.flipVertical?-1:1;u.push(`translate(${i} ${n})scale(${l} ${h})translate(${-i} ${-n})`)}return r.rotation&&u.push(`rotate(${r.rotation} ${i} ${n})`),` transform="${u.join(" ")}"`}_generateCellBackground(t,e,r){if(!r.includeBackgroundRectangles||t.secondaryColor.a===0)return"";const{position:a}=t,{r:i,g:n,b:u,a:l}=t.secondaryColor,h=`rgba(${i},${n},${u},${l/255})`;return r.drawMode==="stroke"?`<rect x="${a.cellX}" y="${a.cellY}" width="${e.cellWidth}" height="${e.cellHeight}" stroke="${h}" fill="none" stroke-width="${r.strokeWidth}"/>`:`<rect x="${a.cellX}" y="${a.cellY}" width="${e.cellWidth}" height="${e.cellHeight}" fill="${h}"/>`}_generateCharacterPath(t,e,r,a){const i=r.characters[t.charIndex];if(!i)return"";const n=this._pathGenerator.$generatePositionedCharacterPath(i.character,r,t.position.cellX,t.position.cellY,e.cellWidth,e.cellHeight,r.fontSize,i.advanceWidth);if(!n)return"";const{r:u,g:l,b:h,a:o}=t.primaryColor,s=`rgba(${u},${l},${h},${o/255})`;return a.drawMode==="stroke"?`<path d="${n}" stroke="${s}" stroke-width="${a.strokeWidth}" fill="none"/>`:`<path d="${n}" fill="${s}"/>`}$generateCellContent(t,e,r,a){const i=[],n=this._generateCellBackground(t,e,a);n&&i.push(n);const u=this._generateCharacterPath(t,e,r,a);if(u){const l=this._generateTransformAttribute(t,e);i.push(l?`<g${l}>${u}</g>`:u)}return i.join("")}$generateSVGContent(t,e,r,a){const i=[this.$generateSVGHeader(e),'<g id="ascii-cells">'];for(const n of t)i.push(this.$generateCellContent(n,e,r,a));return i.push(this.$generateSVGFooter()),i.join("")}$optimizeSVGContent(t){return t.replace(/<path[^>]*d=""[^>]*\/>/g,"").replace(/\s+/g," ").replace(/> </g,"><")}}class xt{_applyDefaultOptions(t){return{includeBackgroundRectangles:t.includeBackgroundRectangles??!0,drawMode:t.drawMode??"fill",strokeWidth:t.strokeWidth??1,filename:t.filename}}$generateSVG(t,e={}){const r=new ne,a=new le,i=r.$extractSVGCellData(r.$extractFramebufferData(t.drawFramebuffer),t.grid),n=a.$generateSVGContent(i,t.grid,t.font,this._applyDefaultOptions(e));return a.$optimizeSVGContent(n)}$saveSVG(t,e={}){new X().$downloadFile(new Blob([this.$generateSVG(t,e)],{type:"image/svg+xml;charset=utf-8"}),e.filename)}}const nt={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},de=".png",ce=".jpg",ue=".webp";class yt{_applyDefaultOptions(t){return{format:t.format??"png",scale:Math.abs(t.scale??1),filename:t.filename}}_validateOptions(t){if(!(t.format in nt))throw new Error(`Saving '${t.format}' files is not supported`)}async $generateImageBlob(t,e){const r=t,a=document.createElement("canvas"),i=a.getContext("2d"),n=Math.round(r.width*e.scale),u=Math.round(r.height*e.scale);return a.width=n,a.height=u,i.imageSmoothingEnabled=!1,i.clearRect(0,0,n,u),i.drawImage(r,0,0,r.width,r.height,0,0,n,u),await new Promise((l,h)=>{a.toBlob(o=>{o?l(o):h(new Error(`Failed to generate ${e.format.toUpperCase()} blob`))},nt[e.format])})}async $saveImage(t,e={}){const r=this._applyDefaultOptions(e);this._validateOptions(r);const a=await this.$generateImageBlob(t,r);new X().$downloadFile(a,r.filename)}async $copyImageToClipboard(t,e={}){if(typeof navigator>"u"||!navigator.clipboard||typeof navigator.clipboard.write!="function")throw new Error("Clipboard API is not available in this environment");const r=this._applyDefaultOptions(e);this._validateOptions(r);const a=await this.$generateImageBlob(t,r),i=new ClipboardItem({[nt[r.format]]:a});await navigator.clipboard.write([i])}}class _t{_applyDefaultOptions(t){return{preserveTrailingSpaces:t.preserveTrailingSpaces??!1,emptyCharacter:t.emptyCharacter??" ",filename:t.filename}}_createTXTContent(t,e){const r=new j;let a=r.$extractFramebufferData(t.drawFramebuffer);const i=[];let n=0;for(let l=0;l<t.grid.rows;l++){const h=[];for(let o=0;o<t.grid.cols;o++){const s=4*n,d=r.$getCharacterIndex(a.characterPixels,s),m=t.font.characters[d]?.character||e.emptyCharacter;h.push(m),n++}i.push(h)}const u=[];for(const l of i){let h=l.join("");e.preserveTrailingSpaces||(h=h.replace(/\s+$/,"")),u.push(h)}return u.join(`
|
|
2
|
+
`)}$generateTXT(t,e={}){return this._createTXTContent(t,this._applyDefaultOptions(e))}$saveTXT(t,e={}){const r=this._applyDefaultOptions(e),a=this._createTXTContent(t,r),i=new Blob([a],{type:"text/plain;charset=utf-8"});new X().$downloadFile(i,r.filename)}}class pe{_canvas;_ctx;async $record(t,e,r,a){const i=Math.max(1,Math.round(e.frameRate)),n=Math.round(1e3/i),u=Math.max(1,Math.round(e.frameCount));return await new Promise((l,h)=>{const o=[];let s,d=0,m=!1;const y=()=>{s&&(s(),s=void 0)},p=E=>{m||(m=!0,y(),l(E))},b=()=>{if(d>=u)p(o);else try{const E=e.scale,x=Math.max(1,Math.round(t.width*E)),g=Math.max(1,Math.round(t.height*E));this._canvas||(this._canvas=document.createElement("canvas")),this._canvas.width===x&&this._canvas.height===g||(this._canvas.width=x,this._canvas.height=g),this._ctx||(this._ctx=this._canvas.getContext("2d"));const B=this._ctx;B.imageSmoothingEnabled=!1,B.clearRect(0,0,x,g),B.drawImage(t,0,0,t.width,t.height,0,0,x,g);const S={imageData:B.getImageData(0,0,x,g),width:x,height:g,delayMs:n};o.push(S),d+=1,a?.({state:"recording",frameIndex:d,totalFrames:u}),d>=u&&p(o)}catch(E){(x=>{if(m)return;m=!0,y();const g=x instanceof Error?x.message:"GIF recording failed";a?.({state:"error",message:g}),h(x instanceof Error?x:new Error(String(x)))})(E)}};s=r(()=>{b()}),a?.({state:"recording",frameIndex:0,totalFrames:u})})}}var wt,tt,Ct=Object.defineProperty,he=(wt=c=>{function t(s,d,m){return .29889531*s+.58662247*d+.11448223*m}function e(s,d,m){return .59597799*s-.2741761*d-.32180189*m}function r(s,d,m){return .21147017*s-.52261711*d+.31114694*m}function a(s,d){let m=s[0]-d[0],y=s[1]-d[1],p=s[2]-d[2],b=i(s)-i(d);return m*m*.5053+y*y*.299+p*p*.1957+b*b}function i(s){return s[3]!=null?s[3]:255}function n(s,d){return Math.sqrt(a(s,d))}function u(s,d){let[m,y,p]=s,[b,E,x]=d,g=t(m,y,p)-t(b,E,x),B=e(m,y,p)-e(b,E,x),S=r(m,y,p)-r(b,E,x),k=i(s)-i(d);return g*g*.5053+B*B*.299+S*S*.1957+k*k}function l(s,d){return Math.sqrt(u(s,d))}function h(s,d){var m,y=0;for(m=0;m<s.length;m++){let p=s[m]-d[m];y+=p*p}return y}function o(s,d){return Math.sqrt(h(s,d))}Ct(c,"__esModule",{value:!0}),((s,d)=>{for(var m in d)Ct(s,m,{get:d[m],enumerable:!0})})(c,{colorDifferenceRGBToYIQ:()=>l,colorDifferenceRGBToYIQSquared:()=>u,colorDifferenceYIQ:()=>n,colorDifferenceYIQSquared:()=>a,euclideanDistance:()=>o,euclideanDistanceSquared:()=>h})},()=>(tt||wt((tt={exports:{}}).exports,tt),tt.exports)),me=59;function Et(c=256){let t=0,e=new Uint8Array(c);return{get buffer(){return e.buffer},reset(){t=0},bytesView:()=>e.subarray(0,t),bytes:()=>e.slice(0,t),writeByte(a){r(t+1),e[t]=a,t++},writeBytes(a,i=0,n=a.length){r(t+n);for(let u=0;u<n;u++)e[t++]=a[u+i]},writeBytesView(a,i=0,n=a.byteLength){r(t+n),e.set(a.subarray(i,i+n),t),t+=n}};function r(a){var i=e.length;if(i>=a)return;a=Math.max(a,i*(i<1048576?2:1.125)>>>0),i!=0&&(a=Math.max(a,256));let n=e;e=new Uint8Array(a),t>0&&e.set(n.subarray(0,t),0)}}var fe=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],ge=function(c,t,e,r,a,i,n,u){a=a||Et(512),i=i||new Uint8Array(256),n=n||new Int32Array(5003),u=u||new Int32Array(5003);let l=n.length,h=Math.max(2,r);i.fill(0),u.fill(0),F();let o=0,s=0,d=h+1,m=d,y=!1,p=m,b=$(p),E=1<<d-1,x=E+1,g=E+2,B=0,S=e[0],k=0;for(let v=l;v<65536;v*=2)++k;k=8-k,a.writeByte(h),V(E);for(let v=1;v<e.length;v++)L(e[v]);return V(S),V(x),a.writeByte(0),a.bytesView();function C(v){i[B++]=v,B>=254&&w()}function F(){n.fill(-1)}function L(v){let D=(v<<12)+S,f=v<<k^S;if(n[f]===D)S=u[f];else{if(n[f]>=0){let _=f===0?1:l-f;do if(f-=_,f<0&&(f+=l),n[f]===D)return void(S=u[f]);while(n[f]>=0)}V(S),S=v,g<4096?(u[f]=g++,n[f]=D):(F(),g=E+2,y=!0,V(E))}}function w(){B>0&&(a.writeByte(B),a.writeBytesView(i,0,B),B=0)}function $(v){return(1<<v)-1}function V(v){for(o&=fe[s],s>0?o|=v<<s:o=v,s+=p;s>=8;)C(255&o),o>>=8,s-=8;if((g>b||y)&&(y?(p=m,b=$(p),y=!1):(++p,b=p==12?4096:$(p))),v==x){for(;s>0;)C(255&o),o>>=8,s-=8;w()}}};function Bt(c,t,e){return c<<8&63488|t<<2&992|e>>3&31}function kt(c,t,e,r){return c>>4|240&t|(240&e)<<4|(240&r)<<8}function It(c,t,e){return c>>4<<8|t>>4<<4|e>>4}function et(c,t,e){return c<t?t:c>e?e:c}function rt(c){return c*c}function Ft(c,t,e){for(var r=0,a=1e100,i=c[t],n=i.cnt,u=(i.ac,i.rc),l=i.gc,h=i.bc,o=i.fw;o!=0;o=c[o].fw){var s=c[o].cnt,d=n*s/(n+s);if(!(d>=a)){var m=0;!((m+=d*rt(c[o].rc-u))>=a)&&!((m+=d*rt(c[o].gc-l))>=a)&&!((m+=d*rt(c[o].bc-h))>=a)&&(a=m,r=o)}}i.err=a,i.nn=r}function st(){return{ac:0,rc:0,gc:0,bc:0,cnt:0,nn:0,fw:0,bk:0,tm:0,mtm:0,err:0}}function be(c,t,e){let{format:r="rgb565",clearAlpha:a=!0,clearAlphaColor:i=0,clearAlphaThreshold:n=0,oneBitAlpha:u=!1}=e||{},l=e.useSqrt!==!1,h=r==="rgba4444",o=(function(v,D){let f=new Array(D==="rgb444"?4096:65536),_=v.length;if(D==="rgba4444")for(let M=0;M<_;++M){let P=v[M],A=P>>24&255,O=P>>16&255,I=P>>8&255,T=255&P,U=kt(T,I,O,A),G=U in f?f[U]:f[U]=st();G.rc+=T,G.gc+=I,G.bc+=O,G.ac+=A,G.cnt++}else if(D==="rgb444")for(let M=0;M<_;++M){let P=v[M],A=P>>16&255,O=P>>8&255,I=255&P,T=It(I,O,A),U=T in f?f[T]:f[T]=st();U.rc+=I,U.gc+=O,U.bc+=A,U.cnt++}else for(let M=0;M<_;++M){let P=v[M],A=P>>16&255,O=P>>8&255,I=255&P,T=Bt(I,O,A),U=T in f?f[T]:f[T]=st();U.rc+=I,U.gc+=O,U.bc+=A,U.cnt++}return f})(c,r),s=o.length,d=s-1,m=new Uint32Array(s+1);for(var y=0,p=0;p<o.length;++p){let v=o[p];if(v!=null){var b=1/v.cnt;h&&(v.ac*=b),v.rc*=b,v.gc*=b,v.bc*=b,o[y++]=v}}for(rt(t)/y<.022&&(l=!1),p=0;p<y-1;++p)o[p].fw=p+1,o[p+1].bk=p,l&&(o[p].cnt=Math.sqrt(o[p].cnt));var E,x,g;for(l&&(o[p].cnt=Math.sqrt(o[p].cnt)),p=0;p<y;++p){Ft(o,p);var B=o[p].err;for(x=++m[0];x>1&&!(o[E=m[g=x>>1]].err<=B);x=g)m[x]=E;m[x]=p}var S=y-t;for(p=0;p<S;){for(var k;;){var C=m[1];if((k=o[C]).tm>=k.mtm&&o[k.nn].mtm<=k.tm)break;for(k.mtm==d?C=m[1]=m[m[0]--]:(Ft(o,C),k.tm=p),B=o[C].err,x=1;(g=x+x)<=m[0]&&(g<m[0]&&o[m[g]].err>o[m[g+1]].err&&g++,!(B<=o[E=m[g]].err));x=g)m[x]=E;m[x]=C}var F=o[k.nn],L=k.cnt,w=F.cnt;b=1/(L+w),h&&(k.ac=b*(L*k.ac+w*F.ac)),k.rc=b*(L*k.rc+w*F.rc),k.gc=b*(L*k.gc+w*F.gc),k.bc=b*(L*k.bc+w*F.bc),k.cnt+=F.cnt,k.mtm=++p,o[F.bk].fw=F.fw,o[F.fw].bk=F.bk,F.mtm=d}let $=[];var V=0;for(p=0;;++V){let v=et(Math.round(o[p].rc),0,255),D=et(Math.round(o[p].gc),0,255),f=et(Math.round(o[p].bc),0,255),_=255;h&&(_=et(Math.round(o[p].ac),0,255),u&&(_=_<=(typeof u=="number"?u:127)?0:255),a&&_<=n&&(v=D=f=i,_=0));let M=h?[v,D,f,_]:[v,D,f];if(ve($,M)||$.push(M),(p=o[p].fw)==0)break}return $}function ve(c,t){for(let e=0;e<c.length;e++){let r=c[e],a=r[0]===t[0]&&r[1]===t[1]&&r[2]===t[2],i=!(r.length>=4&&t.length>=4)||r[3]===t[3];if(a&&i)return!0}return!1}function xe(c,t,e,r,a){let i=0,n=1e100;for(let u=0;u<a.length;u++){let l=a[u],h=l[0],o=l[1],s=l[2],d=H(l[3]-r);d>n||(d+=H(h-c),!(d>n)&&(d+=H(o-t),!(d>n)&&(d+=H(s-e),!(d>n)&&(n=d,i=u))))}return i}function ye(c,t,e,r){let a=0,i=1e100;for(let n=0;n<r.length;n++){let u=r[n],l=u[0],h=u[1],o=u[2],s=H(l-c);s>i||(s+=H(h-t),!(s>i)&&(s+=H(o-e),!(s>i)&&(i=s,a=n)))}return a}function H(c){return c*c}function _e(c={}){let{initialCapacity:t=4096,auto:e=!0}=c,r=Et(t),a=new Uint8Array(256),i=new Int32Array(5003),n=new Int32Array(5003),u=!1;return{reset(){r.reset(),u=!1},finish(){r.writeByte(me)},bytes:()=>r.bytes(),bytesView:()=>r.bytesView(),get buffer(){return r.buffer},get stream(){return r},writeHeader:l,writeFrame(h,o,s,d={}){let{transparent:m=!1,transparentIndex:y=0,delay:p=0,palette:b=null,repeat:E=0,colorDepth:x=8,dispose:g=-1}=d,B=!1;if(e?u||(B=!0,l(),u=!0):B=!!d.first,o=Math.max(0,Math.floor(o)),s=Math.max(0,Math.floor(s)),B){if(!b)throw new Error("First frame must include a { palette } option");(function(C,F,L,w,$=8){let V=1,v=0,D=lt(w.length)-1,f=V<<7|$-1<<4|v<<3|D;W(C,F),W(C,L),C.writeBytes([f,0,0])})(r,o,s,b,x),Mt(r,b),E>=0&&(function(C,F){C.writeByte(33),C.writeByte(255),C.writeByte(11),$t(C,"NETSCAPE2.0"),C.writeByte(3),C.writeByte(1),W(C,F),C.writeByte(0)})(r,E)}let S=Math.round(p/10);(function(C,F,L,w,$){var V,v;C.writeByte(33),C.writeByte(249),C.writeByte(4),$<0&&($=0,w=!1),w?(V=1,v=2):(V=0,v=0),F>=0&&(v=7&F),v<<=2,C.writeByte(0|v|0|V),W(C,L),C.writeByte($||0),C.writeByte(0)})(r,g,S,m,y);let k=!!b&&!B;(function(C,F,L,w){if(C.writeByte(44),W(C,0),W(C,0),W(C,F),W(C,L),w){let $=0,V=0,v=lt(w.length)-1;C.writeByte(128|$|V|v)}else C.writeByte(0)})(r,o,s,k?b:null),k&&Mt(r,b),(function(C,F,L,w,$=8,V,v,D){ge(L,w,F,$,C,V,v,D)})(r,h,o,s,x,a,i,n)}};function l(){$t(r,"GIF89a")}}function Mt(c,t){let e=1<<lt(t.length);for(let r=0;r<e;r++){let a=[0,0,0];r<t.length&&(a=t[r]),c.writeByte(a[0]),c.writeByte(a[1]),c.writeByte(a[2])}}function W(c,t){c.writeByte(255&t),c.writeByte(t>>8&255)}function $t(c,t){for(var e=0;e<t.length;e++)c.writeByte(t.charCodeAt(e))}function lt(c){return Math.max(Math.ceil(Math.log2(c)),1)}he();class we{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new pe,this._textmodifier=t,this._registerPostDrawHook=e}async $saveGIF(t={}){const e=this._textmodifier.canvas,r=this._applyDefaultOptions(t),a=t.onProgress;try{const i=await this._recorder.$record(e,r,this._registerPostDrawHook,a),n=_e(),{repeat:u}=t;i.forEach((o,s)=>{const{width:d,height:m,imageData:y,delayMs:p}=o,b=new Uint32Array(y.data.buffer.slice(0)),E=be(b,256,{}),x=(function(g,B,S){let k=(S=S||"rgb565")==="rgb444"?4096:65536,C=new Uint8Array(g.length),F=new Array(k);if(S==="rgba4444")for(let L=0;L<g.length;L++){let w,$=g[L],V=$>>24&255,v=$>>16&255,D=$>>8&255,f=255&$,_=kt(f,D,v,V);F[_]!=null?w=F[_]:(w=xe(f,D,v,V,B),F[_]=w),C[L]=w}else for(let L=0;L<g.length;L++){let w,$=g[L],V=$>>16&255,v=$>>8&255,D=255&$,f=S==="rgb444"?It(D,v,V):Bt(D,v,V);F[f]!=null?w=F[f]:(w=ye(D,v,V,B),F[f]=w),C[L]=w}return C})(b,E);n.writeFrame(x,d,m,{palette:E,delay:p,repeat:s===0?u:-1})}),n.finish();const l=n.bytes(),h=l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength);new X().$downloadFile(new Blob([h],{type:"image/gif"}),r.filename),a?.({state:"completed",totalFrames:r.frameCount})}catch(i){throw a?.({state:"error",message:i instanceof Error?i.message:"GIF export failed"}),i}}_applyDefaultOptions(t){const e=Math.abs(Math.round(t.frameCount??300)),r=Math.abs(t.frameRate??60),a=Math.abs(t.scale??1),i=Math.max(-1,Math.round(t.repeat??0));return{filename:t.filename,frameCount:e,frameRate:r,scale:a,repeat:i}}}function Ce(c){return c&&c.__esModule&&Object.prototype.hasOwnProperty.call(c,"default")?c.default:c}var St,Lt={exports:{}};function Ee(){return St||(St=1,(function(c){(function(){function t(l,h){return(function(o){if(typeof o!="string"||!o.match(/^data:image\/webp;base64,/i))throw new Error("Failed to decode WebP Base64 URL");return window.atob(o.substring(23))})(typeof l=="string"&&/^data:image\/webp/.test(l)?l:l.toDataURL("image/webp",h))}function e(l){return(l.charCodeAt(0)|l.charCodeAt(1)<<8|l.charCodeAt(2)<<16|l.charCodeAt(3)<<24)>>>0}function r(l){let h=l.indexOf("VP8",12);if(h===-1)throw new Error("Bad image format, does this browser support WebP?");let o=!1;for(;h<l.length-8;){let s,d;switch(d=l.substring(h,h+4),h+=4,s=e(l.substring(h,h+4)),h+=4,d){case"VP8 ":return{frame:l.substring(h,h+s),hasAlpha:o};case"ALPH":o=!0}h+=s,1&s&&h++}throw new Error("Failed to find VP8 keyframe in WebP image, is this image mistakenly encoded in the Lossless WebP format?")}function a(l){this.value=l}function i(l){this.value=l}function n(l,h,o){if(Array.isArray(o))for(let s=0;s<o.length;s++)n(l,h,o[s]);else if(typeof o=="string")l.writeString(o);else if(o instanceof Uint8Array)l.writeBytes(o);else{if(!o.id)throw new Error("Bad EBML datatype "+typeof o.data);if(o.offset=l.pos+h,l.writeUnsignedIntBE(o.id),Array.isArray(o.data)){let s,d,m;o.size===-1?l.writeByte(255):o.size===-2?(s=l.pos,l.writeBytes([15,255,255,255,255])):(s=l.pos,l.writeBytes([0,0,0,0])),d=l.pos,o.dataOffset=d+h,n(l,h,o.data),o.size!==-1&&o.size!==-2&&(m=l.pos,o.size=m-d,l.seek(s),l.writeEBMLVarIntWidth(o.size,4),l.seek(m))}else if(typeof o.data=="string")l.writeEBMLVarInt(o.data.length),o.dataOffset=l.pos+h,l.writeString(o.data);else if(typeof o.data=="number")o.size||(o.size=l.measureUnsignedInt(o.data)),l.writeEBMLVarInt(o.size),o.dataOffset=l.pos+h,l.writeUnsignedIntBE(o.data,o.size);else if(o.data instanceof i)l.writeEBMLVarInt(8),o.dataOffset=l.pos+h,l.writeDoubleBE(o.data.value);else if(o.data instanceof a)l.writeEBMLVarInt(4),o.dataOffset=l.pos+h,l.writeFloatBE(o.data.value);else{if(!(o.data instanceof Uint8Array))throw new Error("Bad EBML datatype "+typeof o.data);l.writeEBMLVarInt(o.data.byteLength),o.dataOffset=l.pos+h,l.writeBytes(o.data)}}}let u=function(l,h){return function(o){let s,d,m=!1,y=0,p=0,b=null,E=null,x=null,g=[],B=0,S=0,k={quality:.95,transparent:!1,alphaQuality:void 0,fileWriter:null,fd:null,frameDuration:null,frameRate:null},C={Cues:{id:new Uint8Array([28,83,187,107]),positionEBML:null},SegmentInfo:{id:new Uint8Array([21,73,169,102]),positionEBML:null},Tracks:{id:new Uint8Array([22,84,174,107]),positionEBML:null}},F={id:17545,data:new i(0)},L=[],w=new h(o.fileWriter||o.fd);function $(f){return f-s.dataOffset}function V(){d=(function(){let A={id:21420,size:5,data:0},O={id:290298740,data:[]};for(let I in C){let T=C[I];T.positionEBML=Object.create(A),O.data.push({id:19899,data:[{id:21419,data:T.id},T.positionEBML]})}return O})();let f={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:"webm-writer-js"},{id:22337,data:"webm-writer-js"},F]},_=[{id:176,data:y},{id:186,data:p}];o.transparent&&_.push({id:21440,data:1});let M={id:374648427,data:[{id:174,data:[{id:215,data:1},{id:29637,data:1},{id:156,data:0},{id:2274716,data:"und"},{id:134,data:"V_VP8"},{id:2459272,data:"VP8"},{id:131,data:1},{id:224,data:_}]}]};s={id:408125543,size:-2,data:[d,f,M]};let P=new l(256);n(P,w.pos,[{id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:"webm"},{id:17031,data:2},{id:17029,data:2}]},s]),w.write(P.getAsDataArray()),C.SegmentInfo.positionEBML.data=$(f.offset),C.Tracks.positionEBML.data=$(M.offset),m=!0}function v(f){return f.alpha?(function(_){let M,P,A=new l(4);if(!(_.trackNumber>0&&_.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return A.writeEBMLVarInt(_.trackNumber),A.writeU16BE(_.timecode),A.writeByte(0),M={id:161,data:[A.getAsDataArray(),_.frame]},P={id:30113,data:[{id:166,data:[{id:238,data:1},{id:165,data:_.alpha}]}]},{id:160,data:[M,P]}})(f):(function(_){let M=new l(4);if(!(_.trackNumber>0&&_.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return M.writeEBMLVarInt(_.trackNumber),M.writeU16BE(_.timecode),M.writeByte(128),{id:163,data:[M.getAsDataArray(),_.frame]}})(f)}function D(){if(g.length===0)return;let f=0;for(let I=0;I<g.length;I++)f+=g[I].frame.length+(g[I].alpha?g[I].alpha.length:0);let _=new l(f+64*g.length),M=(function(I){return{id:524531317,data:[{id:231,data:Math.round(I.timecode)}]}})({timecode:Math.round(B)});for(let I=0;I<g.length;I++)M.data.push(v(g[I]));var P,A,O;n(_,w.pos,M),w.write(_.getAsDataArray()),P=1,A=Math.round(B),O=M.offset,L.push({id:187,data:[{id:179,data:A},{id:183,data:[{id:247,data:P},{id:241,data:$(O)}]}]}),g=[],B+=S,S=0}this.addFrame=function(f,_,M){m||(y=f.width||0,p=f.height||0,V());let P,A=r(t(f,o.quality)),O=null;P=M||(typeof _=="number"?_:o.frameDuration),o.transparent&&(_ instanceof HTMLCanvasElement||typeof _=="string"?O=_:A.hasAlpha&&(O=(function(I){b!==null&&b.width===I.width&&b.height===I.height||(b=document.createElement("canvas"),b.width=I.width,b.height=I.height,E=b.getContext("2d"),x=E.createImageData(b.width,b.height));let T=I.getContext("2d").getImageData(0,0,I.width,I.height).data,U=x.data,G=0,mr=I.width*I.height*4;for(let gt=3;gt<mr;gt+=4){let bt=T[gt];U[G++]=bt,U[G++]=bt,U[G++]=bt,U[G++]=255}return E.putImageData(x,0,0),b})(f))),(function(I){I.trackNumber=1,I.timecode=Math.round(S),g.push(I),S+=I.duration,S>=5e3&&D()})({frame:A.frame,duration:P,alpha:O?r(t(O,o.alphaQuality)).frame:null})},this.complete=function(){return m||V(),D(),(function(){let f={id:475249515,data:L},_=new l(16+32*L.length);n(_,w.pos,f),w.write(_.getAsDataArray()),C.Cues.positionEBML.data=$(f.offset)})(),(function(){let f=new l(d.size),_=w.pos;n(f,d.dataOffset,d.data),w.seek(d.dataOffset),w.write(f.getAsDataArray()),w.seek(_)})(),(function(){let f=new l(8),_=w.pos;f.writeDoubleBE(B),w.seek(F.dataOffset),w.write(f.getAsDataArray()),w.seek(_)})(),(function(){let f=new l(10),_=w.pos;f.writeUnsignedIntBE(s.id),f.writeEBMLVarIntWidth(w.pos-s.dataOffset,5),w.seek(s.offset),w.write(f.getAsDataArray()),w.seek(_)})(),w.complete("video/webm")},this.getWrittenSize=function(){return w.length},o=(function(f,_){let M={};return[f,_].forEach(function(P){for(let A in P)Object.prototype.hasOwnProperty.call(P,A)&&(M[A]=P[A])}),M})(k,o||{}),(function(){if(!o.frameDuration){if(!o.frameRate)throw new Error("Missing required frameDuration or frameRate setting");o.frameDuration=1e3/o.frameRate}o.quality=Math.max(Math.min(o.quality,.99999),0),o.alphaQuality===void 0?o.alphaQuality=o.quality:o.alphaQuality=Math.max(Math.min(o.alphaQuality,.99999),0)})()}};c.exports=u})()})(Lt)),Lt.exports}var Pt,Vt={exports:{}};function Be(){return Pt||(Pt=1,(function(c){(function(){let t=function(e){this.data=new Uint8Array(e),this.pos=0};t.prototype.seek=function(e){this.pos=e},t.prototype.writeBytes=function(e){for(let r=0;r<e.length;r++)this.data[this.pos++]=e[r]},t.prototype.writeByte=function(e){this.data[this.pos++]=e},t.prototype.writeU8=t.prototype.writeByte,t.prototype.writeU16BE=function(e){this.data[this.pos++]=e>>8,this.data[this.pos++]=e},t.prototype.writeDoubleBE=function(e){let r=new Uint8Array(new Float64Array([e]).buffer);for(let a=r.length-1;a>=0;a--)this.writeByte(r[a])},t.prototype.writeFloatBE=function(e){let r=new Uint8Array(new Float32Array([e]).buffer);for(let a=r.length-1;a>=0;a--)this.writeByte(r[a])},t.prototype.writeString=function(e){for(let r=0;r<e.length;r++)this.data[this.pos++]=e.charCodeAt(r)},t.prototype.writeEBMLVarIntWidth=function(e,r){switch(r){case 1:this.writeU8(128|e);break;case 2:this.writeU8(64|e>>8),this.writeU8(e);break;case 3:this.writeU8(32|e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 4:this.writeU8(16|e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 5:this.writeU8(8|e/4294967296&7),this.writeU8(e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;default:throw new Error("Bad EBML VINT size "+r)}},t.prototype.measureEBMLVarInt=function(e){if(e<127)return 1;if(e<16383)return 2;if(e<2097151)return 3;if(e<268435455)return 4;if(e<34359738367)return 5;throw new Error("EBML VINT size not supported "+e)},t.prototype.writeEBMLVarInt=function(e){this.writeEBMLVarIntWidth(e,this.measureEBMLVarInt(e))},t.prototype.writeUnsignedIntBE=function(e,r){switch(r===void 0&&(r=this.measureUnsignedInt(e)),r){case 5:this.writeU8(Math.floor(e/4294967296));case 4:this.writeU8(e>>24);case 3:this.writeU8(e>>16);case 2:this.writeU8(e>>8);case 1:this.writeU8(e);break;default:throw new Error("Bad UINT size "+r)}},t.prototype.measureUnsignedInt=function(e){return e<256?1:e<65536?2:e<1<<24?3:e<4294967296?4:5},t.prototype.getAsDataArray=function(){if(this.pos<this.data.byteLength)return this.data.subarray(0,this.pos);if(this.pos==this.data.byteLength)return this.data;throw new Error("ArrayBufferDataStream's pos lies beyond end of buffer")},c.exports=t})()})(Vt)),Vt.exports}var Dt,At,Ot,Ut={exports:{}};function ke(){return Dt||(Dt=1,(function(c){(function(){let t=function(e){return function(r){let a=[],i=Promise.resolve(),n=null,u=null;function l(s){return new Promise(function(d,m){let y=new FileReader;y.addEventListener("loadend",function(){d(y.result)}),y.readAsArrayBuffer(s)})}function h(s){return new Promise(function(d,m){s instanceof Uint8Array?d(s):s instanceof ArrayBuffer||ArrayBuffer.isView(s)?d(new Uint8Array(s)):s instanceof Blob?d(l(s).then(function(y){return new Uint8Array(y)})):d(l(new Blob([s])).then(function(y){return new Uint8Array(y)}))})}function o(s){let d=s.byteLength||s.length||s.size;if(!Number.isInteger(d))throw new Error("Failed to determine size of element");return d}r&&r.constructor.name==="FileWriter"?n=r:e&&r&&(u=r),this.pos=0,this.length=0,this.seek=function(s){if(s<0)throw new Error("Offset may not be negative");if(isNaN(s))throw new Error("Offset may not be NaN");if(s>this.length)throw new Error("Seeking beyond the end of file is not allowed");this.pos=s},this.write=function(s){let d={offset:this.pos,data:s,length:o(s)},m=d.offset>=this.length;this.pos+=d.length,this.length=Math.max(this.length,this.pos),i=i.then(function(){if(u)return new Promise(function(y,p){h(d.data).then(function(b){let E=0,x=Buffer.from(b.buffer),g=function(B,S,k){E+=S,E>=k.length?y():e.write(u,k,E,k.length-E,d.offset+E,g)};e.write(u,x,0,x.length,d.offset,g)})});if(n)return new Promise(function(y,p){n.onwriteend=y,n.seek(d.offset),n.write(new Blob([d.data]))});if(!m)for(let y=0;y<a.length;y++){let p=a[y];if(!(d.offset+d.length<=p.offset||d.offset>=p.offset+p.length)){if(d.offset<p.offset||d.offset+d.length>p.offset+p.length)throw new Error("Overwrite crosses blob boundaries");return d.offset==p.offset&&d.length==p.length?void(p.data=d.data):h(p.data).then(function(b){return p.data=b,h(d.data)}).then(function(b){d.data=b,p.data.set(d.data,d.offset-p.offset)})}}a.push(d)})},this.complete=function(s){return i=u||n?i.then(function(){return null}):i.then(function(){let d=[];for(let m=0;m<a.length;m++)d.push(a[m].data);return new Blob(d,{type:s})}),i}}};c.exports=t})()})(Ut)),Ut.exports}function Ie(){return Ot?At:(Ot=1,At=Ee()(Be(),ke()(null)))}const Fe=Ce(Ie());class Me{async $record(t,e,r,a){const i=Math.max(1,Math.round(e.frameRate)),n=Math.max(1,Math.round(e.frameCount)),u=new Fe({quality:e.quality,alphaQuality:e.transparent?e.quality:void 0,transparent:e.transparent,frameRate:i}),l=this._createSnapshotSurface();return await new Promise((h,o)=>{let s,d="capturing",m=!1,y=0;const p=()=>{s&&(s(),s=void 0)},b=()=>{a?.({state:"recording",frameIndex:y,totalFrames:n})},E=g=>{if(m)return;m=!0,p();const B=g instanceof Error?g.message:"WEBM export failed";a?.({state:"error",message:B}),o(g instanceof Error?g:new Error(String(g)))},x=()=>{d!=="capturing"||m||(d="encoding",p(),u.complete().then(g=>{(B=>{m||(m=!0,a?.({state:"completed",frameIndex:Math.min(n,y),totalFrames:n}),h(B))})(g)}).catch(E))};s=r(()=>{(()=>{if(d==="capturing")if(y>=n)x();else try{const g=l(t);u.addFrame(g),y+=1,b(),y>=n&&x()}catch(g){E(g)}})()}),b()})}_createSnapshotSurface(){let t=null,e=null;return r=>{const a=Math.max(1,r.width),i=Math.max(1,r.height),n=((u,l)=>(t||(t=document.createElement("canvas")),t.width!==u||t.height!==l?(t.width=u,t.height=l,e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)):e||(e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)),e?t:null))(a,i);return n&&e?(e.clearRect(0,0,a,i),e.drawImage(r,0,0,a,i),n):r}}}class $e{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new Me,this._textmodifier=t,this._registerPostDrawHook=e}async $saveWEBM(t={}){const e=this._textmodifier.canvas,r=this._applyDefaultOptions(t);try{const a=await this._recorder.$record(e,r,this._registerPostDrawHook,t.onProgress);new X().$downloadFile(a,r.filename)}catch(a){throw t.onProgress?.({state:"error",message:a instanceof Error?a.message:"WEBM export failed"}),a}}_applyDefaultOptions(t){return{filename:t.filename,frameRate:Math.abs(Math.round(t.frameRate??60)),frameCount:Math.abs(Math.round(t.frameCount??300)),quality:Math.abs(Math.min(Math.max(t.quality??1,0),1)),transparent:!!t.transparent,debugLogging:!!t.debugLogging}}}const Se="textmode-export-overlay",z="textmode-export-overlay__stack",dt="textmode-export-overlay__stack--dense",Tt="textmode-export-overlay__stack--compact",Rt="textmode-export-overlay__section",Le="textmode-export-overlay__header",Pe="textmode-export-overlay__header-title-row",Ve="textmode-export-overlay__header-links",De="textmode-export-overlay__row",Nt="textmode-export-overlay__label",zt="textmode-export-overlay__field",Gt="textmode-export-overlay__field--compact",Wt="textmode-export-overlay__field--dense",qt="textmode-export-overlay__field--full",Ht="textmode-export-overlay__field--channel",jt="textmode-export-overlay__input",Ae="textmode-export-overlay__checkbox",Qt="textmode-export-overlay__muted",Oe="textmode-export-overlay__status",Ue="textmode-export-overlay__status--gif",Te="textmode-export-overlay__status--video",Re="textmode-export-overlay__status-title",Ne="textmode-export-overlay__status-value",ze="textmode-export-overlay__divider",Ge="textmode-export-overlay__title",We="textmode-export-overlay__button",ct="textmode-export-overlay__button--primary",ut="textmode-export-overlay__button--secondary",Xt="textmode-export-overlay__button--full",qe="textmode-export-overlay__support-link",He="textmode-export-overlay__support-icon",je="textmode-export-overlay__link-icon";class N{element;mounted=!1;destroyed=!1;mount(t){if(this.destroyed)throw new Error("Cannot mount a destroyed component");if(this.mounted)return;const e=this.render();t.appendChild(e),this.element=e,this.onMount(),this.mounted=!0}unmount(){this.mounted&&this.element&&(this._onUnmount(),this.element.remove(),this.element=void 0,this.mounted=!1)}destroy(){this.destroyed||(this.unmount(),this._onDestroy(),this.destroyed=!0)}update(t){this.mounted&&this.onUpdate(t)}onMount(){}_onUnmount(){}_onDestroy(){}onUpdate(t){}get root(){if(!this.element)throw new Error("Component is not mounted yet");return this.element}isMounted(){return this.mounted}}class Y extends N{static _iconNamespace="http://www.w3.org/2000/svg";render(){const t=document.createElement("div");t.classList.add(z,dt,Le);const e=document.createElement("div");e.classList.add(Pe);const r=document.createElement("strong");r.textContent="textmode.export.js",r.classList.add(Ge);const a=document.createElement("div");a.classList.add(Ve);const i=this._createLink("https://github.com/humanbydefinition/textmode.export.js","View repository on GitHub",je,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5"}]),n=this._createLink("https://code.textmode.art/support.html","Support textmode.export.js",He,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M3 14c.83 .642 2.077 1.017 3.5 1c1.423 .017 2.67 -.358 3.5 -1c.83 -.642 2.077 -1.017 3.5 -1c1.423 -.017 2.67 .358 3.5 1"},{d:"M8 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M12 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M3 10h14v5a6 6 0 0 1 -6 6h-2a6 6 0 0 1 -6 -6v-5z"},{d:"M16.746 16.726a3 3 0 1 0 .252 -5.555"}]);a.appendChild(i),a.appendChild(n),e.appendChild(r),e.appendChild(a);const u=document.createElement("div");return u.classList.add(ze),t.appendChild(e),t.appendChild(u),t}_createLink(t,e,r,a){const i=document.createElement("a");return i.href=t,i.target="_blank",i.rel="noopener noreferrer",i.classList.add(qe),i.setAttribute("aria-label",e),i.appendChild(this._createIcon(r,a)),i}_createIcon(t,e){const r=document.createElementNS(Y._iconNamespace,"svg");r.setAttribute("xmlns",Y._iconNamespace),r.setAttribute("width","18"),r.setAttribute("height","18"),r.setAttribute("viewBox","0 0 24 24"),r.setAttribute("fill","none"),r.setAttribute("stroke","currentColor"),r.setAttribute("stroke-width","2"),r.setAttribute("stroke-linecap","round"),r.setAttribute("stroke-linejoin","round"),r.classList.add(t);for(const a of e){const i=document.createElementNS(Y._iconNamespace,"path");for(const[n,u]of Object.entries(a))i.setAttribute(n,u);r.appendChild(i)}return r}}class R extends N{props;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.classList.add(zt),this.applyVariant(t,this.props.variant);const e=document.createElement("label");if(e.classList.add(Nt),e.textContent=this.props.label,this.props.labelFor&&(e.htmlFor=this.props.labelFor),t.appendChild(e),this.props.description){const r=document.createElement("span");r.classList.add(Qt),r.textContent=this.props.description,t.appendChild(r)}return t}attachControl(t){this.root.appendChild(t)}update(t){this.props=t,super.update(t)}onUpdate(t){const e=this.root;for(;e.firstChild;)e.removeChild(e.firstChild);this.props=t,e.classList.add(zt),this.applyVariant(e,t.variant);const r=document.createElement("label");if(r.classList.add(Nt),r.textContent=t.label,t.labelFor&&(r.htmlFor=t.labelFor),e.appendChild(r),t.description){const a=document.createElement("span");a.classList.add(Qt),a.textContent=t.description,e.appendChild(a)}}applyVariant(t,e){switch(t.classList.remove(Gt,Wt,qt,Ht),e){case"compact":t.classList.add(Gt);break;case"dense":t.classList.add(Wt);break;case"full":t.classList.add(qt);break;case"channel":t.classList.add(Ht)}}}class pt extends N{props;select;handleChange=()=>{this.props.defaultValue=this.select.value};constructor(t){super(),this.props=t}render(){return this.select=document.createElement("select"),this.select.classList.add(jt),this.props.id&&(this.select.id=this.props.id),this.populateOptions(),this.select.addEventListener("change",this.handleChange),this.select}get selectElement(){return this.select}get value(){return this.select.value}set value(t){this.select&&(this.select.value=t),this.props.defaultValue=t}_onUnmount(){this.select.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,this.populateOptions(),t.defaultValue&&(this.select.value=t.defaultValue)}update(t){this.props={...this.props,...t},this.select&&(t.id&&(this.select.id=t.id),t.options&&this.populateOptions(),t.defaultValue!==void 0&&(this.select.value=t.defaultValue))}populateOptions(){if(this.select){this.select.innerHTML="";for(const t of this.props.options){const e=document.createElement("option");e.value=t.value,e.textContent=t.label,this.select.appendChild(e)}this.props.defaultValue&&(this.select.value=this.props.defaultValue)}}}class Yt extends N{props;button;constructor(t){super(),this.props=t}render(){return this.button=document.createElement("button"),this.button.type="button",this.button.textContent=this.props.label,this.button.classList.add(We),this.props.variant==="secondary"?this.button.classList.add(ut):this.button.classList.add(ct),this.props.fullWidth&&this.button.classList.add(Xt),this.button.disabled=!!this.props.disabled,this.button}get buttonElement(){return this.button}setLabel(t){this.props.label=t,this.button.textContent=t}setDisabled(t){this.props.disabled=t,this.button.disabled=t}onUpdate(t){this.props=t,this.button.textContent=t.label,this.button.disabled=!!t.disabled,t.variant==="secondary"?(this.button.classList.add(ut),this.button.classList.remove(ct)):(this.button.classList.add(ct),this.button.classList.remove(ut)),this.button.classList.toggle(Xt,!!t.fullWidth)}}class Qe{api;constructor(t){this.api=t}async $copy(t,e){switch(t){case"txt":{const r=this.api.toString(e);await navigator.clipboard.writeText(r);break}case"svg":{const r=this.api.toSVG(e);await navigator.clipboard.writeText(r);break}case"image":await this.api.copyCanvas(e);break;default:throw new Error(`Clipboard not supported for ${t}`)}}}class Xe{api;events;constructor(t,e){this.api=t,this.events=e}async $requestExport(t,e,r={}){this.events.$emit("export:request",{format:t});try{const a={onGIFProgress:r.onGIFProgress?i=>{r.onGIFProgress?.(i),this.events.$emit("export:progress",{format:t,progress:i})}:t==="gif"?i=>this.events.$emit("export:progress",{format:t,progress:i}):void 0,onVideoProgress:r.onVideoProgress?i=>{r.onVideoProgress?.(i),this.events.$emit("export:progress",{format:t,progress:i})}:t==="video"?i=>this.events.$emit("export:progress",{format:t,progress:i}):void 0};await this._execute(t,e,a),this.events.$emit("export:success",{format:t})}catch(a){throw this.events.$emit("export:error",{format:t,error:a}),a}}_execute(t,e,r){switch(t){case"txt":return Promise.resolve(this.api.saveStrings(e));case"image":return this.api.saveCanvas(e);case"svg":return Promise.resolve(this.api.saveSVG(e));case"gif":{const a={...e,onProgress:r.onGIFProgress};return this.api.saveGIF(a)}case"video":{const a={...e,onProgress:r.onVideoProgress};return this.api.saveWEBM(a)}}}}class Ye{modifier;overlay;animationFrameId=null;handleUpdate;bound=!1;constructor(t,e){this.modifier=t,this.overlay=e,this.handleUpdate=()=>this.scheduleUpdate()}scheduleUpdate(){this.animationFrameId!==null&&cancelAnimationFrame(this.animationFrameId),this.animationFrameId=requestAnimationFrame(()=>this.update())}bind(){this.bound||(window.addEventListener("resize",this.handleUpdate),window.addEventListener("scroll",this.handleUpdate,!0),this.bound=!0,this.handleUpdate())}update(){this.animationFrameId=null;const t=this.modifier.canvas.getBoundingClientRect();this.overlay.style.top=`${t.top+window.scrollY+8}px`,this.overlay.style.left=`${t.left+window.scrollX+8}px`}dispose(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.bound&&(window.removeEventListener("resize",this.handleUpdate),window.removeEventListener("scroll",this.handleUpdate,!0),this.bound=!1)}}const J="textmode-export-number-input",Je=`${J}__field`,Ze=`${J}__controls`,Ke=`${J}__control`,Jt=`${J}__display`,at=`${Jt}--visible`,Zt=c=>{const t=document.createElement("button");return t.type="button",t.className=Ke,t.textContent=c>0?"▲":"▼",t};class q extends N{props;input;display;incrementButton;decrementButton;suppressClickAfterPointer=new WeakMap;holdTimeoutId;holdIntervalId;activePointerId;disabledObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.className=J,this.input=document.createElement("input"),this.input.type="number",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=Je,this.display=document.createElement("div"),this.display.className=Jt;const e=document.createElement("div");return e.className=Ze,this.incrementButton=Zt(1),this.decrementButton=Zt(-1),e.appendChild(this.incrementButton),e.appendChild(this.decrementButton),t.appendChild(this.input),t.appendChild(this.display),t.appendChild(e),this.bindStepControls(),this.bindHoldBehavior(),this.bindInputListeners(),this.observeDisabledState(t),this.updateDisplay(),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateDisplay()}refresh(){this.updateDisplay()}_onDestroy(){this.clearHoldTimers(),this.disabledObserver?.disconnect()}bindStepControls(){const t=i=>()=>{if(this.input.disabled)return;const n=this.input.value,u=this.input.getAttribute("step");if(u&&u!=="any")i>0?this.input.stepUp():this.input.stepDown();else{const h=i>0?1:-1,o=Number.parseFloat(this.input.value||"0"),s=Number.isFinite(o)?o+h:h;this.input.value=String(s)}var l;this.input.value!==n&&((l=this.input).dispatchEvent(new Event("input",{bubbles:!0})),l.dispatchEvent(new Event("change",{bubbles:!0}))),this.updateDisplay(),this.input.focus({preventScroll:!0})},e=t(1),r=t(-1),a=(i,n)=>u=>{if(this.suppressClickAfterPointer.get(i))return this.suppressClickAfterPointer.set(i,!1),void u.preventDefault();n()};this.incrementButton.addEventListener("click",a(this.incrementButton,e)),this.decrementButton.addEventListener("click",a(this.decrementButton,r))}bindHoldBehavior(){const t=(e,r)=>{const a=r>0?()=>this.incrementButton.click():()=>this.decrementButton.click();e.addEventListener("pointerdown",u=>{if(u.button===0){u.preventDefault(),this.suppressClickAfterPointer.set(e,!0),this.activePointerId=u.pointerId;try{e.setPointerCapture(u.pointerId)}catch{}a(),this.holdTimeoutId=window.setTimeout(()=>{this.holdIntervalId=window.setInterval(a,80)},380)}});const i=()=>{if(this.activePointerId!==void 0){try{e.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}},n=()=>{this.clearHoldTimers(),i()};e.addEventListener("pointerup",n),e.addEventListener("pointerleave",n),e.addEventListener("pointercancel",n)};t(this.incrementButton,1),t(this.decrementButton,-1)}bindInputListeners(){const t=()=>{this.props.defaultValue=this.input.value,this.updateDisplay()};this.input.addEventListener("input",t),this.input.addEventListener("change",t)}observeDisabledState(t){const e=()=>{const r=this.input.disabled;this.incrementButton.disabled=r,this.decrementButton.disabled=r,t.classList.toggle("is-disabled",r),r?(this.display.classList.remove(at),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor")):this.updateDisplay()};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}updateDisplay(){const t=this.props.formatDisplay;if(!t)return this.display.textContent="",this.display.classList.remove(at),this.input.style.removeProperty("color"),void this.input.style.removeProperty("caretColor");const e=this.input.value,r=Number.parseFloat(e),a=t(Number.isFinite(r)?r:Number.NaN,e,this.input);a?(this.display.textContent=a,this.display.classList.add(at),this.input.style.color="transparent",this.input.style.caretColor="#f8fafc"):(this.display.textContent="",this.display.classList.remove(at),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor"))}clearHoldTimers(){this.holdTimeoutId!==void 0&&(window.clearTimeout(this.holdTimeoutId),this.holdTimeoutId=void 0),this.holdIntervalId!==void 0&&(window.clearInterval(this.holdIntervalId),this.holdIntervalId=void 0)}}class Z extends N{variant;additionalClasses;constructor(t="stack",e=[]){super(),this.variant=t,this.additionalClasses=e}render(){const t=document.createElement("div"),e=[this.variant==="stack"?z:void 0,this.variant==="stackDense"?dt:void 0,this.variant==="stackCompact"?Tt:void 0,this.variant==="row"?De:void 0,this.variant==="section"?Rt:void 0,...this.additionalClasses].filter(Boolean);return t.classList.add(...e),t}}const Kt={neutral:"textmode-export-overlay__status-value--neutral",active:"textmode-export-overlay__status-value--active",alert:"textmode-export-overlay__status-value--alert"};class te extends N{props;container;messageElement;constructor(t){super(),this.props=t}render(){this.container=document.createElement("div"),this.container.classList.add(Oe),this.props.context==="gif"?this.container.classList.add(Ue):this.props.context==="video"&&this.container.classList.add(Te);const t=document.createElement("span");return t.classList.add(Re),t.textContent=this.props.title,this.messageElement=document.createElement("span"),this.messageElement.classList.add(Ne),this.messageElement.textContent=this.props.message,this.applyVariant(this.props.variant??"neutral"),this.container.appendChild(t),this.container.appendChild(this.messageElement),this.container}setMessage(t,e="neutral"){this.messageElement.textContent=t,this.applyVariant(e)}onUpdate(t){this.props=t,this.setMessage(t.message,t.variant??"neutral")}applyVariant(t){this.messageElement.classList.remove(...Object.values(Kt)),this.messageElement.classList.add(Kt[t])}}class K extends N{_config;_managedComponents=new Set;constructor(t){super(),this._config=t}_manageComponent(t){return this._managedComponents.add(t),t}_onUnmount(){for(const t of this._managedComponents)t.unmount()}_onDestroy(){for(const t of this._managedComponents)t.destroy();this._managedComponents.clear()}}const ee=300,re=60,ae=1,tr=0;class ht extends K{frameCountInput=this._manageComponent(new q({defaultValue:String(ee),attributes:{min:"1",max:"600",step:"1"}}));frameRateInput=this._manageComponent(new q({defaultValue:String(re),attributes:{min:"1",max:"60",step:"1"}}));scaleInput=this._manageComponent(new q({defaultValue:String(ae),attributes:{min:"0.1",max:"8",step:"0.1"}}));repeatInput=this._manageComponent(new q({defaultValue:"0",attributes:{min:"0",max:"50",step:"1"},formatDisplay:(t,e)=>Number.isFinite(t)?t===0?"∞":null:e.trim()===""?null:e}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"gif"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"number of frames",labelFor:"textmode-export-gif-frame-count",variant:"dense"});r.mount(e.root),this.frameCountInput.mount(r.root),this.frameCountInput.inputElement.id="textmode-export-gif-frame-count";const a=new R({label:"frame rate (fps)",labelFor:"textmode-export-gif-frame-rate",variant:"dense"});a.mount(e.root),this.frameRateInput.mount(a.root),this.frameRateInput.inputElement.id="textmode-export-gif-frame-rate";const i=new Z("row");i.mount(t);const n=new R({label:"scale",labelFor:"textmode-export-gif-scale",variant:"dense"});n.mount(i.root),this.scaleInput.mount(n.root),this.scaleInput.inputElement.id="textmode-export-gif-scale";const u=new R({label:"loop count",labelFor:"textmode-export-gif-repeat",variant:"dense"});return u.mount(i.root),this.repeatInput.mount(u.root),this.repeatInput.inputElement.id="textmode-export-gif-repeat",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{};return{frameCount:this.safeParseInt(this.frameCountInput.value,t.frameCount??300),frameRate:this.safeParseInt(this.frameRateInput.value,t.frameRate??60),scale:this.safeParseFloat(this.scaleInput.value,t.scale??1),repeat:this.safeParseInt(this.repeatInput.value,t.repeat??0)}}reset(){this.recordingState="idle",this.applyDefaults(),this.setRecordingState("idle")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseInt(this.frameRateInput.value,10),r=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&Number.isFinite(r)&&r>0}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const r=t==="recording";switch(this.frameCountInput.inputElement.disabled=r,this.frameRateInput.inputElement.disabled=r,this.scaleInput.inputElement.disabled=r,this.repeatInput.inputElement.disabled=r,t){case"recording":if(e?.totalFrames){const a=e.frameIndex??0;this.status.setMessage(`recording ${a}/${e.totalFrames}`,"active")}else this.status.setMessage("recording…","active");break;case"completed":this.status.setMessage("GIF saved successfully","active");break;case"error":this.status.setMessage(e?.message??"failed to export GIF","alert");break;default:this.status.setMessage("ready to record","neutral")}}handleProgress(t){t.state==="recording"&&t.totalFrames?this.status.setMessage(`recording ${t.frameIndex??0}/${t.totalFrames}`,"active"):t.state==="completed"?this.status.setMessage("GIF saved successfully","active"):t.state==="error"&&this.status.setMessage(t.message??"failed to export GIF","alert")}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??ee,r=t.frameRate??re,a=t.scale??ae,i=t.repeat??tr;this.frameCountInput.value=String(e),this.frameRateInput.value=String(r),this.scaleInput.value=String(a),this.repeatInput.value=String(i),this.frameCountInput.refresh(),this.frameRateInput.refresh(),this.scaleInput.refresh(),this.repeatInput.refresh()}safeParseInt(t,e){const r=Number.parseInt(t,10);return Number.isFinite(r)?r:e}safeParseFloat(t,e){const r=Number.parseFloat(t);return Number.isFinite(r)?r:e}}const it="textmode-export-range-input",er=`${it}__field`,rr=`${it}__tooltip`,mt=`${it}__tooltip--visible`,ot=(c,t)=>{if(typeof c!="string"||c.length===0)return t;const e=Number.parseFloat(c);return Number.isFinite(e)?e:t};class ar extends N{props;input;tooltip;hoverActive=!1;focusActive=!1;pointerActive=!1;suppressFocusFromPointer=!1;activePointerId;disabledObserver;resizeObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");return t.className=it,this.input=document.createElement("input"),this.input.type="range",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=er,this.tooltip=document.createElement("div"),this.tooltip.className=rr,t.appendChild(this.input),t.appendChild(this.tooltip),this.bindEvents(t),this.updateTooltip(),this.syncDisabledState(t),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateTooltip()}_onDestroy(){this.disabledObserver?.disconnect(),this.resizeObserver?.disconnect()}bindEvents(t){this.input.addEventListener("pointerenter",()=>{this.hoverActive=!0,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerleave",()=>{this.hoverActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("focus",()=>{let r=!1;try{r=this.input.matches(":focus-visible")}catch{r=!this.suppressFocusFromPointer}this.suppressFocusFromPointer||!r||this.input.disabled?this.focusActive=!1:this.focusActive=!0,this.suppressFocusFromPointer=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("blur",()=>{this.focusActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerdown",r=>{this.pointerActive=!0,this.suppressFocusFromPointer=!0,this.hoverActive=!0,this.refreshTooltipVisibility();try{this.input.setPointerCapture(r.pointerId),this.activePointerId=r.pointerId}catch{this.activePointerId=void 0}});const e=()=>{this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.hoverActive=this.input.matches(":hover"),this.releasePointerCapture(),this.refreshTooltipVisibility()};this.input.addEventListener("pointerup",e),this.input.addEventListener("pointercancel",e),this.input.addEventListener("lostpointercapture",e),this.input.addEventListener("input",()=>{(this.hoverActive||this.focusActive||this.pointerActive)&&this.updateTooltip(),this.props.defaultValue=this.input.value}),this.input.addEventListener("change",()=>{this.pointerActive||this.updateTooltip(),this.props.defaultValue=this.input.value}),typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>{this.tooltip.classList.contains(mt)&&this.updateTooltipPosition()}),this.resizeObserver.observe(t))}refreshTooltipVisibility(){const t=(this.hoverActive||this.focusActive||this.pointerActive)&&!this.input.disabled;t&&this.updateTooltip(),this.tooltip.classList.toggle(mt,t)}syncDisabledState(t){const e=()=>{const r=this.input.disabled;t.classList.toggle("is-disabled",r),r&&(this.hoverActive=!1,this.focusActive=!1,this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.releasePointerCapture(),this.tooltip.classList.remove(mt))};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}releasePointerCapture(){if(this.activePointerId!==void 0){try{this.input.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}}updateTooltip(){this.updateTooltipContent(),this.updateTooltipPosition()}updateTooltipContent(){const t=this.props.formatValue??(r=>`${r}`),e=this.getCurrentValue();this.tooltip.textContent=t(e,this.input)}updateTooltipPosition(){const t=this.getMin(),e=this.getMax(),r=((n,u,l)=>Math.min(l,Math.max(u,n)))(this.getCurrentValue(),t,e),a=e-t,i=a===0?0:(r-t)/a;this.tooltip.style.left=100*i+"%"}getMin(){return ot(this.input.min,0)}getMax(){return ot(this.input.max,100)}getCurrentValue(){return ot(this.input.value,ot(this.props.defaultValue,0))}}function ir(c){return`${(function(e){if(!Number.isFinite(e))return"default quality";const r=Math.max(0,Math.min(1,e));return r>=.995?"near-lossless":r>=.98?"maximum detail":r>=.88?"ultra quality":r>=.7?"high quality":r>=.5?"balanced":r>=.25?"compact":r>=.1?"lightweight":"draft"})(c)} (quality ≈ ${c.toFixed(3)})`}class ft extends K{frameRateInput=this._manageComponent(new q({defaultValue:String(60),attributes:{min:String(1),max:String(60),step:"1"},formatDisplay:t=>Number.isFinite(t)?`${t} fps`:null}));frameCountInput=this._manageComponent(new q({defaultValue:String(480),attributes:{min:String(1),max:String(3600),step:"1"}}));qualityInput=this._manageComponent(new ar({defaultValue:String(.7),attributes:{min:String(0),max:String(1),step:"0.001"},formatValue:t=>ir(t)}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"video"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"number of frames",labelFor:"textmode-export-video-frame-count",variant:"compact"});r.mount(e.root),this.frameCountInput.mount(r.root),this.frameCountInput.inputElement.id="textmode-export-video-frame-count";const a=new R({label:"frame rate (fps)",labelFor:"textmode-export-video-frame-rate",variant:"compact"});a.mount(e.root),this.frameRateInput.mount(a.root),this.frameRateInput.inputElement.id="textmode-export-video-frame-rate";const i=new R({label:"quality",labelFor:"textmode-export-video-quality",variant:"full"});return i.mount(t),this.qualityInput.mount(i.root),this.qualityInput.inputElement.id="textmode-export-video-quality",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{},e=Number.parseInt(this.frameCountInput.value,10),r=Number.parseFloat(this.frameRateInput.value),a=Number.parseFloat(this.qualityInput.value);return{frameCount:Number.isFinite(e)?e:t.frameCount??480,frameRate:Number.isFinite(r)?r:t.frameRate??60,quality:Number.isFinite(a)?a:t.quality??.7}}reset(){this.recordingState="idle",this.applyDefaults(),this.status.setMessage("ready to record","neutral")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseFloat(this.frameRateInput.value);return Number.isFinite(t)&&t>=1&&Number.isFinite(e)&&e>=1}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const r=t==="recording";this.frameCountInput.inputElement.disabled=r,this.frameRateInput.inputElement.disabled=r,this.qualityInput.inputElement.disabled=r,this.syncStatus(t,e)}handleProgress(t){this.syncStatus(t.state,t)}syncStatus(t,e){switch(t){case"recording":{const r=e?.frameIndex??0,a=e?.totalFrames??this.resolvePlannedFrameCount();if(a){const i=Math.min(Math.max(0,Math.round(r)),a);this.status.setMessage(`recording ${i}/${a} frames`,"active")}else this.status.setMessage(`recording ${Math.max(0,Math.round(r))} frames`,"active");break}case"completed":this.status.setMessage("saved to disk","active");break;case"error":this.status.setMessage(e?.message?`error: ${e.message}`:"recording failed","alert");break;default:this.status.setMessage("ready to record","neutral")}}resolvePlannedFrameCount(){const t=Number.parseInt(this.frameCountInput.value,10);return Number.isFinite(t)&&t>0?Math.round(t):void 0}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??480,r=t.frameRate??60,a=t.quality??.7;this.frameCountInput.value=String(e),this.frameRateInput.value=String(r),this.qualityInput.value=String(a),this.frameCountInput.refresh(),this.frameRateInput.refresh()}}class or{_textmodifier;_state;_events;_exportService;_clipboardService;_definitions;_formats=new Map;_eventUnsubscribers=[];_shadowHost;_shadowRoot;_overlayElement;_optionsContainer;_copyButtonContainer;_positionService;_header=new Y;_formatField=new R({label:"export format",labelFor:"textmode-export-format",variant:"full"});_formatSelect=new pt({id:"textmode-export-format",options:[]});_exportButton=new Yt({label:"download file",fullWidth:!0,variant:"primary"});_copyButton=new Yt({label:"copy to clipboard",fullWidth:!0,variant:"primary"});_currentFormat;_currentBlade;_handleFormatSelectChange=()=>{this._handleFormatChange(this._formatSelect.value)};_handleExportClickSafe=()=>{this._handleExportClick().catch(t=>{console.error("[textmode-export] Export failed",t)})};_handleCopyClickSafe=()=>{this._handleCopyClick().catch(t=>{console.error("[textmode-export] Copy failed",t)})};constructor(t,e,r,a,i){this._textmodifier=t,this._state=r,this._events=a,this._exportService=new Xe(e,a),this._clipboardService=new Qe(e),this._definitions=i,this._currentFormat=r.snapshot.format,this._initializeFormatMap(),this._registerEventHandlers()}$mount(){this._createOverlay(),this._renderStaticContent(),this._positionService=new Ye(this._textmodifier,this._shadowHost),this._positionService.bind(),this._switchFormat(this._currentFormat)}$dispose(){this._formatSelect.isMounted()&&this._formatSelect.selectElement.removeEventListener("change",this._handleFormatSelectChange),this._exportButton.isMounted()&&this._exportButton.buttonElement.removeEventListener("click",this._handleExportClickSafe),this._copyButton.isMounted()&&this._copyButton.buttonElement.removeEventListener("click",this._handleCopyClickSafe);for(const t of this._eventUnsubscribers)t();this._eventUnsubscribers.length=0,this._events.$clear();for(const t of this._formats.values())t.blade.destroy();this._formats.clear(),this._currentBlade=void 0,this._shadowHost?.isConnected&&this._shadowHost.remove(),this._positionService?.dispose()}_initializeFormatMap(){for(const t of this._definitions){const e=t.createBlade();this._formats.set(t.format,{definition:t,blade:e,initialized:!1})}}_createOverlay(){this._shadowHost=document.createElement("div"),this._shadowHost.dataset.plugin="textmode-export-overlay-host",this._shadowHost.style.cssText="position: absolute; top: 0; left: 0; pointer-events: none; z-index: 2147483647;",this._shadowRoot=this._shadowHost.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent="@layer textmode-export-overlay{.textmode-export-overlay{--overlay-bg: rgba(20, 20, 20, .8);--overlay-surface: rgba(40, 40, 40, .9);--overlay-border: rgba(255, 255, 255, .14);--overlay-border-strong: rgba(255, 255, 255, .2);--overlay-border-focus: rgba(160, 160, 160, .6);--overlay-focus-shadow: 0 0 0 1px rgba(140, 140, 140, .28);--overlay-text: #ffffff;--overlay-muted: rgba(200, 200, 200, .74);--overlay-radius: .75rem;--overlay-stack-gap: .55rem;position:absolute;top:0;left:0;display:flex;flex-direction:column;gap:var(--overlay-stack-gap);min-width:236px;max-width:236px;padding:.65rem .8rem;background:var(--overlay-bg);color:var(--overlay-text);border-radius:var(--overlay-radius);border:1px solid var(--overlay-border);box-shadow:0 12px 28px #0000004d;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:.82rem;line-height:1.35;pointer-events:auto;z-index:2147483647}.textmode-export-overlay *{box-sizing:border-box}.textmode-export-overlay__header{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__header-title-row{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.textmode-export-overlay__header-links{display:inline-flex;align-items:center;gap:.3rem}.textmode-export-overlay__support-link{display:inline-flex;align-items:center;justify-content:center;padding:.2rem;border-radius:.45rem;border:1px solid transparent;color:#d7d7d7d1;background:transparent;text-decoration:none;line-height:0;transition:background .18s ease,color .18s ease,transform .18s ease,border-color .18s ease}.textmode-export-overlay__support-link:hover{color:#fff;background:#5a5a5a4d;border-color:#c8c8c824}.textmode-export-overlay__support-link:focus-visible{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-overlay__support-icon,.textmode-export-overlay__link-icon{display:block;width:1rem;height:1rem}.textmode-export-overlay__stack{display:flex;flex-direction:column;gap:var(--overlay-stack-gap)}.textmode-export-overlay__stack--dense{gap:.3rem}.textmode-export-overlay__stack--compact{gap:.45rem}.textmode-export-overlay__section{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__title{font-size:.92rem;font-weight:600}.textmode-export-overlay__divider{width:100%;height:1px;background:#ffffff29;margin-top:.25rem}.textmode-export-overlay__label{font-weight:500;opacity:.9}.textmode-export-overlay__checkbox{display:flex;align-items:center;gap:.5rem}.textmode-export-overlay__checkbox input[type=checkbox]{width:1rem;height:1rem;accent-color:rgba(100,100,100,.9)}.textmode-export-overlay__row{display:flex;gap:.6rem;flex-wrap:wrap;align-items:flex-start;width:100%}.textmode-export-overlay__field{display:flex;flex-direction:column;gap:.3rem;flex:1 1 120px;min-width:120px}.textmode-export-overlay__field--compact{flex:1 1 100px;min-width:100px}.textmode-export-overlay__field--dense{flex:1 1 90px;min-width:90px}.textmode-export-overlay__field--channel{flex:1 1 0;min-width:0}.textmode-export-overlay__field--full{width:100%;flex:1 1 100%}.textmode-export-overlay__input,.textmode-export-overlay select.textmode-export-overlay__input,.textmode-export-overlay input.textmode-export-overlay__input{width:100%;padding:.35rem .5rem;border-radius:.4rem;border:1px solid var(--overlay-border-strong);background:var(--overlay-surface);color:var(--overlay-text);transition:border-color .18s ease,box-shadow .18s ease,background .18s ease}.textmode-export-overlay__input:focus{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow);background:#2d2f42eb}.textmode-export-overlay__input::placeholder{color:var(--overlay-muted);opacity:.7}.textmode-export-overlay__muted{font-size:.75rem;opacity:.7;display:block}.textmode-export-overlay__button{display:inline-flex;align-items:center;justify-content:center;gap:.35rem;border-radius:.45rem;border:none;font-weight:600;padding:.45rem .7rem;cursor:pointer;transition:background .2s ease,transform .2s ease,box-shadow .2s ease}.textmode-export-overlay__button--primary{background:#505050;color:#fff}.textmode-export-overlay__button--secondary{background:#606060;color:#fff}.textmode-export-overlay__button--full{width:100%}.textmode-export-overlay__button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 7px 18px #00000073}.textmode-export-overlay__button--primary:hover:not(:disabled){background:#404040}.textmode-export-overlay__button--secondary:hover:not(:disabled){background:#4a4a4a}.textmode-export-overlay__button:disabled{cursor:default;opacity:.55;transform:none;box-shadow:none}.textmode-export-overlay__status{display:flex;flex-direction:column;gap:.25rem;padding:.45rem .55rem;border-radius:.45rem;border:1px solid rgba(110,110,110,.22);background:#4646462e}.textmode-export-overlay__status--gif{background:#5050501f;border-color:#78787840}.textmode-export-overlay__status--video{background:#4646461f;border-color:#6e6e6e40}.textmode-export-overlay__status-title{font-weight:600;font-size:.75rem;opacity:.85;text-transform:uppercase;letter-spacing:.04em}.textmode-export-overlay__status-value{font-size:.82rem;color:#dedede;transition:color .18s ease}.textmode-export-overlay__status-value--neutral{color:#cfcfcf}.textmode-export-overlay__status-value--active{color:#f5f5f5}.textmode-export-overlay__status-value--alert{color:#b8b8b8}.textmode-export-number-input,.textmode-export-overlay .textmode-export-number-input{display:flex;align-items:stretch;width:100%;background:var(--overlay-surface);border:1px solid var(--overlay-border-strong);border-radius:.4rem;overflow:hidden;transition:border-color .18s ease,box-shadow .18s ease,background .18s ease;position:relative}.textmode-export-number-input:focus-within{border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-number-input.is-disabled{opacity:.55}.textmode-export-number-input__field{flex:1 1 auto;min-width:0;border:none;background:transparent;color:var(--overlay-text);font:inherit;padding:.35rem .5rem;appearance:textfield}.textmode-export-number-input__field::-webkit-outer-spin-button,.textmode-export-number-input__field::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.textmode-export-number-input__field:focus{outline:none}.textmode-export-number-input__controls{display:flex;flex-direction:column;border-left:1px solid rgba(255,255,255,.12);min-width:1.6rem}.textmode-export-number-input__control{display:flex;align-items:center;justify-content:center;width:100%;flex:1;border:none;background:#32323299;color:#d0d0d0;font-size:.68rem;line-height:1;cursor:pointer;transition:background .15s ease,color .15s ease;padding:0}.textmode-export-number-input__control:hover:not(:disabled){background:#5a5a5ad9;color:#fff}.textmode-export-number-input__control:disabled{cursor:default;opacity:.4;background:#28282880;color:#c8c8c866}.textmode-export-number-input:focus-within .textmode-export-number-input__control{background:#3c3c3cbf;color:#e8e8e8}.textmode-export-number-input__display{position:absolute;inset:0;display:flex;align-items:center;padding:.4rem .55rem;pointer-events:none;color:#f8fafc;opacity:0;transition:opacity .14s ease}.textmode-export-number-input__display--visible{opacity:1}.textmode-export-range-input{position:relative;width:100%}.textmode-export-range-input.is-disabled{opacity:.55}.textmode-export-range-input__field{width:100%;height:1.4rem;padding:0;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none}.textmode-export-range-input__field::-webkit-slider-thumb{width:12px;height:12px;margin-top:-3.5px;-webkit-appearance:none;border-radius:50%;background:#a0a0a0;border:2px solid #303030;box-shadow:0 0 0 2px #00000059}.textmode-export-range-input__field::-webkit-slider-runnable-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__field::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:#a0a0a0;border:2px solid #303030;margin-top:-3.5px}.textmode-export-range-input__field::-moz-range-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__tooltip{position:absolute;top:-1.5rem;left:0;transform:translate(-50%);padding:.2rem .35rem;border-radius:.35rem;background:#1e1e1ee0;color:#f8fafc;font-size:.68rem;line-height:1;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.textmode-export-range-input__tooltip--visible{opacity:1}}",this._shadowRoot.appendChild(t),this._overlayElement=document.createElement("div"),this._overlayElement.dataset.plugin="textmode-export-overlay",this._overlayElement.classList.add(Se,z),this._shadowRoot.appendChild(this._overlayElement),document.body.appendChild(this._shadowHost)}_renderStaticContent(){this._header.mount(this._overlayElement);const t=document.createElement("div");t.classList.add(Rt),this._overlayElement.appendChild(t),this._formatField.mount(t),this._prepareFormatOptions(),this._formatSelect.mount(this._formatField.root),this._formatSelect.selectElement.addEventListener("change",this._handleFormatSelectChange),this._optionsContainer=document.createElement("div"),this._optionsContainer.classList.add(z,Tt),this._overlayElement.appendChild(this._optionsContainer),this._exportButton.mount(this._overlayElement),this._exportButton.buttonElement.addEventListener("click",this._handleExportClickSafe),this._copyButtonContainer=document.createElement("div"),this._copyButtonContainer.classList.add(z,dt),this._overlayElement.appendChild(this._copyButtonContainer),this._copyButton.mount(this._copyButtonContainer),this._copyButton.buttonElement.dataset.defaultLabel="copy to clipboard",this._copyButton.buttonElement.addEventListener("click",this._handleCopyClickSafe)}_prepareFormatOptions(){const t=this._definitions.map(e=>({value:e.format,label:e.label}));this._formatSelect.update({options:t,defaultValue:this._currentFormat})}_registerEventHandlers(){this._eventUnsubscribers.push(this._events.$on("export:request",({format:t})=>{t===this._currentFormat&&(this._state.$set({isBusy:!0,error:void 0}),this._updateExportButton())}),this._events.$on("export:success",({format:t})=>{if(t===this._currentFormat){const e={isBusy:!1};t==="gif"&&(e.gifProgress=void 0),t==="video"&&(e.videoProgress=void 0),this._state.$set(e),this._updateExportButton()}}),this._events.$on("export:error",({format:t,error:e})=>{t===this._currentFormat&&(this._state.$set({isBusy:!1,error:e}),this._updateExportButton())}),this._events.$on("export:progress",({format:t,progress:e})=>{if(e){if(t==="gif"&&this._currentBlade?.blade instanceof ht){const r=e;this._state.$set({gifProgress:r}),this._currentBlade.blade.handleProgress(r)}else if(t==="video"&&this._currentBlade?.blade instanceof ft){const r=e;this._state.$set({videoProgress:r}),this._currentBlade.blade.handleProgress(r)}this._updateExportButton()}}))}_handleFormatChange(t){this._currentFormat=t,this._state.$set({format:t}),this._switchFormat(t),this._events.$emit("format:change",{format:t})}_switchFormat(t){const e=this._formats.get(t);if(!e)throw new Error(`Unknown export format: ${t}`);this._currentBlade&&this._currentBlade.blade.unmount(),this._optionsContainer.innerHTML="",e.blade.mount(this._optionsContainer),e.initialized||(e.blade.reset(),e.initialized=!0),this._currentBlade=e,this._formatSelect.value=t,this._updateCopyButtonState(),this._updateExportButton(),this._positionService?.scheduleUpdate()}_updateCopyButtonState(){const t=this._currentBlade?.definition.supportsClipboard??!1;this._copyButtonContainer.style.display=t?"flex":"none",this._copyButton.setDisabled(!t)}async _handleExportClick(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions();if(this._currentBlade.blade.validate()){if(t==="gif"){const r=this._currentBlade.blade;if(r.isRecording())return;r.setRecordingState("recording");try{await this._exportService.$requestExport("gif",e,{onGIFProgress:a=>{r.setRecordingState(a.state,a)}})}catch(a){throw r.setRecordingState("error"),a}return void window.setTimeout(()=>{r.setRecordingState("idle"),this._updateExportButton()},1600)}if(t==="video"){const r=this._currentBlade.blade;if(r.isRecording())return;r.setRecordingState("recording");try{await this._exportService.$requestExport("video",e,{onVideoProgress:a=>{r.setRecordingState(a.state,a)}})}catch(a){throw r.setRecordingState("error"),a}return void window.setTimeout(()=>{r.setRecordingState("idle"),this._updateExportButton()},1600)}this._exportButton.setDisabled(!0),this._exportButton.setLabel("exporting…");try{await this._exportService.$requestExport(t,e)}finally{this._exportButton.setDisabled(!1),this._exportButton.setLabel("download file")}}else console.warn("[textmode-export] Export options failed validation")}async _handleCopyClick(){if(!this._currentBlade||!this._currentBlade.definition.supportsClipboard)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions(),r=this._copyButton.buttonElement.dataset.defaultLabel??"copy to clipboard";this._copyButton.setDisabled(!0),this._copyButton.setLabel("copying…");try{await this._clipboardService.$copy(t,e),this._copyButton.setLabel("copied!")}catch(a){console.error("[textmode-export] Failed to copy to clipboard",a),this._copyButton.setLabel("copy failed!")}finally{window.setTimeout(()=>{this._copyButton.setLabel(r),this._copyButton.setDisabled(!1)},1200)}}_updateExportButton(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format;if(t==="gif"&&this._currentBlade.blade instanceof ht){const r=this._currentBlade.blade,a=this._state.snapshot.gifProgress;if(r.isRecording())if(this._exportButton.setDisabled(!0),a?.totalFrames){const i=a.frameIndex??0;this._exportButton.setLabel(`recording ${i}/${a.totalFrames}`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}if(t==="video"&&this._currentBlade.blade instanceof ft){const r=this._currentBlade.blade,a=this._state.snapshot.videoProgress;if(r.isRecording())if(this._exportButton.setDisabled(!0),a?.totalFrames){const i=a.frameIndex??0;this._exportButton.setLabel(`recording ${i}/${a.totalFrames} frames`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}const e=this._state.snapshot.isBusy;this._exportButton.setDisabled(e),this._exportButton.setLabel(e?"exporting…":"download file")}}class nr{_listeners=new Map;$on(t,e){this._listeners.has(t)||this._listeners.set(t,new Set);const r=this._listeners.get(t);return r.add(e),()=>{r.delete(e),r.size===0&&this._listeners.delete(t)}}$emit(t,e){const r=this._listeners.get(t);if(r)for(const a of[...r])try{a(e)}catch(i){console.error("[textmode-export] Event handler failed",i)}}$clear(){this._listeners.clear()}}class sr{_state;_listeners=new Set;constructor(t){this._state=t}get snapshot(){return Object.freeze({...this._state})}$set(t){this._state=Object.assign({},this._state,t);const e=this.snapshot;for(const r of[...this._listeners])try{r(e)}catch(a){console.error("[textmode-export] State listener failed",a)}}$subscribe(t){return this._listeners.add(t),t(this.snapshot),()=>{this._listeners.delete(t)}}$reset(t){this._state=t;const e=this.snapshot;for(const r of[...this._listeners])r(e)}}class ie extends N{props;checkbox;labelElement;handleChange=()=>{this.props.defaultChecked=this.checkbox.checked};constructor(t){super(),this.props=t}render(){this.labelElement=document.createElement("label"),this.labelElement.classList.add(Ae),this.checkbox=document.createElement("input"),this.checkbox.type="checkbox",this.props.id&&(this.checkbox.id=this.props.id),this.checkbox.checked=!!this.props.defaultChecked,this.checkbox.addEventListener("change",this.handleChange);const t=document.createElement("span");return t.textContent=this.props.label,this.labelElement.htmlFor=this.props.id??"",this.labelElement.appendChild(this.checkbox),this.labelElement.appendChild(t),this.labelElement}get inputElement(){return this.checkbox}get checked(){return this.checkbox.checked}set checked(t){this.checkbox.checked=t}_onUnmount(){this.checkbox.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,t.id&&(this.checkbox.id=t.id,this.labelElement.htmlFor=t.id),this.checkbox.checked=!!t.defaultChecked,this.labelElement.lastElementChild&&(this.labelElement.lastElementChild.textContent=t.label)}}class lr extends N{props;input;handleInput=()=>{this.props.defaultValue=this.input.value};constructor(t){super(),this.props=t}render(){return this.input=document.createElement("input"),this.input.type="text",this.input.classList.add(jt),this.props.id&&(this.input.id=this.props.id),this.props.maxLength!==void 0&&(this.input.maxLength=this.props.maxLength),this.props.defaultValue!==void 0&&(this.input.value=this.props.defaultValue),this.input.addEventListener("input",this.handleInput),this.input}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t}_onUnmount(){this.input.removeEventListener("input",this.handleInput)}onUpdate(t){this.props=t,t.id&&(this.input.id=t.id),t.maxLength!==void 0&&(this.input.maxLength=t.maxLength),t.defaultValue!==void 0&&(this.input.value=t.defaultValue)}}class dr extends K{trailingSpaces=this._manageComponent(new ie({label:"preserve trailing spaces",defaultChecked:!1}));emptyCharacter=this._manageComponent(new lr({id:"textmode-export-empty-character",defaultValue:" ",maxLength:1}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z),this.trailingSpaces.mount(t);const e=new R({label:"empty character",labelFor:"textmode-export-empty-character",variant:"full"});return e.mount(t),this.emptyCharacter.mount(e.root),t}getOptions(){const t=this._config.defaultOptions??{},e=this.emptyCharacter.value||t.emptyCharacter||" ";return{preserveTrailingSpaces:this.trailingSpaces.checked,emptyCharacter:e}}reset(){this.applyDefaults()}validate(){return this.emptyCharacter.value.length<=1}applyDefaults(){const t=this._config.defaultOptions??{};this.trailingSpaces.checked=t.preserveTrailingSpaces??!1,this.emptyCharacter.value=t.emptyCharacter??" "}}class cr extends K{formatSelect=this._manageComponent(new pt({id:"textmode-export-image-format",options:[{value:"png",label:`PNG (${de})`},{value:"jpg",label:`JPG (${ce})`},{value:"webp",label:`WEBP (${ue})`}],defaultValue:"png"}));scaleInput=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0.1",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"image format",labelFor:"textmode-export-image-format",variant:"compact"});r.mount(e.root),this.formatSelect.mount(r.root);const a=new R({label:"scale",labelFor:"textmode-export-image-scale",variant:"dense"});return a.mount(e.root),this.scaleInput.mount(a.root),this.scaleInput.inputElement.id="textmode-export-image-scale",t}getOptions(){const t=Number.parseFloat(this.scaleInput.value);return{format:this.formatSelect.value,scale:Number.isFinite(t)?t:this._config.defaultOptions?.scale??1}}reset(){this.applyDefaults(),this.scaleInput.refresh()}validate(){const t=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0}applyDefaults(){const t=this._config.defaultOptions??{};this.formatSelect.value=t.format??"png";const e=t.scale??1;this.scaleInput.value=String(e)}}class ur extends K{includeBackground=this._manageComponent(new ie({id:"textmode-export-svg-include-backgrounds",label:"include cell backgrounds",defaultChecked:!0}));drawMode=this._manageComponent(new pt({id:"textmode-export-svg-draw-mode",options:[{value:"fill",label:"fill"},{value:"stroke",label:"stroke"}],defaultValue:"fill"}));strokeWidth=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z),this.includeBackground.mount(t);const e=new Z("row");e.mount(t);const r=new R({label:"draw mode",labelFor:"textmode-export-svg-draw-mode",variant:"compact"});r.mount(e.root),this.drawMode.mount(r.root);const a=new R({label:"stroke width",labelFor:"textmode-export-svg-stroke-width",variant:"compact"});return a.mount(e.root),this.strokeWidth.mount(a.root),this.strokeWidth.inputElement.id="textmode-export-svg-stroke-width",this.drawMode.selectElement.addEventListener("change",()=>this.updateStrokeControls()),this.updateStrokeControls(),t}getOptions(){return{includeBackgroundRectangles:this.includeBackground.checked,drawMode:this.drawMode.value,strokeWidth:Number.parseFloat(this.strokeWidth.value)}}reset(){this.applyDefaults(),this.updateStrokeControls()}validate(){const t=Number.parseFloat(this.strokeWidth.value);return this.drawMode.value!=="stroke"||Number.isFinite(t)&&t>=0}updateStrokeControls(){const t=this.drawMode.value==="stroke";this.strokeWidth.inputElement.disabled=!t,this.strokeWidth.refresh()}applyDefaults(){const t=this._config.defaultOptions??{};this.includeBackground.checked=t.includeBackgroundRectangles??!0,this.drawMode.value=t.drawMode??"fill";const e=t.strokeWidth??1;this.strokeWidth.value=String(e),this.strokeWidth.refresh()}}const pr=[{format:"txt",label:"plain text (.txt)",supportsClipboard:!0,createBlade:()=>new dr({format:"txt",label:"plain text (.txt)",supportsClipboard:!0,defaultOptions:{preserveTrailingSpaces:!1,emptyCharacter:" "}})},{format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,createBlade:()=>new cr({format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,defaultOptions:{format:"png",scale:1}})},{format:"svg",label:"vector (.svg)",supportsClipboard:!0,createBlade:()=>new ur({format:"svg",label:"vector (.svg)",supportsClipboard:!0,defaultOptions:{includeBackgroundRectangles:!0,drawMode:"fill",strokeWidth:1}})},{format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,createBlade:()=>new ht({format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,defaultOptions:{frameCount:300,frameRate:60,scale:1,repeat:0}})},{format:"video",label:"video (.webm)",supportsClipboard:!1,createBlade:()=>new ft({format:"video",label:"video (.webm)",supportsClipboard:!1,defaultOptions:{frameCount:480,frameRate:60,quality:.7}})}];function hr(c,t){const e=pr,r=e[0]?.format,a=new sr((u=>({format:u,isBusy:!1}))(r)),i=new nr,n=new or(c,t,a,i,e);return n.$mount(),n}const oe=(c={})=>{const t=c.overlay??!0;let e;return{name:"textmode-export",version:"1.0.0",async install(r,a){const i={saveCanvas:async(n={})=>(a.flushDrawCommands(),new yt().$saveImage(r.canvas,n)),copyCanvas:async(n={})=>(a.flushDrawCommands(),new yt().$copyImageToClipboard(r.canvas,n)),saveSVG:(n={})=>{a.flushDrawCommands(),new xt().$saveSVG(r,n)},saveStrings:(n={})=>{a.flushDrawCommands(),new _t().$saveTXT(r,n)},toSVG:(n={})=>(a.flushDrawCommands(),new xt().$generateSVG(r,n)),toString:(n={})=>(a.flushDrawCommands(),new _t().$generateTXT(r,n)),saveGIF:async(n={})=>(a.flushDrawCommands(),new we(r,a.registerPostDrawHook).$saveGIF(n)),saveWEBM:async(n={})=>(a.flushDrawCommands(),new $e(r,a.registerPostDrawHook).$saveWEBM(n))};Object.assign(r,i),t&&(e=hr(r,i))},async uninstall(r){e?.$dispose(),e=void 0;const a=["saveCanvas","copyCanvas","saveSVG","saveStrings","toSVG","toString","saveGIF","saveWEBM"];for(const i of a)delete r[i]}}};typeof window<"u"&&(window.createTextmodeExportPlugin=oe),Q.createTextmodeExportPlugin=oe,Object.defineProperty(Q,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -14,6 +14,8 @@ export declare class OverlayController {
|
|
|
14
14
|
private readonly _definitions;
|
|
15
15
|
private readonly _formats;
|
|
16
16
|
private readonly _eventUnsubscribers;
|
|
17
|
+
private _shadowHost;
|
|
18
|
+
private _shadowRoot;
|
|
17
19
|
private _overlayElement;
|
|
18
20
|
private _optionsContainer;
|
|
19
21
|
private _copyButtonContainer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OverlayController.d.ts","sourceRoot":"","sources":["../../../../src/overlay/core/OverlayController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"OverlayController.d.ts","sourceRoot":"","sources":["../../../../src/overlay/core/OverlayController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAiBnE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAyB;IAE7D,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,gBAAgB,CAAmB;IAE3C,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAA8F;IAClH,OAAO,CAAC,aAAa,CAGlB;IACH,OAAO,CAAC,aAAa,CAA+E;IACpG,OAAO,CAAC,WAAW,CAAmF;IAEtG,OAAO,CAAC,cAAc,CAAe;IACrC,OAAO,CAAC,aAAa,CAAC,CAAgB;IAEtC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAExC;IAEF,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAIrC;IAEF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAInC;gBAGA,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,YAAY,CAAC,YAAY,CAAC,EACjC,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC/B,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC;IAavC,MAAM,IAAI,IAAI;IAQd,QAAQ,IAAI,IAAI;IA0BvB,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,oBAAoB;IA4B5B,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,sBAAsB;IA6C9B,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,sBAAsB;YAMhB,kBAAkB;YAqElB,gBAAgB;IAyB9B,OAAO,CAAC,mBAAmB;CA8C5B"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Textmodifier } from 'textmode.js';
|
|
2
2
|
import type { TextmodeExportAPI } from '../types';
|
|
3
3
|
import { OverlayController } from './core/OverlayController';
|
|
4
|
-
import './style.css';
|
|
5
4
|
export type { ExportFormat } from './types';
|
|
6
5
|
/**
|
|
7
6
|
* Creates an export overlay controller.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/overlay/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/overlay/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAO7D,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,GAAG,iBAAiB,CAS/G"}
|
package/package.json
CHANGED