flatblox-tui 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  Create pixel art in your terminal and preview it as voxels. Export your creations as SVG, PNG or OBJ files.
4
4
 
5
- ![Flatblox terminal editor](https://flatblox.com/tui.jpg)
6
- ![Flatblox terminal editor](https://flatblox.com/tui-3d.jpg)
5
+ ![Flatblox terminal editor](https://flatblox.com/tui-1.jpg)
6
+ ![Flatblox terminal editor](https://flatblox.com/tui-3d-1.jpg)
7
7
 
8
8
  Run the terminal editor without installing it:
9
9
 
@@ -14,8 +14,7 @@ npx flatblox-tui
14
14
  `npx` installs the matching Bun and OpenTUI runtime automatically. macOS,
15
15
  Windows, and Linux on x64 or ARM64 are supported.
16
16
 
17
- Press `C` in the editor to toggle the OpenTUI Three voxel preview. Use the
17
+ Press `C` in the editor to toggle the voxel preview. Use the
18
18
  arrow keys or `H J K L` to orbit, `R` to reset rotation, and `-` / `+` to zoom.
19
- The 3D preview requires
20
- native WebGPU support and is available on macOS x64/ARM64, Windows x64, and
19
+ The 3D preview requires native WebGPU support and is available on macOS x64/ARM64, Windows x64, and
21
20
  Linux x64; the 2D editor remains available everywhere else.
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ ${dl.join(`
14
14
  `)}
15
15
  `}}function wo(e,t){let r=new Uint8Array(12+t.length),n=new DataView(r.buffer);return n.setUint32(0,t.length),r.set(new TextEncoder().encode(e),4),r.set(t,8),n.setUint32(8+t.length,Bun.hash.crc32(r.subarray(4,8+t.length))),r}function Wf(e,t=vo){let r=e.length,i=Zl(e)*t,s=r*t,o=i*4+1,a=new Uint8Array(o*s);for(let f=0;f<r;f++)for(let g=0;g<e[f].length;g++){let m=e[f][g];if(!Xl(m))continue;let p=Jt(m.color);if(!p)continue;for(let v=0;v<t;v++){let y=(f*t+v)*o+1;for(let E=0;E<t;E++){let _=y+(g*t+E)*4;a[_]=p.r,a[_+1]=p.g,a[_+2]=p.b,a[_+3]=Math.round(p.a*255)}}}let l=new Uint8Array(13),c=new DataView(l.buffer);c.setUint32(0,i),c.setUint32(4,s),l[8]=8,l[9]=6;let u=[Uf,wo("IHDR",l),wo("IDAT",new Uint8Array(Gf(a))),wo("IEND",new Uint8Array(0))],d=new Uint8Array(u.reduce((f,g)=>f+g.length,0)),A=0;for(let f of u)d.set(f,A),A+=f.length;return d}function Yf(e,t,r=Tt){let n=[],{saturation:i,lightness:s}=e.paletteColorAdjustment??{saturation:0,lightness:0},o=Qt(e.grid,i,s);for(let a of r)if(a==="svg")n.push({path:`${t}.svg`,content:Hf(o)});else if(a==="obj"){let l=`${t}.mtl`,{obj:c,mtl:u}=Kf(o,Lf(l));n.push({path:`${t}.obj`,content:c}),n.push({path:l,content:u})}else n.push({path:`${t}.png`,content:Wf(o)});return n}async function Bi(e,t,r=Tt,n=(i,s)=>Bun.write(i,s)){let i=Yf(e,t,r);for(let s of i)await n(s.path,s.content);return i.map((s)=>s.path)}import{mkdir as Qf,readFile as Jf,writeFile as Vf}from"fs/promises";import{homedir as $f}from"os";import{dirname as Zf,join as zl}from"path";function ql(e=process.env){if(e.FLATBLOX_TUI_EXPORT_FILE)return e.FLATBLOX_TUI_EXPORT_FILE;let t=e.XDG_CONFIG_HOME||zl($f(),".config");return zl(t,"flatblox","tui-export.json")}async function ec(e=ql()){try{let t=JSON.parse(await Jf(e,"utf8")),r=typeof t==="object"&&t!==null?t.directory:void 0;return typeof r==="string"&&r.length>0?r:null}catch{return null}}async function tc(e,t=ql()){await Qf(Zf(t),{recursive:!0,mode:448}),await Vf(t,`${JSON.stringify({directory:e},null,2)}
16
16
  `)}function or(e){let t=e.name.toLowerCase();return t==="return"||t==="enter"||t==="space"||e.sequence===" "}function wr(e){switch(e){case"left":case"h":return{dx:-1,dy:0};case"right":case"l":return{dx:1,dy:0};case"up":case"k":return{dx:0,dy:-1};case"down":case"j":return{dx:0,dy:1};default:return}}import{MouseButton as _o,NativeImage as nc,parseColor as og,Renderable as ag,RGBA as Un,TextAttributes as ic}from"@opentui/core";import{RGBA as Xf}from"@opentui/core";var zf={r:76,g:76,b:76,a:1},qf={r:96,g:96,b:96,a:1},rc=new Map;function eg(e){let t=rc.get(e);if(t!==void 0)return t;let r=Jt(e);return rc.set(e,r),r}function tg(e,t){return(e+t)%2===0?zf:qf}function rg(e,t){let r=Math.max(0,Math.min(1,e.a));return{r:Math.round(e.r*r+t.r*(1-r)),g:Math.round(e.g*r+t.g*(1-r)),b:Math.round(e.b*r+t.b*(1-r)),a:1}}function ng(e,t,r){let n=tg(t,r),i=e?.active&&e.color?eg(e.color):null;return i?rg(i,n):n}var ig=[new Map,new Map],sg=4096;function ar(e,t,r){let n=ig[(t+r)%2],i=e?.active&&e.color?e.color:"",s=n.get(i);if(!s){if(n.size>=sg)n.clear();let o=ng(e,t,r);s=Xf.fromInts(o.r,o.g,o.b),n.set(i,s)}return s}var Oi=Un.fromInts(22,8,33),sc=Un.fromInts(33,22,41),Co=4,lg=Un.fromInts(255,255,255),cg=Un.fromInts(8,10,16),ug=0.25,Pi=512,oc=16384,dg=25000000;function ac(e,t){if(!e||e.points.length===0)return null;let r=new Set;for(let n of e.points)r.add(n.y*t+n.x);return{cells:r,color:og(e.color)}}function xo(e){let[t,r,n]=e.toInts(),i=(0.2126*t+0.7152*r+0.0722*n)/255,[s,o,a]=i>0.55?cg.toInts():lg.toInts(),l=(c,u)=>Math.round(c+(u-c)*ug);return Un.fromInts(l(t,s),l(r,o),l(n,a))}function lc(e,t,r){return Math.max(0,Math.min(r-t,e-Math.floor(t/2)))}function hg(e,t){let r=Math.ceil(e/Pi)*Pi,n=Math.ceil(t/Pi)*Pi;if(r>oc||n>oc||r*n>dg)return null;return{width:r,height:n}}function Ag(e,t,r,n,i){let o=Math.max(1,Math.floor(n)),a=Math.max(1,Math.round(o*2/i)),l=Math.min(r,Math.floor(e/o)),c=Math.min(r,Math.floor(t*2/a)),u=l*o,d=c*a;return{columns:l,pixelRows:c,columnZoom:o,subrowZoom:a,renderedColumns:u,renderedSubrows:d,terminalRows:Math.ceil(d/2)}}function fg(e,t,r,n,i,s){let o=Math.max(1,Math.floor(n)),a=Math.max(1,Math.round(o*i)),l=Math.min(r,Math.floor(e/o)),c=Math.min(r,Math.floor(t*s/a)),u=l*a,d=c*a,A=d*2/s;return{columns:l,pixelRows:c,columnZoom:o,subrowZoom:a*2/s,renderedColumns:l*o,renderedSubrows:A,terminalRows:Math.ceil(d/s),pixelWidth:u,pixelHeight:d}}class Eo extends ag{textFrame=null;artworkImage=null;artworkImageCache=null;worldImage=null;worldImageSide=0;worldImageWidth=0;worldImageHeight=0;currentModel={grid:[],cursor:{x:0,y:0},zoom:1};cellHandler;viewport={originX:0,originY:0,startX:0,startY:0,columns:0,pixelRows:0,columnZoom:1,subrowZoom:1,renderedSubrows:0};constructor(e,t){super(e,{...t,buffered:!0});if(t.model)this.currentModel=t.model;this.cellHandler=t.onCell,this.onMouseDown=(r)=>this.handleMouse(r)}set model(e){if(!e)return;this.currentModel=e,this.requestRender()}set onCell(e){this.cellHandler=e}sameTextFrame(e){let t=this.currentModel,r=this.textFrame;if(r&&r.grid===t.grid&&r.revision===t.revision&&r.preview===t.preview&&r.cursorX===t.cursor.x&&r.cursorY===t.cursor.y&&r.zoom===t.zoom&&r.width===this.width&&r.height===this.height&&r.cellAspect===e)return!0;return this.textFrame={grid:t.grid,revision:t.revision,preview:t.preview,cursorX:t.cursor.x,cursorY:t.cursor.y,zoom:t.zoom,width:this.width,height:this.height,cellAspect:e},!1}renderSelf(e){let t=this.currentModel.grid.length,r=Ii(this._ctx),n=xt(this._ctx),i=n!==null&&ki(this._ctx);if(i)this.textFrame=null;else if(this.sameTextFrame(r))return;if(e.clear(Oi),t===0||this.width<=0||this.height<=0){this.viewport.columns=0,this.viewport.pixelRows=0;return}let s=n&&i?fg(this.width,this.height,t,this.currentModel.zoom,n.width,n.height):null,o=s??Ag(this.width,this.height,t,this.currentModel.zoom,r),{columns:a,pixelRows:l}=o;if(a===0||l===0){this.viewport.columns=0,this.viewport.pixelRows=0,this.viewport.columnZoom=o.columnZoom,this.viewport.subrowZoom=o.subrowZoom,this.viewport.renderedSubrows=0;return}let{renderedColumns:c,renderedSubrows:u,terminalRows:d}=o,A=lc(this.currentModel.cursor.x,a,t),f=lc(this.currentModel.cursor.y,l,t),g=Math.floor((this.width-c)/2),m=Math.floor((this.height-d)/2);if(s&&n){if(!this.drawWorldGridImage(e,g,m,n.width,n.height))this.drawWorldGrid(e,g,m,r)}else this.releaseWorldImage(),this.drawWorldGrid(e,g,m,r);if(this.viewport={originX:g,originY:m,startX:A,startY:f,columns:a,pixelRows:l,columnZoom:o.columnZoom,subrowZoom:o.subrowZoom,renderedSubrows:u},s){this.drawArtworkImage(e,s,g,m,A,f);return}this.releaseArtworkImage();let{grid:p,cursor:v}=this.currentModel,y=ac(this.currentModel.preview,t),{subrowZoom:E,columnZoom:_}=o;for(let b=0;b<d;b++){let w=b*2,C=w+1,O=f+Math.floor(w/E),N=f+Math.floor(C/E),P=p[O],R=p[N];for(let U=0;U<c;U++){let X=A+Math.floor(U/_),V=y?.cells.has(O*t+X)?y.color:ar(P?.[X],X,O),te=C<u&&N<t?y?.cells.has(N*t+X)?y.color:ar(R?.[X],X,N):Oi,ge=v.x===X&&v.y===O,z=v.x===X&&v.y===N;e.setCell(g+U,m+b,"\u2580",ge?xo(V):V,z?xo(te):te)}}}drawArtworkImage(e,t,r,n,i,s){let o=this.currentModel.cursor,a=this.artworkImageCache;if(!(this.artworkImage&&a&&a.grid===this.currentModel.grid&&a.revision===this.currentModel.revision&&a.preview===this.currentModel.preview&&a.columns===t.columns&&a.pixelRows===t.pixelRows&&a.pixelWidth===t.pixelWidth&&a.pixelHeight===t.pixelHeight&&a.startX===i&&a.startY===s&&a.cursorX===o.x&&a.cursorY===o.y)){let c=this.currentModel.grid.length,u=ac(this.currentModel.preview,c),d=new Uint8Array(t.columns*t.pixelRows*4);for(let g=0;g<t.pixelRows;g++){let m=s+g;for(let p=0;p<t.columns;p++){let v=i+p,y=u?.cells.has(m*c+v)?u.color:ar(this.currentModel.grid[m]?.[v],v,m);if(o.x===v&&o.y===m)y=xo(y);let[E,_,b]=y.toInts(),w=(g*t.columns+p)*4;d[w]=E,d[w+1]=_,d[w+2]=b,d[w+3]=255}}let A=nc.fromRgba(d,t.columns,t.pixelRows),f=A.resize({width:t.pixelWidth,height:t.pixelHeight,kernel:"nearest"});A.dispose(),this.releaseArtworkImage(),this.artworkImage=f,this.artworkImageCache={grid:this.currentModel.grid,revision:this.currentModel.revision,preview:this.currentModel.preview,columns:t.columns,pixelRows:t.pixelRows,pixelWidth:t.pixelWidth,pixelHeight:t.pixelHeight,startX:i,startY:s,cursorX:o.x,cursorY:o.y}}if(!this.artworkImage)return;e.drawImage(this.artworkImage,r,n,t.renderedColumns,t.terminalRows,t.pixelWidth,t.pixelHeight,0,0,t.pixelWidth,t.pixelHeight,"auto")}releaseArtworkImage(){this.artworkImage?.dispose(),this.artworkImage=null,this.artworkImageCache=null}drawWorldGridImage(e,t,r,n,i){let s=Math.max(1,Math.round(this.width*n)),o=Math.max(1,Math.round(this.height*i)),a=Math.max(1,Math.round(Co*n)),l=Math.round(t*n),c=Math.round(r*i),u=s+a,d=o+a,A=hg(u,d);if(!A)return this.releaseWorldImage(),!1;if(!this.worldImage||a!==this.worldImageSide||u>this.worldImageWidth||d>this.worldImageHeight){let{width:m,height:p}=A,v=new Uint8Array(m*p*4),[y,E,_]=Oi.toInts(),[b,w,C]=sc.toInts(),O=m*4,N=new Uint8Array(O),P=new Uint8Array(O);for(let R=0;R<m;R++){let U=R*4,X=R%a===0;N[U]=X?b:y,N[U+1]=X?w:E,N[U+2]=X?C:_,N[U+3]=255,P[U]=b,P[U+1]=w,P[U+2]=C,P[U+3]=255}for(let R=0;R<p;R++)v.set(R%a===0?P:N,R*O);this.releaseWorldImage(),this.worldImage=nc.fromRgba(v,m,p),this.worldImageSide=a,this.worldImageWidth=m,this.worldImageHeight=p}if(!this.worldImage)return!1;let f=(-l%a+a)%a,g=(-c%a+a)%a;return e.drawImage(this.worldImage,0,0,this.width,this.height,s,o,f,g,s,o,"auto"),!0}releaseWorldImage(){this.worldImage?.dispose(),this.worldImage=null,this.worldImageSide=0,this.worldImageWidth=0,this.worldImageHeight=0}drawWorldGrid(e,t,r,n){let i=Math.max(1,Math.round(Co/n));for(let s=0;s<this.height;s++){let o=s+1-r,a=Math.floor(o/i)!==Math.floor((o-1)/i);for(let l=0;l<this.width;l++){let c=l>0&&(l-t)%Co===0;if(!a&&!c)continue;e.setCell(l,s,c?"\u258F":" ",sc,Oi,a?ic.UNDERLINE:ic.NONE)}}}destroySelf(){this.releaseArtworkImage(),this.releaseWorldImage(),super.destroySelf()}handleMouse(e){if(e.button!==_o.LEFT&&e.button!==_o.RIGHT)return;let t=e.x-this.screenX-this.viewport.originX,r=e.y-this.screenY-this.viewport.originY;if(t<0||t>=this.viewport.columns*this.viewport.columnZoom||r<0||r>=Math.ceil(this.viewport.renderedSubrows/2))return;let n=this.viewport.startX+Math.floor(t/this.viewport.columnZoom),i=e.modifiers.shift?1:0,s=r*2+i;if(s>=this.viewport.renderedSubrows)return;let o=this.viewport.startY+Math.floor(s/this.viewport.subrowZoom);if(o>=this.currentModel.grid.length)return;this.cellHandler?.({x:n,y:o,...e.button===_o.RIGHT?{tool:"erase"}:{}})}}import{RGBA as Cg}from"@opentui/core";import{SuperSampleType as xg,ThreeRenderable as Eg}from"@opentui/three";import{appendFileSync as gg}from"fs";var cc=process.env.FLATBLOX_TUI_TIMING;function vr(e,t){if(!cc)return;let r=(performance.now()-t).toFixed(0);gg(cc,`${e} ${r}ms
17
- `)}import{RGBA as mg}from"@opentui/core";var So="Loading voxel preview\u2026",pg=mg.fromInts(175,129,202);function Di(e,t,r,n){if(t<1||r<1)return;let i=t>=So.length?So:So.slice(0,t),s=Math.max(0,Math.floor((t-i.length)/2)),o=Math.floor((r-1)/2);e.drawText(i,s,o,pg,n)}import{THREE as Ce}from"@opentui/three";var bg=1.12,yg=[0.76,0.64,1,0.42,0.9,0.72],uc=128,wg=2,dc=6710886,vg=new Uint8Array([76,76,76,255,96,96,96,255,96,96,96,255,76,76,76,255]);function _g(e,t){let r=[];for(let n of yg){let i=t?n**2.2:n;for(let s=0;s<4;s+=1)r.push(i,i,i)}e.setAttribute("color",new Ce.Float32BufferAttribute(r,3))}class Hn{scene=new Ce.Scene;camera=new Ce.OrthographicCamera(-1,1,1,-1,0.1,1000);boxGeometry=new Ce.BoxGeometry(1,1,1);boxMaterial;sceneHalfExtents=new Ce.Vector3(2,2,2);groundGeometry;groundMaterial;groundTexture;ground;worldGrid;mesh=null;model;aspect=1;sceneCenterY=0;constructor(e,t){if(this.model=e,_g(this.boxGeometry,t==="raster"),this.boxMaterial=new Ce.MeshBasicMaterial({toneMapped:!1,vertexColors:!0}),t==="raster"){this.groundGeometry=new Ce.PlaneGeometry(1,1),this.groundTexture=new Ce.DataTexture(vg,2,2),this.groundTexture.colorSpace=Ce.SRGBColorSpace,this.groundTexture.magFilter=Ce.NearestFilter,this.groundTexture.minFilter=Ce.NearestFilter,this.groundTexture.wrapS=Ce.RepeatWrapping,this.groundTexture.wrapT=Ce.RepeatWrapping,this.groundTexture.needsUpdate=!0,this.groundMaterial=new Ce.MeshBasicMaterial({map:this.groundTexture,toneMapped:!1}),this.ground=new Ce.Mesh(this.groundGeometry,this.groundMaterial),this.ground.rotation.x=-Math.PI/2,this.scene.add(this.ground),this.worldGrid=new Ce.GridHelper(uc,uc/wg,dc,dc);let r=Array.isArray(this.worldGrid.material)?this.worldGrid.material:[this.worldGrid.material];for(let n of r)n.toneMapped=!1,n.transparent=!0,n.opacity=0.06;this.scene.add(this.worldGrid)}this.rebuildMesh(),this.updateCamera()}update(e,t=this.aspect){let r=e.grid!==this.model.grid||e.revision!==this.model.revision;if(this.model=e,this.aspect=Math.max(0.25,t),r)this.rebuildMesh();this.updateCamera()}setAspect(e){this.aspect=Math.max(0.25,e),this.updateCamera()}dispose(){this.scene.clear(),this.mesh=null}rebuildMesh(){if(this.mesh)this.scene.remove(this.mesh);let e=Ri(this.model.grid),t=this.model.grid.length,r=this.model.grid.reduce((l,c)=>Math.max(l,c.length),0),n=e.reduce((l,c)=>Math.min(l,c.y-c.height/2),0),i=e.reduce((l,c)=>Math.max(l,c.y+c.height/2),0);if(this.sceneHalfExtents.set(Math.max(1,r)/2,Math.max(1,i-n)/2,Math.max(1,t)/2),this.sceneCenterY=(n+i)/2,this.ground)this.ground.position.y=n-0.04,this.ground.scale.set(Math.max(1,r),Math.max(1,t),1),this.groundTexture?.repeat.set(Math.max(1,r)/2,Math.max(1,t)/2);if(this.worldGrid)this.worldGrid.position.y=n-0.08;if(e.length===0){this.mesh=null;return}let s=new Ce.InstancedMesh(this.boxGeometry,this.boxMaterial,e.length),o=new Ce.Object3D,a=new Ce.Color;for(let l=0;l<e.length;l+=1){let c=e[l];o.position.set(c.x,c.y,c.z),o.scale.set(1,c.height,1),o.updateMatrix(),s.setMatrixAt(l,o.matrix);let u=nr(c.color)??{r:255,g:255,b:255};s.setColorAt(l,a.setRGB(u.r/255,u.g/255,u.b/255,Ce.SRGBColorSpace))}if(s.instanceMatrix.needsUpdate=!0,s.instanceColor)s.instanceColor.needsUpdate=!0;this.scene.add(s),this.mesh=s}updateCamera(){let e=new Ce.Vector3(Math.sin(this.model.yaw)*Math.cos(this.model.pitch),Math.sin(this.model.pitch),Math.cos(this.model.yaw)*Math.cos(this.model.pitch)),t=new Ce.Vector3(0,this.sceneCenterY,0);this.camera.position.copy(t).addScaledVector(e,100),this.camera.lookAt(t);let r=new Ce.Vector3(Math.sin($t)*Math.cos(sr),Math.sin(sr),Math.cos($t)*Math.cos(sr)),n=new Ce.Vector3(Math.cos($t),0,-Math.sin($t)),i=r.clone().cross(n).normalize(),s=Math.abs(n.x)*this.sceneHalfExtents.x+Math.abs(n.z)*this.sceneHalfExtents.z,o=Math.abs(i.x)*this.sceneHalfExtents.x+Math.abs(i.y)*this.sceneHalfExtents.y+Math.abs(i.z)*this.sceneHalfExtents.z,a=Math.sqrt(2/this.model.zoom),l=Math.max(1,o,s/this.aspect)*bg*a;this.camera.left=-l*this.aspect,this.camera.right=l*this.aspect,this.camera.top=l,this.camera.bottom=-l,this.camera.updateProjectionMatrix()}}function Ni(){return{grid:[],yaw:$t,pitch:sr,zoom:1}}var hc=Cg.fromInts(22,8,33),Sg=250;class Io extends Eg{currentModel;sceneController;initErrorHandler;rendererReady=!1;firstFrameDrawn=!1;destroyRequested=!1;sceneDisposed=!1;constructor(e,t){let{model:r,onInitError:n,renderer:i,...s}=t,o=r??Ni(),a=new Hn(o,"terminal");super(e,{...s,scene:a.scene,camera:a.camera,autoAspect:!1,live:!1,renderer:{backgroundColor:hc,superSample:xg.GPU,...i}});this.currentModel=o,this.sceneController=a,this.initErrorHandler=n,this.sceneController.setAspect(this.aspectRatio),setTimeout(()=>void this.warmUp(),Sg);let l=this.renderer.drawScene.bind(this.renderer);this.renderer.drawScene=async(...u)=>{if(await l(...u),!this.firstFrameDrawn)this.firstFrameDrawn=!0,this.requestRender()};let c=this.renderer.init.bind(this.renderer);this.renderer.init=async()=>{try{if(await c(),this.rendererReady=!0,this.destroyRequested)this.disposeScene()}catch(u){let d=u instanceof Error?u.message:String(u);throw this.initErrorHandler?.(d),u}}}async warmUp(){if(this.destroyRequested)return;let e=performance.now(),r=await this.ensureInitialized();if(vr("voxel preview init",e),!r||this.destroyRequested||!this.sceneController)return;let n=this.renderer,i=performance.now();await n.threeRenderer?.render(this.sceneController.scene,this.sceneController.camera),vr("voxel preview first render",i)}get model(){return this.currentModel}set model(e){this.currentModel=e,this.sceneController?.update(e,this.aspectRatio),this.requestRender()}set onInitError(e){this.initErrorHandler=e}renderSelf(e,t){if(super.renderSelf(e,t),!this.firstFrameDrawn&&this.visible)Di(e,this.width,this.height,hc)}onResize(e,t){super.onResize(e,t),this.sceneController?.setAspect(this.aspectRatio)}destroySelf(){if(this.destroyRequested=!0,super.destroySelf(),this.rendererReady)this.disposeScene()}disposeScene(){if(this.sceneDisposed)return;this.sceneDisposed=!0,this.sceneController?.dispose()}}import{NativeImage as Ig,Renderable as kg,RGBA as Rg}from"@opentui/core";import{CLICanvas as Tg,SuperSampleType as Bg,THREE as Mi}from"@opentui/three";import{createWebGPUDevice as Og,setupGlobals as Pg}from"bun-webgpu";import{WebGPURenderer as Dg}from"three/webgpu";var Li=[22,8,33],Ac=Rg.fromInts(...Li),Ng=250,fc=64,Mg=250,Lg=150,Fg=0.4;class ko extends kg{currentModel;sceneController;initErrorHandler;frame=null;device=null;canvas=null;context=null;webgpuRenderer=null;readbackBuffer=null;readbackSize=0;renderWidth=0;renderHeight=0;pending=!1;scheduled=!1;rendering=!1;failed=!1;destroyRequested=!1;warmedUp=!1;lowDetail=!1;lastModelUpdate=0;refineTimer=null;constructor(e,t){let{model:r,onInitError:n,...i}=t;super(e,{...i,buffered:!0,live:!1});this.currentModel=r??Ni(),this.sceneController=new Hn(this.currentModel,"raster"),this.initErrorHandler=n,this.scheduleRender(),setTimeout(()=>void this.warmUp(),Ng)}async warmUp(){if(this.warmedUp||this.rendering||this.failed||this.destroyRequested)return;this.rendering=!0;try{if(await this.ensureRenderer(fc,fc),this.destroyRequested)return;this.sceneController.update(this.currentModel,1);let e=performance.now();await this.webgpuRenderer.render(this.sceneController.scene,this.sceneController.camera),vr("voxel raster first render",e),this.warmedUp=!0}catch(e){this.failed=!0;let t=e instanceof Error?e.message:String(e);this.initErrorHandler?.(t)}finally{if(this.rendering=!1,this.destroyRequested)this.releaseGpu();else if(this.pending)this.scheduleRender()}}get model(){return this.currentModel}set model(e){this.currentModel=e;let t=performance.now();if(this.lowDetail=t-this.lastModelUpdate<Mg,this.lastModelUpdate=t,this.refineTimer)clearTimeout(this.refineTimer);this.refineTimer=setTimeout(()=>{if(this.refineTimer=null,!this.lowDetail)return;this.lowDetail=!1,this.scheduleRender()},Lg),this.scheduleRender()}set onInitError(e){this.initErrorHandler=e}renderSelf(e){e.clear(Ac);let t=this.frame,r=xt(this._ctx);if(!t||!r||!ir(this._ctx.capabilities)){if(!t&&!this.failed)Di(e,this.width,this.height,Ac);return}let n=Math.max(1,Math.round(this.width*r.width)),i=Math.max(1,Math.round(this.height*r.height));e.drawImage(t,0,0,this.width,this.height,n,i,0,0,t.width,t.height,"auto")}onResize(e,t){if(super.onResize(e,t),this.sceneController)this.scheduleRender()}set visible(e){if(super.visible=e,e&&this.pending)this.scheduleRender()}get visible(){return super.visible}destroySelf(){if(this.destroyRequested=!0,this.refineTimer)clearTimeout(this.refineTimer);if(this.releaseFrame(),!this.rendering)this.releaseGpu();super.destroySelf()}scheduleRender(){if(this.pending=!0,this.scheduled||this.rendering||this.failed||this.destroyRequested||!this.visible&&this.warmedUp)return;this.scheduled=!0,queueMicrotask(()=>{this.scheduled=!1,this.flushRender()})}async flushRender(){if(this.rendering||this.failed||this.destroyRequested)return;this.rendering=!0;try{while(this.pending&&!this.destroyRequested){if(!this.visible&&this.warmedUp)break;this.pending=!1,await this.renderFrame(),this.warmedUp=!0}}catch(e){this.failed=!0;let t=e instanceof Error?e.message:String(e);this.initErrorHandler?.(t)}finally{if(this.rendering=!1,this.destroyRequested)this.releaseGpu();else if(this.pending)this.scheduleRender()}}dimensions(){let e=xt(this._ctx);if(!e||this.width<=0||this.height<=0)return null;return Jl(this.width,this.height,e.width,e.height,this.lowDetail?{density:Fg}:void 0)}async renderFrame(){let e=this.dimensions();if(!e)return;if(await this.ensureRenderer(e.width,e.height),this.destroyRequested)return;this.resizeRenderer(e.width,e.height),this.sceneController.update(this.currentModel,e.width/e.height),await this.webgpuRenderer.render(this.sceneController.scene,this.sceneController.camera);let t=await this.captureFrame(e.width,e.height);if(!t)return;this.releaseFrame(),this.frame=t,this.requestRender()}async ensureRenderer(e,t){if(this.webgpuRenderer)return;let r=performance.now();await Pg();let n=await Og();vr("voxel raster device",r);let i=new Tg(n,e,t,Bg.NONE),s=new Dg({canvas:i,device:n,alpha:!0});s.outputColorSpace=Mi.SRGBColorSpace,s.toneMapping=Mi.NoToneMapping,s.setClearColor(new Mi.Color().setRGB(Li[0]/255,Li[1]/255,Li[2]/255,Mi.SRGBColorSpace),1),s.setSize(e,t,!1),await s.init(),vr("voxel raster renderer init",r),this.device=n,this.canvas=i,this.context=i.getContext("webgpu"),this.webgpuRenderer=s,this.renderWidth=e,this.renderHeight=t}resizeRenderer(e,t){if(e===this.renderWidth&&t===this.renderHeight)return;this.canvas.setSize(e,t),this.webgpuRenderer.setSize(e,t,!1),this.renderWidth=e,this.renderHeight=t,this.releaseReadback()}async captureFrame(e,t){let r=this.device,n=this.context,i=Math.ceil(e*4/256)*256,s=i*t;if(!this.readbackBuffer||this.readbackSize!==s)this.releaseReadback(),this.readbackBuffer=r.createBuffer({label:"Flatblox voxel image readback",size:s,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.readbackSize=s;let o=n.getCurrentTexture();n.switchTextures();let a=r.createCommandEncoder({label:"Flatblox voxel image capture"});if(a.copyTextureToBuffer({texture:o},{buffer:this.readbackBuffer,bytesPerRow:i,rowsPerImage:t},{width:e,height:t}),r.queue.submit([a.finish()]),await this.readbackBuffer.mapAsync(GPUMapMode.READ),this.destroyRequested)return this.readbackBuffer.unmap(),null;let l=new Uint8Array(this.readbackBuffer.getMappedRange().slice(0));this.readbackBuffer.unmap();let c=o.format,u=Ig.fromPixels(l,e,t,{stride:i,format:c==="bgra8unorm"?"bgra8":"rgba8",alpha:"opaque"});return u.ensureEncodedPng(),u}releaseFrame(){this.frame?.dispose(),this.frame=null}releaseReadback(){this.readbackBuffer?.destroy(),this.readbackBuffer=null,this.readbackSize=0}releaseGpu(){this.releaseReadback(),this.webgpuRenderer?.dispose(),this.canvas?.destroy(),this.device?.destroy(),this.webgpuRenderer=null,this.canvas=null,this.context=null,this.device=null,this.sceneController.dispose()}}var gc={name:"flatblox-tui",version:"0.2.7",description:"Flatblox pixel art editor for the terminal",homepage:"https://flatblox.com",license:"MIT",type:"module",bin:{"flatblox-tui":"dist/index.js"},files:["dist","README.md"],publishConfig:{access:"public"},scripts:{build:"bun --env-file=../web/.env scripts/build.ts",dev:"bun --env-file=../web/.env --watch src/index.tsx",prepack:"bun run build",start:"bun --env-file=../web/.env src/index.tsx",typecheck:"tsc --noEmit",test:"bun test --preload ./scripts/preload.ts"},dependencies:{"@opentui/core":"^0.5.10","@opentui/solid":"^0.5.10","@opentui/three":"^0.5.10",bun:"^1.4.0","bun-webgpu":"0.1.7","solid-js":"1.9.12",three:"0.177.0"},devDependencies:{"@flatblox/editor-core":"workspace:*","@flatblox/shared":"workspace:*","@supabase/supabase-js":"^2.49.4","@types/bun":"latest","@types/three":"0.177.0",typescript:"~5.9.3"}};var Fi=`v${gc.version}`;import{NativeImage as mc,parseColor as Ug}from"@opentui/core";Yt({fitted_image:Ln});var Hg=new URL("./flatblox-logo.png",import.meta.url),jg=mc.load(Hg),Ro=new Map;function Kg(e){let t=Ro.get(e);if(!t)t=jg.then((r)=>{let[n,i,s]=Ug(e).toInts(),o=new Uint8Array(r.width*r.height*4);for(let l=0;l<o.length;l+=4)o[l]=n,o[l+1]=i,o[l+2]=s,o[l+3]=255;let a=mc.fromRgba(o,r.width,r.height);try{return a.composite(r)}finally{a.dispose()}}),t.catch(()=>Ro.delete(e)),Ro.set(e,t);return t}function $r(e){let t=ht(),r=Jr(),[n,i]=j(),s=!1;return gr(()=>{Kg(e.backgroundColor).then((o)=>{if(!s)i(o),t.requestRender()},()=>{})}),ot(()=>{s=!0}),Q(ke,{get when(){return lt(()=>!!r())()&&n()},get fallback(){return(()=>{var o=S("box");return h(o,"alignItems","center"),h(o,"justifyContent","center"),L(o,Q(ke,{get when(){return e.height>=2},get fallback(){return(()=>{var a=S("text"),l=S("b");return k(a,l),k(l,Re("FLATBLOX")),de((c)=>h(a,"fg",e.foregroundColor,c)),a})()},get children(){var a=S("ascii_font");return h(a,"text","FLATBLOX"),h(a,"font","tiny"),de((l)=>{var c=`${e.id}-ascii`,u=e.foregroundColor,d=e.backgroundColor;return c!==l.e&&(l.e=h(a,"id",c,l.e)),u!==l.t&&(l.t=h(a,"color",u,l.t)),d!==l.a&&(l.a=h(a,"backgroundColor",d,l.a)),l},{e:void 0,t:void 0,a:void 0}),a}})),de((a)=>{var{id:l,width:c,height:u,backgroundColor:d}=e;return l!==a.e&&(a.e=h(o,"id",l,a.e)),c!==a.t&&(a.t=h(o,"width",c,a.t)),u!==a.a&&(a.a=h(o,"height",u,a.a)),d!==a.o&&(a.o=h(o,"backgroundColor",d,a.o)),a},{e:void 0,t:void 0,a:void 0,o:void 0}),o})()},get children(){var o=S("fitted_image");return de((a)=>{var l=e.id,c=n(),u=e.width,d=e.height,A=e.backgroundColor;return l!==a.e&&(a.e=h(o,"id",l,a.e)),c!==a.t&&(a.t=h(o,"source",c,a.t)),u!==a.a&&(a.a=h(o,"width",u,a.a)),d!==a.o&&(a.o=h(o,"height",d,a.o)),A!==a.i&&(a.i=h(o,"background",A,a.i)),a},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),o}})}Yt({pixel_grid:Eo,voxel_raster:ko,voxel_preview:Io});var x={background:je("hsl(275 60% 9%)"),panel:je("hsl(275 60% 11%)"),panelActive:je("hsl(275 60% 14%)"),card:je("hsl(275 60% 16%)"),border:je("hsl(275 60% 28%)"),text:je("hsl(278 100% 80%)"),muted:je("hsl(278 41% 65%)"),accent:je("hsl(315 68% 71%)"),accentText:je("hsl(278 70% 80%)"),warning:je("hsl(37 100% 71%)"),textPink:je("hsl(308, 50%, 75%)"),orangeActive:je("hsl(28, 80%, 38%)")};function je(e){let t=nr(e);return t?En(t):"#ffffff"}function Zt(e){return e[0].toUpperCase()+e.slice(1)}function Yg(e){return(()=>{var t=S("box");return h(t,"flexDirection","column"),h(t,"gap",0),L(t,Q(wt,{get each(){return e.colors.slice(0,10)},children:(r,n)=>{let i=K(()=>(e.refresh(),e.session.selectedColorIndex===n())),s=n()===9?"0":String(n()+1);return(()=>{var o=S("box"),a=S("text"),l=Re(" ");return k(o,a),h(o,"height",1),h(o,"flexDirection","row"),h(o,"paddingX",1),L(o,Q(Fn,{get color(){return je(r)},get background(){return lt(()=>!!i())()?x.panelActive:x.panel}}),a),k(a,l),L(a,()=>i()?" \u203A ":" ",l),L(a,s,l),L(a,()=>je(r),null),de((c)=>{var u=i()?x.panelActive:x.panel,d=i()?x.text:x.muted;return u!==c.e&&(c.e=h(o,"backgroundColor",u,c.e)),d!==c.t&&(c.t=h(a,"fg",d,c.t)),c},{e:void 0,t:void 0}),o})()}})),t})()}function Qg(e){let t=K(()=>(e.refresh(),{tool:Zt(e.session.tool),mirrorX:e.session.mirrorX?"on":"off",mirrorY:e.session.mirrorY?"on":"off",cursor:`${e.session.cursor.x+1}, ${e.session.cursor.y+1}`}));return(()=>{var r=S("box"),n=S("box"),i=S("box"),s=S("text"),o=Re("Tool: "),a=S("text"),l=Re("Cursor: "),c=S("box"),u=S("box"),d=S("box"),A=S("text"),f=Re("Mirror X: "),g=S("text"),m=Re("Mirror Y: ");return k(r,n),h(r,"id","sidebar"),h(r,"flexDirection","column"),h(r,"paddingY",1),k(n,i),k(n,c),k(n,u),k(n,d),h(n,"width","100%"),h(n,"flexDirection","column"),h(n,"paddingX",1),k(i,s),k(i,a),h(i,"flexDirection","column"),k(s,o),L(s,()=>t().tool,null),k(a,l),L(a,()=>t().cursor,null),h(c,"height",1),L(n,Q(Yg,{get session(){return e.session},get colors(){return e.colors},get refresh(){return e.refresh}}),u),h(u,"height",1),k(d,A),k(d,g),h(d,"flexDirection","column"),k(A,f),L(A,()=>t().mirrorX,null),k(g,m),L(g,()=>t().mirrorY,null),de((p)=>{var v=e.visible?28:0,y=e.visible,E=x.panel,_=x.textPink,b=x.textPink,w=x.muted,C=x.muted;return v!==p.e&&(p.e=h(r,"width",v,p.e)),y!==p.t&&(p.t=h(r,"visible",y,p.t)),E!==p.a&&(p.a=h(r,"backgroundColor",E,p.a)),_!==p.o&&(p.o=h(s,"fg",_,p.o)),b!==p.i&&(p.i=h(a,"fg",b,p.i)),w!==p.n&&(p.n=h(A,"fg",w,p.n)),C!==p.s&&(p.s=h(g,"fg",C,p.s)),p},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0}),r})()}function Jg(e){let t=K(()=>{e.refresh();let r=`${e.session.mirrorX?"X":"-"}${e.session.mirrorY?"Y":"-"}`;return{tool:Zt(e.session.tool),color:je(e.colors[e.session.selectedColorIndex]??e.session.activeColor),mirror:r}});return(()=>{var r=S("box"),n=S("text"),i=Re("Tool "),s=Re(" Color "),o=S("text"),a=Re(" "),l=Re(" Mirror ");return k(r,n),k(r,o),h(r,"border",!0),h(r,"borderStyle","rounded"),h(r,"paddingX",1),h(r,"flexDirection","row"),k(n,i),k(n,s),L(n,()=>t().tool,s),L(r,Q(Fn,{get color(){return t().color},get background(){return x.panel}}),o),k(o,a),k(o,l),L(o,()=>t().color,l),L(o,()=>t().mirror,null),de((c)=>{var u=e.visible?3:0,d=e.visible,A=x.border,f=x.panel,g=x.textPink,m=x.textPink;return u!==c.e&&(c.e=h(r,"height",u,c.e)),d!==c.t&&(c.t=h(r,"visible",d,c.t)),A!==c.a&&(c.a=h(r,"borderColor",A,c.a)),f!==c.o&&(c.o=h(r,"backgroundColor",f,c.o)),g!==c.i&&(c.i=h(n,"fg",g,c.i)),m!==c.n&&(c.n=h(o,"fg",m,c.n)),c},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),r})()}var Vg=11;function $g(e){return[["Move","Arrow keys or H J K L"],["Paint","Space or Enter"],["Tools","D draw | E erase | F fill | R rectangle | O circle"],["Shapes","Space sets a corner, Space again draws, Esc cancels"],["Palette","1\u20130 direct | [ and ] cycle"],["Mirroring","X horizontal | Y vertical"],["Blender","B connect / disconnect"],["History","U undo | Ctrl+Z undo | Ctrl+Y redo"],["View","C toggle 2D / 3D | arrows orbit | R resets rotation"],["Zoom","- / +"],["Save","Ctrl+S"],["Export","Ctrl+E choose SVG / OBJ / PNG and a destination"],["Help","?"],...e?[["Artworks","Escape"],["Quit","Q"]]:[["Quit","Q or Escape"]],["",""],["Mouse","Click to paint | right-click to erase"],["","Shift+click targets the lower half-cell"],["",""],["","Press ? or Escape to close help."]]}function Zg(e){let t=K(()=>$g(e.canGoBack)),r=K(()=>Math.max(1,Math.min(70,e.width-2))),n=K(()=>Math.max(1,Math.min(t().length+4,e.height-2)));return(()=>{var i=S("box");return h(i,"id","help-overlay"),h(i,"position","absolute"),h(i,"zIndex",20),h(i,"border",!0),h(i,"title"," Keyboard & mouse "),h(i,"padding",1),L(i,Q(wt,{get each(){return t()},children:([s,o])=>(()=>{var a=S("box"),l=S("text"),c=S("text");return k(a,l),k(a,c),h(a,"flexDirection","row"),L(l,()=>s.padEnd(Vg)),L(c,o),de((u)=>{var{textPink:d,accentText:A}=x;return d!==u.e&&(u.e=h(l,"fg",d,u.e)),A!==u.t&&(u.t=h(c,"fg",A,u.t)),u},{e:void 0,t:void 0}),a})()})),de((s)=>{var o=Math.max(0,Math.floor((e.width-r())/2)),a=Math.max(0,Math.floor((e.height-n())/2)),l=r(),c=n(),u=e.visible,d=x.border,A=x.panel,f=x.accent;return o!==s.e&&(s.e=h(i,"left",o,s.e)),a!==s.t&&(s.t=h(i,"top",a,s.t)),l!==s.a&&(s.a=h(i,"width",l,s.a)),c!==s.o&&(s.o=h(i,"height",c,s.o)),u!==s.i&&(s.i=h(i,"visible",u,s.i)),d!==s.n&&(s.n=h(i,"borderColor",d,s.n)),A!==s.s&&(s.s=h(i,"backgroundColor",A,s.s)),f!==s.h&&(s.h=h(i,"titleColor",f,s.h)),s},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0}),i})()}function Xg(e){let t=K(()=>Math.max(1,Math.min(48,e.width-4))),r=K(()=>Math.max(1,Math.min(7,e.height-2))),n=K(()=>r()>=7?1:0);return(()=>{var i=S("box"),s=S("box"),o=S("input"),a=S("box"),l=S("text");return k(i,s),h(i,"id","filename-modal"),h(i,"position","absolute"),h(i,"zIndex",30),h(i,"border",!0),h(i,"title"," Save artwork "),h(i,"flexDirection","column"),k(s,o),k(s,a),k(s,l),h(s,"flexGrow",1),h(s,"width","100%"),h(s,"padding",1),h(s,"flexDirection","column"),h(o,"id","artwork-name-input"),h(o,"width","100%"),h(o,"maxLength",ro),h(o,"focused",!0),h(o,"onKeyDown",(c)=>{if(c.eventType!=="release"&&c.name==="escape")c.preventDefault(),e.onCancel()}),L(l,()=>e.error||"Enter save \xB7 Esc cancel"),de((c)=>{var u=Math.max(0,Math.floor((e.width-t())/2)),d=Math.max(0,Math.floor((e.height-r())/2)),A=t(),f=r(),g=x.border,m=x.panel,p=x.accent,v=x.panel,y=e.value,E=x.panelActive,_=x.panelActive,b=x.text,w=x.text,C=e.onInput,O=e.onSubmit,N=n(),P=e.error?x.warning:x.accentText;return u!==c.e&&(c.e=h(i,"left",u,c.e)),d!==c.t&&(c.t=h(i,"top",d,c.t)),A!==c.a&&(c.a=h(i,"width",A,c.a)),f!==c.o&&(c.o=h(i,"height",f,c.o)),g!==c.i&&(c.i=h(i,"borderColor",g,c.i)),m!==c.n&&(c.n=h(i,"backgroundColor",m,c.n)),p!==c.s&&(c.s=h(i,"titleColor",p,c.s)),v!==c.h&&(c.h=h(s,"backgroundColor",v,c.h)),y!==c.r&&(c.r=h(o,"value",y,c.r)),E!==c.d&&(c.d=h(o,"backgroundColor",E,c.d)),_!==c.l&&(c.l=h(o,"focusedBackgroundColor",_,c.l)),b!==c.u&&(c.u=h(o,"textColor",b,c.u)),w!==c.c&&(c.c=h(o,"focusedTextColor",w,c.c)),C!==c.w&&(c.w=h(o,"onInput",C,c.w)),O!==c.m&&(c.m=h(o,"on:enter",O,c.m)),N!==c.f&&(c.f=h(a,"height",N,c.f)),P!==c.y&&(c.y=h(l,"fg",P,c.y)),c},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0,u:void 0,c:void 0,w:void 0,m:void 0,f:void 0,y:void 0}),i})()}var zg={svg:"SVG flat vector",obj:"OBJ voxel mesh (+ .mtl)",png:"PNG 16px per cell"};function qg(e){let t=K(()=>Math.max(1,Math.min(66,e.width-4))),r=K(()=>Math.max(1,Math.min(12,e.height-2)));return(()=>{var n=S("box"),i=S("box"),s=S("box"),o=S("text"),a=S("input"),l=S("box"),c=S("text");return k(n,i),h(n,"id","export-modal"),h(n,"position","absolute"),h(n,"zIndex",30),h(n,"border",!0),h(n,"title"," Export artwork "),h(n,"flexDirection","column"),k(i,s),k(i,o),k(i,a),k(i,l),k(i,c),h(i,"flexGrow",1),h(i,"width","100%"),h(i,"padding",1),h(i,"flexDirection","column"),L(i,Q(wt,{each:Tt,children:(u,d)=>(()=>{var A=S("box"),f=S("text");return k(A,f),h(A,"flexDirection","row"),L(f,()=>e.focus==="formats"&&e.cursor===d()?"\u203A ":" ",null),L(f,()=>e.formats.includes(u)?"[x] ":"[ ] ",null),L(f,()=>zg[u],null),de((g)=>h(f,"fg",e.focus==="formats"&&e.cursor===d()?x.accent:x.text,g)),A})()}),s),h(s,"height",1),k(o,Re("Destination")),h(a,"id","export-path-input"),h(a,"width","100%"),h(a,"onKeyDown",(u)=>{if(u.name==="escape"||u.name==="tab")u.preventDefault()}),h(l,"height",1),L(c,()=>e.error||(e.focus==="formats"?"Space toggle \xB7 Tab destination \xB7 Enter export \xB7 Esc cancel":"Tab formats \xB7 Enter export \xB7 Esc cancel")),de((u)=>{var d=Math.max(0,Math.floor((e.width-t())/2)),A=Math.max(0,Math.floor((e.height-r())/2)),f=t(),g=r(),m=x.border,p=x.panel,v=x.accent,y=x.panel,E=x.textPink,_=e.path,b=x.panelActive,w=x.panelActive,C=x.text,O=x.text,N=e.focus==="path",P=e.onPathInput,R=e.onSubmit,U=e.error?x.warning:x.accentText;return d!==u.e&&(u.e=h(n,"left",d,u.e)),A!==u.t&&(u.t=h(n,"top",A,u.t)),f!==u.a&&(u.a=h(n,"width",f,u.a)),g!==u.o&&(u.o=h(n,"height",g,u.o)),m!==u.i&&(u.i=h(n,"borderColor",m,u.i)),p!==u.n&&(u.n=h(n,"backgroundColor",p,u.n)),v!==u.s&&(u.s=h(n,"titleColor",v,u.s)),y!==u.h&&(u.h=h(i,"backgroundColor",y,u.h)),E!==u.r&&(u.r=h(o,"fg",E,u.r)),_!==u.d&&(u.d=h(a,"value",_,u.d)),b!==u.l&&(u.l=h(a,"backgroundColor",b,u.l)),w!==u.u&&(u.u=h(a,"focusedBackgroundColor",w,u.u)),C!==u.c&&(u.c=h(a,"textColor",C,u.c)),O!==u.w&&(u.w=h(a,"focusedTextColor",O,u.w)),N!==u.m&&(u.m=h(a,"focused",N,u.m)),P!==u.f&&(u.f=h(a,"onInput",P,u.f)),R!==u.y&&(u.y=h(a,"on:enter",R,u.y)),U!==u.g&&(u.g=h(c,"fg",U,u.g)),u},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0,u:void 0,c:void 0,w:void 0,m:void 0,f:void 0,y:void 0,g:void 0}),n})()}function Zr(e){let t=ht(),r=Jr(),n=Lr(),[i,s]=j(0),[o,a]=j("Ready"),[l,c]=j(!1),[u,d]=j(null),[A,f]=j(null),[g,m]=j(!1),[p,v]=j(!1),[y,E]=j(""),[_,b]=j(""),[w,C]=j(!1),[O,N]=j(["svg"]),[P,R]=j(0),[U,X]=j("formats"),[V,te]=j(""),[ge,z]=j(""),[Me,Le]=j(2),[q,Z]=j(2),[ue,pe]=j(!1),[M,re]=j(""),ie=Vl(),[oe,qe]=j($t),[me,Se]=j(sr),[gt,Ze]=j(null),et=!e.blenderLive,ee=e.blenderLive??new go(()=>e.session.toDocument()),[mt,T]=j(ee.getStatus()),Y=ee.onStatus(T);ot(()=>{if(Y(),et)ee.dispose()});let he=K(()=>n().width>=88&&n().height>=19),it=()=>i(),[Ct,Fe]=j(0),be=(B=!1)=>{if(s((I)=>I+1),B)Fe((I)=>I+1),ee.sync()},Xe=()=>(i(),e.session.dirty),Lt=K(()=>(i(),Sn(e.session.palette,e.session.paletteColorAdjustment.saturation,e.session.paletteColorAdjustment.lightness))),se=K(()=>(Ct(),Qt(e.session.grid,e.session.paletteColorAdjustment.saturation,e.session.paletteColorAdjustment.lightness))),di=K(()=>{i();let B=u(),I=e.session.tool;if(!B||!Qr(I))return;let G=e.session;return{points:G.shapePreview(I,B,G.cursor).flatMap((_e)=>Si(G.size,_e,G.mirrorX,G.mirrorY)),color:je(Lt()[G.selectedColorIndex]??G.activeColor)}}),Ft=K(()=>(i(),{grid:se(),revision:Ct(),cursor:e.session.cursor,zoom:Me(),preview:di()})),hr=K(()=>({grid:se(),revision:Ct(),yaw:oe(),pitch:me(),zoom:q()})),Gt=()=>{if(A())f(null)},Ut=(B,I)=>{if(!Qr(B))return!1;let G=u();if(!G)return d({...I}),a(`${Zt(B)} from ${I.x+1}, ${I.y+1} \xB7 Space or click to finish \xB7 Esc cancels`),be(),!0;let Ie=e.session.applyShape(B,G,I);return d(null),be(Ie),a(Ie?`${Zt(B)} drawn`:"No change"),!0},qt=()=>{if(!u())return!1;return d(null),a(`${Zt(e.session.tool)} cancelled`),be(),!0},un=(B=e.session.tool)=>{if(Gt(),Ut(B,e.session.cursor))return;let I=e.session.applyAtCursor(B);be(I),a(I?`${Zt(B)} applied`:"No change")},dn=(B,I)=>{Gt(),e.session.moveCursor(B,I);let G=gt(),Ie=G?e.session.applyAtCursor(G):!1;be(Ie),a(G&&Ie?`${Zt(G)} at ${e.session.cursor.x+1}, ${e.session.cursor.y+1}`:`Cell ${e.session.cursor.x+1}, ${e.session.cursor.y+1}`)},Ar=(B)=>{let I=B==="undo"?e.session.undo():e.session.redo();a(I?B==="undo"?"Undo":"Redo":`Nothing to ${B}`),be(I)},hn=(B)=>{e.session.selectNextColor(B),Gt(),a(`Color ${e.session.selectedColorIndex+1}`),be()},An=async()=>{if(g())return;let B=e.session.revision,I=e.session.toDocument();m(!0),a("Saving\u2026");try{let G;if(e.saveDocument)G=await e.saveDocument(I);else{let _e=e.filePath??`${e.session.filename}.flatblox.json`,pt=Dn(I);if(e.writeFile)await e.writeFile(_e,pt);else await Bun.write(_e,pt);G=`Saved ${_e}`}let Ie=e.session.markSaved(B);f(null),a(Ie?G||"Saved":`${G||"Saved"}; newer edits remain unsaved`),be()}catch(G){let Ie=G instanceof Error?G.message:String(G);a(`Save failed: ${Ie}`)}finally{m(!1)}},Ae=()=>Ti("",e.session.filename,Gn(e.filePath,e.session.filename)),we="",We=async()=>{if(g())return;let B=await ec();we=B?Ti(`${B}/`,e.session.filename,Ae()):Ae(),te(we),z(""),R(0),X("formats"),C(!0),a("Choose export formats and destination")},xe=()=>{C(!1),a("Export cancelled")},fe=(B)=>{N((I)=>I.includes(B)?I.filter((G)=>G!==B):Tt.filter((G)=>G===B||I.includes(G))),z("")},ne=async()=>{let B=O();if(B.length===0){z("Select at least one format");return}let I=Ti(V(),e.session.filename,Ae());C(!1),m(!0),a("Exporting\u2026");try{let Ie=(await Bi(e.session.toDocument(),I,B,e.writeFile)).map((_e)=>Wg(_e));if(a(`Exported ${Ie.join(", ")} to ${Gi(I)}`),Gi(I)!==Gi(we))await tc(Gi(I)).catch(()=>{})}catch(G){let Ie=G instanceof Error?G.message:String(G);a(`Export failed: ${Ie}`)}finally{m(!1)}},ae=(B)=>{let I=B.name.toLowerCase();if(I==="escape")xe();else if(I==="tab")X((G)=>G==="path"?"formats":"path");else if(U()==="path")return;else if(I==="return"||I==="enter")ne();else if(I==="up"||I==="k")R((G)=>(G+Tt.length-1)%Tt.length);else if(I==="down"||I==="j")R((G)=>(G+1)%Tt.length);else if(or(B))fe(Tt[P()])},Ge=()=>{if(e.promptForFilenameOnSave){E(""),b(""),v(!0),a("Name artwork before saving");return}An()},Ye=(B)=>{let I=In(B);if(!I){b("Enter an artwork name");return}e.session.rename(I),b(""),v(!1),be(),An()},Pe=()=>{v(!1),b(""),a("Save cancelled")},Qe=(B)=>{if(!Xe()||A()===B){if(B==="back"&&e.onBack)e.onBack();else t.destroy();return}f(B),a(B==="back"?"Unsaved changes \u2014 press Escape again to return":"Unsaved changes \u2014 press Q again to quit")},De=(B)=>{e.session.setTool(B),d(null),Gt(),a(`${Zt(B)} tool`),be()},at=(B)=>{let I=ue(),G=I?q():Me(),Ie=I?0.25:1,_e=I&&B>0&&G<1?1:G+B,pt=Math.max(Ie,Math.min(8,_e));if(I)Z(pt);else Le(pt);a(`Zoom ${pt}\xD7`)},xs=()=>{if(!ue()&&!ie){a("3D preview is unavailable on this platform");return}if(!ue()&&M()){a(`3D unavailable: ${M()}`);return}Ze(null),d(null),pe((B)=>(a(B?"2D editor":"Voxel preview"),!B))},Es=(B,I)=>{qe((G)=>G+B*0.16),Se((G)=>Math.max(0.18,Math.min(1.15,G-I*0.12))),a("3D orbit")},Ss=()=>{qe($t),Se(sr),a("Rotation reset")},Aa=(B)=>{if(re(B),!ue())return;pe(!1),a(`3D unavailable: ${B}`)},Pd=async()=>{let B=ee.getStatus();if(B.state==="connected"||B.state==="connecting"){ee.disconnect(),a("Blender Live disconnected");return}a("Connecting to Blender\u2026");let I=await ee.connect();a(I.state==="connected"?"Drawing live in Blender":I.message??"Blender Live disconnected")},Dd=(B)=>{e.session.setCursor(B.x,B.y);let I=B.tool??e.session.tool;if(Gt(),Ut(I,{x:B.x,y:B.y}))return;let G=e.session.applyAt(B.x,B.y,I);a(G?`${Zt(I)} at ${B.x+1}, ${B.y+1}`:`Cell ${B.x+1}, ${B.y+1}`),be(G)};Fr((B)=>{let I=B.name.toLowerCase(),G=B.sequence,Ie=or(B),_e=wr(I);if(B.eventType==="release"){if(Ie)Ze(null);return}if(p())return;if(w()){ae(B);return}if(l()){if(I==="escape"||G==="?")c(!1);return}let pt=I==="q"||I==="escape"||B.ctrl&&I==="c";if(A()&&!pt)f(null);if(B.ctrl){if(I==="s")Ge();else if(I==="e")We();else if(I==="z"&&B.shift)Ar("redo");else if(I==="z")Ar("undo");else if(I==="y")Ar("redo");else if(I==="c")Qe("quit");return}if(G==="?"){c(!0);return}if(I==="escape"&&qt())return;if(I==="escape"&&e.onBack){Qe("back");return}if(I==="q"||I==="escape"){Qe("quit");return}if(I==="c"){xs();return}if(ue()){if(I==="r")Ss();else if(_e)Es(_e.dx,_e.dy);else if(G==="+"||I==="+"||I==="=")at(1);else if(G==="-"||I==="-")at(-1);return}if(_e)dn(_e.dx,_e.dy);else if(Ie){let st=e.session.tool;Ze(B.source==="kitty"&&(st==="draw"||st==="erase")?st:null),un(st)}else if(I==="b")Pd();else if(I==="d")De("draw");else if(I==="e")De("erase");else if(I==="f")De("fill");else if(I==="r")De("rectangle");else if(I==="o")De("circle");else if(I==="x")e.session.toggleMirrorX(),a(`Mirror X ${e.session.mirrorX?"on":"off"}`),be();else if(I==="y")e.session.toggleMirrorY(),a(`Mirror Y ${e.session.mirrorY?"on":"off"}`),be();else if(I==="u")Ar("undo");else if(G==="+"||I==="+"||I==="=")at(1);else if(G==="-"||I==="-")at(-1);else if(G==="[")hn(-1);else if(G==="]")hn(1);else if(/^[0-9]$/.test(I))e.session.selectColor(I==="0"?9:Number(I)-1),a(`Color ${e.session.selectedColorIndex+1}`),be()},{release:!0});let Nd=()=>{i();let B=e.session.dirty?" \u25CF":"";return`${e.session.filename}${B} ${e.session.size}\xD7${e.session.size}`},Md=()=>{switch(mt().state){case"connecting":return"connecting";case"connected":return"live";case"error":return"error";default:return"off"}},fa=K(()=>`Blender:${Md()} | ${o()}`),ga=K(()=>`C ${ue()?"2D":"3D"} \xB7 ${ue()?"R reset \xB7 ":""}`+"-/+ zoom \xB7 ? help \xB7 Ctrl+S save \xB7 Ctrl+E export \xB7 "+`${e.onBack?"Esc artworks \xB7 ":""}Q quit`),Ld=K(()=>fa().length+ga().length+1<=n().width-2);return(()=>{var B=S("box"),I=S("box"),G=S("text"),Ie=S("b"),_e=S("box"),pt=S("text"),st=S("box"),Pr=S("box"),Ht=S("pixel_grid"),jt=S("box"),Is=S("text");return k(B,I),k(B,st),k(B,jt),h(B,"width","100%"),h(B,"height","100%"),h(B,"flexDirection","column"),k(I,G),k(I,_e),k(I,pt),h(I,"height",3),h(I,"paddingX",1),h(I,"paddingY",1),h(I,"flexDirection","row"),h(I,"justifyContent","space-between"),k(G,Ie),L(Ie,Fi),h(_e,"height",1),h(_e,"flexBasis",0),h(_e,"flexGrow",1),h(_e,"flexDirection","row"),h(_e,"justifyContent","center"),L(_e,Q($r,{id:"dashboard-wordmark",width:14,height:1,get backgroundColor(){return x.panel},get foregroundColor(){return x.accent}})),L(pt,Nd),k(st,Pr),h(st,"flexGrow",1),h(st,"flexDirection","row"),h(st,"paddingLeft",1),h(st,"paddingY",1),h(st,"gap",1),k(Pr,Ht),h(Pr,"flexGrow",1),h(Pr,"overflow","hidden"),L(Pr,Q(ke,{when:ie,get children(){return Q(ke,{get when(){return r()},get fallback(){return(()=>{var H=S("voxel_preview");return h(H,"id","voxel-preview"),h(H,"width","100%"),h(H,"height","100%"),h(H,"flexGrow",1),h(H,"onInitError",Aa),de((Ne)=>{var er=ue(),tr=hr();return er!==Ne.e&&(Ne.e=h(H,"visible",er,Ne.e)),tr!==Ne.t&&(Ne.t=h(H,"model",tr,Ne.t)),Ne},{e:void 0,t:void 0}),H})()},get children(){var H=S("voxel_raster");return h(H,"id","voxel-preview"),h(H,"width","100%"),h(H,"height","100%"),h(H,"flexGrow",1),h(H,"onInitError",Aa),de((Ne)=>{var er=ue(),tr=hr();return er!==Ne.e&&(Ne.e=h(H,"visible",er,Ne.e)),tr!==Ne.t&&(Ne.t=h(H,"model",tr,Ne.t)),Ne},{e:void 0,t:void 0}),H}})}}),Ht),h(Ht,"id","pixel-grid"),h(Ht,"width","100%"),h(Ht,"height","100%"),h(Ht,"flexGrow",1),h(Ht,"onCell",Dd),L(st,Q(ke,{get when(){return lt(()=>!!he())()&&!ue()},get children(){return Q(Qg,{get session(){return e.session},get colors(){return Lt()},refresh:it,visible:!0})}}),null),L(B,Q(ke,{get when(){return lt(()=>!he())()&&!ue()},get children(){return Q(Jg,{get session(){return e.session},get colors(){return Lt()},refresh:it,visible:!0})}}),jt),k(jt,Is),h(jt,"height",1),h(jt,"paddingX",1),h(jt,"flexDirection","row"),h(jt,"justifyContent","space-between"),L(Is,fa),L(jt,Q(ke,{get when(){return Ld()},get children(){var H=S("text");return L(H,ga),de((Ne)=>h(H,"fg",x.muted,Ne)),H}}),null),L(B,Q(Zg,{get width(){return n().width},get height(){return n().height},get visible(){return l()},get canGoBack(){return Boolean(e.onBack)}}),null),L(B,Q(ke,{get when(){return w()},get children(){return Q(qg,{get width(){return n().width},get height(){return n().height},get formats(){return O()},get cursor(){return P()},get focus(){return U()},get path(){return V()},get error(){return ge()},onPathInput:(H)=>{if(te(H),ge())z("")},onSubmit:()=>void ne(),onCancel:xe})}}),null),L(B,Q(ke,{get when(){return p()},get children(){return Q(Xg,{get width(){return n().width},get height(){return n().height},get value(){return y()},get error(){return _()},onInput:(H)=>{if(E(H),_())b("")},onSubmit:Ye,onCancel:Pe})}}),null),de((H)=>{var{background:Ne,panel:er}=x,tr=mt().state==="error"?x.warning:x.accentText,ma=Xe()?x.warning:x.muted,pa=he()&&!ue()?0:1,ba=x.background,ya=x.background,wa=!ue(),va=Ft(),_a=x.panelActive,Ca=o().startsWith("Save failed")||mt().state==="error"?x.warning:x.textPink;return Ne!==H.e&&(H.e=h(B,"backgroundColor",Ne,H.e)),er!==H.t&&(H.t=h(I,"backgroundColor",er,H.t)),tr!==H.a&&(H.a=h(G,"fg",tr,H.a)),ma!==H.o&&(H.o=h(pt,"fg",ma,H.o)),pa!==H.i&&(H.i=h(st,"paddingRight",pa,H.i)),ba!==H.n&&(H.n=h(st,"backgroundColor",ba,H.n)),ya!==H.s&&(H.s=h(Pr,"backgroundColor",ya,H.s)),wa!==H.h&&(H.h=h(Ht,"visible",wa,H.h)),va!==H.r&&(H.r=h(Ht,"model",va,H.r)),_a!==H.d&&(H.d=h(jt,"backgroundColor",_a,H.d)),Ca!==H.l&&(H.l=h(Is,"fg",Ca,H.l)),H},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0}),B})()}import{chmod as Yp,mkdir as Qp,readFile as Jp,rename as Vp,unlink as $p,writeFile as Zp}from"fs/promises";import{homedir as Xp}from"os";import{dirname as zp,join as ad}from"path";var Qc=Yd(Yc(),1),{__extends:Ax,__assign:fx,__rest:_r,__decorate:gx,__param:mx,__esDecorate:px,__runInitializers:bx,__propKey:yx,__setFunctionName:wx,__metadata:vx,__awaiter:Jc,__generator:_x,__exportStar:Cx,__createBinding:xx,__values:Ex,__read:Sx,__spread:Ix,__spreadArrays:kx,__spreadArray:Rx,__await:Tx,__asyncGenerator:Bx,__asyncDelegator:Ox,__asyncValues:Px,__makeTemplateObject:Dx,__importStar:Nx,__importDefault:Mx,__classPrivateFieldGet:Lx,__classPrivateFieldSet:Fx,__classPrivateFieldIn:Gx,__addDisposableResource:Ux,__disposeResources:Hx,__rewriteRelativeImportExtension:jx}=Qc.default;var Vc=(e)=>{if(e)return(...t)=>e(...t);return(...t)=>fetch(...t)};class Kn extends Error{constructor(e,t="FunctionsError",r){super(e);this.name=t,this.context=r}toJSON(){return{name:this.name,message:this.message,context:this.context}}}class Ki extends Kn{constructor(e){super("Failed to send a request to the Edge Function","FunctionsFetchError",e)}}class Wn extends Kn{constructor(e){super("Relay Error invoking the Edge Function","FunctionsRelayError",e)}}class Yn extends Kn{constructor(e){super("Edge Function returned a non-2xx status code","FunctionsHttpError",e)}}var jn;(function(e){e.Any="any",e.ApNortheast1="ap-northeast-1",e.ApNortheast2="ap-northeast-2",e.ApSouth1="ap-south-1",e.ApSoutheast1="ap-southeast-1",e.ApSoutheast2="ap-southeast-2",e.CaCentral1="ca-central-1",e.EuCentral1="eu-central-1",e.EuWest1="eu-west-1",e.EuWest2="eu-west-2",e.EuWest3="eu-west-3",e.SaEast1="sa-east-1",e.UsEast1="us-east-1",e.UsWest1="us-west-1",e.UsWest2="us-west-2"})(jn||(jn={}));class Wi{constructor(e,{headers:t={},customFetch:r,region:n=jn.Any}={}){this.url=e,this.headers=t,this.region=n,this.fetch=Vc(r)}setAuth(e){this.headers.Authorization=`Bearer ${e}`}invoke(e){return Jc(this,arguments,void 0,function*(t,r={}){var n;let i,s;try{let{headers:o,method:a,body:l,signal:c,timeout:u}=r,d={},{region:A}=r;if(!A)A=this.region;let f=new URL(`${this.url}/${t}`);if(A&&A!=="any")d["x-region"]=A,f.searchParams.set("forceFunctionRegion",A);let g;if(l&&(o&&!Object.prototype.hasOwnProperty.call(o,"Content-Type")||!o))if(typeof Blob<"u"&&l instanceof Blob||l instanceof ArrayBuffer)d["Content-Type"]="application/octet-stream",g=l;else if(typeof l==="string")d["Content-Type"]="text/plain",g=l;else if(typeof FormData<"u"&&l instanceof FormData)g=l;else d["Content-Type"]="application/json",g=JSON.stringify(l);else if(l&&typeof l!=="string"&&!(typeof Blob<"u"&&l instanceof Blob)&&!(l instanceof ArrayBuffer)&&!(typeof FormData<"u"&&l instanceof FormData))g=JSON.stringify(l);else g=l;let m=c;if(u)if(s=new AbortController,i=setTimeout(()=>s.abort(),u),c)m=s.signal,c.addEventListener("abort",()=>s.abort());else m=s.signal;let p=yield this.fetch(f.toString(),{method:a||"POST",headers:Object.assign(Object.assign(Object.assign({},d),this.headers),o),body:g,signal:m}).catch((_)=>{throw new Ki(_)}),v=p.headers.get("x-relay-error");if(v&&v==="true")throw new Wn(p);if(!p.ok)throw new Yn(p);let y=((n=p.headers.get("Content-Type"))!==null&&n!==void 0?n:"text/plain").split(";")[0].trim(),E;if(y==="application/json")E=yield p.json();else if(y==="application/octet-stream"||y==="application/pdf")E=yield p.blob();else if(y==="text/event-stream")E=p;else if(y==="multipart/form-data")E=yield p.formData();else E=yield p.text();return{data:E,error:null,response:p}}catch(o){return{data:null,error:o,response:o instanceof Yn||o instanceof Wn?o.context:void 0}}finally{if(i)clearTimeout(i)}})}}var $c=(e)=>Math.min(1000*2**e,30000),em=[520,503],qc=["GET","HEAD","OPTIONS"],eu=class extends Error{constructor(e){super(e.message);this.name="PostgrestError",this.details=e.details,this.hint=e.hint,this.code=e.code}toJSON(){return{name:this.name,message:this.message,details:this.details,hint:this.hint,code:this.code}}};function Zc(e,t){return new Promise((r)=>{if(t===null||t===void 0?void 0:t.aborted){r();return}let n=setTimeout(()=>{t===null||t===void 0||t.removeEventListener("abort",i),r()},e);function i(){clearTimeout(n),r()}t===null||t===void 0||t.addEventListener("abort",i)})}function tm(e,t,r,n){if(!n||r>=3)return!1;if(!qc.includes(e))return!1;if(!em.includes(t))return!1;return!0}var rm=class{constructor(e){var t,r,n,i,s;if(this.shouldThrowOnError=!1,this.retryEnabled=!0,this.method=e.method,this.url=e.url,this.headers=new Headers(e.headers),this.schema=e.schema,this.body=e.body,this.shouldThrowOnError=(t=e.shouldThrowOnError)!==null&&t!==void 0?t:!1,this.signal=e.signal,this.isMaybeSingle=(r=e.isMaybeSingle)!==null&&r!==void 0?r:!1,this.shouldStripNulls=(n=e.shouldStripNulls)!==null&&n!==void 0?n:!1,this.urlLengthLimit=(i=e.urlLengthLimit)!==null&&i!==void 0?i:8000,this.retryEnabled=(s=e.retry)!==null&&s!==void 0?s:!0,e.fetch)this.fetch=e.fetch;else this.fetch=fetch}throwOnError(){return this.shouldThrowOnError=!0,this}stripNulls(){if(this.headers.get("Accept")==="text/csv")throw Error("stripNulls() cannot be used with csv()");return this.shouldStripNulls=!0,this}setHeader(e,t){return this.headers=new Headers(this.headers),this.headers.set(e,t),this}retry(e){return this.retryEnabled=e,this}then(e,t){var r=this;if(this.schema===void 0);else if(["GET","HEAD"].includes(this.method))this.headers.set("Accept-Profile",this.schema);else this.headers.set("Content-Profile",this.schema);if(this.method!=="GET"&&this.method!=="HEAD")this.headers.set("Content-Type","application/json");if(this.shouldStripNulls){let o=this.headers.get("Accept");if(o==="application/vnd.pgrst.object+json")this.headers.set("Accept","application/vnd.pgrst.object+json;nulls=stripped");else if(!o||o==="application/json")this.headers.set("Accept","application/vnd.pgrst.array+json;nulls=stripped")}let n=this.fetch,s=(async()=>{let o=0;while(!0){let c=new Headers(r.headers);if(o>0)c.set("X-Retry-Count",String(o));let u;try{u=await n(r.url.toString(),{method:r.method,headers:c,body:JSON.stringify(r.body),signal:r.signal})}catch(d){if((d===null||d===void 0?void 0:d.name)==="AbortError"||(d===null||d===void 0?void 0:d.code)==="ABORT_ERR")throw d;if(!qc.includes(r.method))throw d;if(r.retryEnabled&&o<3){let A=$c(o);o++,await Zc(A,r.signal);continue}throw d}if(tm(r.method,u.status,o,r.retryEnabled)){var a,l;let d=(a=(l=u.headers)===null||l===void 0?void 0:l.get("Retry-After"))!==null&&a!==void 0?a:null,A=d!==null?Math.max(0,parseInt(d,10)||0)*1000:$c(o);await u.text(),o++,await Zc(A,r.signal);continue}return await r.processResponse(u)}})();if(!this.shouldThrowOnError)s=s.catch((o)=>{var a;let l="",c="",u="",d=o===null||o===void 0?void 0:o.cause;if(d){var A,f,g,m;let y=(A=d===null||d===void 0?void 0:d.message)!==null&&A!==void 0?A:"",E=(f=d===null||d===void 0?void 0:d.code)!==null&&f!==void 0?f:"";if(l=`${(g=o===null||o===void 0?void 0:o.name)!==null&&g!==void 0?g:"FetchError"}: ${o===null||o===void 0?void 0:o.message}`,l+=`
17
+ `)}import{RGBA as mg}from"@opentui/core";var So="Loading voxel preview\u2026",pg=mg.fromInts(175,129,202);function Di(e,t,r,n){if(t<1||r<1)return;let i=t>=So.length?So:So.slice(0,t),s=Math.max(0,Math.floor((t-i.length)/2)),o=Math.floor((r-1)/2);e.drawText(i,s,o,pg,n)}import{THREE as Ce}from"@opentui/three";var bg=1.12,yg=[0.76,0.64,1,0.42,0.9,0.72],uc=128,wg=2,dc=6710886,vg=new Uint8Array([76,76,76,255,96,96,96,255,96,96,96,255,76,76,76,255]);function _g(e,t){let r=[];for(let n of yg){let i=t?n**2.2:n;for(let s=0;s<4;s+=1)r.push(i,i,i)}e.setAttribute("color",new Ce.Float32BufferAttribute(r,3))}class Hn{scene=new Ce.Scene;camera=new Ce.OrthographicCamera(-1,1,1,-1,0.1,1000);boxGeometry=new Ce.BoxGeometry(1,1,1);boxMaterial;sceneHalfExtents=new Ce.Vector3(2,2,2);groundGeometry;groundMaterial;groundTexture;ground;worldGrid;mesh=null;model;aspect=1;sceneCenterY=0;constructor(e,t){if(this.model=e,_g(this.boxGeometry,t==="raster"),this.boxMaterial=new Ce.MeshBasicMaterial({toneMapped:!1,vertexColors:!0}),t==="raster"){this.groundGeometry=new Ce.PlaneGeometry(1,1),this.groundTexture=new Ce.DataTexture(vg,2,2),this.groundTexture.colorSpace=Ce.SRGBColorSpace,this.groundTexture.magFilter=Ce.NearestFilter,this.groundTexture.minFilter=Ce.NearestFilter,this.groundTexture.wrapS=Ce.RepeatWrapping,this.groundTexture.wrapT=Ce.RepeatWrapping,this.groundTexture.needsUpdate=!0,this.groundMaterial=new Ce.MeshBasicMaterial({map:this.groundTexture,toneMapped:!1}),this.ground=new Ce.Mesh(this.groundGeometry,this.groundMaterial),this.ground.rotation.x=-Math.PI/2,this.scene.add(this.ground),this.worldGrid=new Ce.GridHelper(uc,uc/wg,dc,dc);let r=Array.isArray(this.worldGrid.material)?this.worldGrid.material:[this.worldGrid.material];for(let n of r)n.toneMapped=!1,n.transparent=!0,n.opacity=0.06;this.scene.add(this.worldGrid)}this.rebuildMesh(),this.updateCamera()}update(e,t=this.aspect){let r=e.grid!==this.model.grid||e.revision!==this.model.revision;if(this.model=e,this.aspect=Math.max(0.25,t),r)this.rebuildMesh();this.updateCamera()}setAspect(e){this.aspect=Math.max(0.25,e),this.updateCamera()}dispose(){this.scene.clear(),this.mesh=null}rebuildMesh(){if(this.mesh)this.scene.remove(this.mesh);let e=Ri(this.model.grid),t=this.model.grid.length,r=this.model.grid.reduce((l,c)=>Math.max(l,c.length),0),n=e.reduce((l,c)=>Math.min(l,c.y-c.height/2),0),i=e.reduce((l,c)=>Math.max(l,c.y+c.height/2),0);if(this.sceneHalfExtents.set(Math.max(1,r)/2,Math.max(1,i-n)/2,Math.max(1,t)/2),this.sceneCenterY=(n+i)/2,this.ground)this.ground.position.y=n-0.04,this.ground.scale.set(Math.max(1,r),Math.max(1,t),1),this.groundTexture?.repeat.set(Math.max(1,r)/2,Math.max(1,t)/2);if(this.worldGrid)this.worldGrid.position.y=n-0.08;if(e.length===0){this.mesh=null;return}let s=new Ce.InstancedMesh(this.boxGeometry,this.boxMaterial,e.length),o=new Ce.Object3D,a=new Ce.Color;for(let l=0;l<e.length;l+=1){let c=e[l];o.position.set(c.x,c.y,c.z),o.scale.set(1,c.height,1),o.updateMatrix(),s.setMatrixAt(l,o.matrix);let u=nr(c.color)??{r:255,g:255,b:255};s.setColorAt(l,a.setRGB(u.r/255,u.g/255,u.b/255,Ce.SRGBColorSpace))}if(s.instanceMatrix.needsUpdate=!0,s.instanceColor)s.instanceColor.needsUpdate=!0;this.scene.add(s),this.mesh=s}updateCamera(){let e=new Ce.Vector3(Math.sin(this.model.yaw)*Math.cos(this.model.pitch),Math.sin(this.model.pitch),Math.cos(this.model.yaw)*Math.cos(this.model.pitch)),t=new Ce.Vector3(0,this.sceneCenterY,0);this.camera.position.copy(t).addScaledVector(e,100),this.camera.lookAt(t);let r=new Ce.Vector3(Math.sin($t)*Math.cos(sr),Math.sin(sr),Math.cos($t)*Math.cos(sr)),n=new Ce.Vector3(Math.cos($t),0,-Math.sin($t)),i=r.clone().cross(n).normalize(),s=Math.abs(n.x)*this.sceneHalfExtents.x+Math.abs(n.z)*this.sceneHalfExtents.z,o=Math.abs(i.x)*this.sceneHalfExtents.x+Math.abs(i.y)*this.sceneHalfExtents.y+Math.abs(i.z)*this.sceneHalfExtents.z,a=Math.sqrt(2/this.model.zoom),l=Math.max(1,o,s/this.aspect)*bg*a;this.camera.left=-l*this.aspect,this.camera.right=l*this.aspect,this.camera.top=l,this.camera.bottom=-l,this.camera.updateProjectionMatrix()}}function Ni(){return{grid:[],yaw:$t,pitch:sr,zoom:1}}var hc=Cg.fromInts(22,8,33),Sg=250;class Io extends Eg{currentModel;sceneController;initErrorHandler;rendererReady=!1;firstFrameDrawn=!1;destroyRequested=!1;sceneDisposed=!1;constructor(e,t){let{model:r,onInitError:n,renderer:i,...s}=t,o=r??Ni(),a=new Hn(o,"terminal");super(e,{...s,scene:a.scene,camera:a.camera,autoAspect:!1,live:!1,renderer:{backgroundColor:hc,superSample:xg.GPU,...i}});this.currentModel=o,this.sceneController=a,this.initErrorHandler=n,this.sceneController.setAspect(this.aspectRatio),setTimeout(()=>void this.warmUp(),Sg);let l=this.renderer.drawScene.bind(this.renderer);this.renderer.drawScene=async(...u)=>{if(await l(...u),!this.firstFrameDrawn)this.firstFrameDrawn=!0,this.requestRender()};let c=this.renderer.init.bind(this.renderer);this.renderer.init=async()=>{try{if(await c(),this.rendererReady=!0,this.destroyRequested)this.disposeScene()}catch(u){let d=u instanceof Error?u.message:String(u);throw this.initErrorHandler?.(d),u}}}async warmUp(){if(this.destroyRequested)return;let e=performance.now(),r=await this.ensureInitialized();if(vr("voxel preview init",e),!r||this.destroyRequested||!this.sceneController)return;let n=this.renderer,i=performance.now();await n.threeRenderer?.render(this.sceneController.scene,this.sceneController.camera),vr("voxel preview first render",i)}get model(){return this.currentModel}set model(e){this.currentModel=e,this.sceneController?.update(e,this.aspectRatio),this.requestRender()}set onInitError(e){this.initErrorHandler=e}renderSelf(e,t){if(super.renderSelf(e,t),!this.firstFrameDrawn&&this.visible)Di(e,this.width,this.height,hc)}onResize(e,t){super.onResize(e,t),this.sceneController?.setAspect(this.aspectRatio)}destroySelf(){if(this.destroyRequested=!0,super.destroySelf(),this.rendererReady)this.disposeScene()}disposeScene(){if(this.sceneDisposed)return;this.sceneDisposed=!0,this.sceneController?.dispose()}}import{NativeImage as Ig,Renderable as kg,RGBA as Rg}from"@opentui/core";import{CLICanvas as Tg,SuperSampleType as Bg,THREE as Mi}from"@opentui/three";import{createWebGPUDevice as Og,setupGlobals as Pg}from"bun-webgpu";import{WebGPURenderer as Dg}from"three/webgpu";var Li=[22,8,33],Ac=Rg.fromInts(...Li),Ng=250,fc=64,Mg=250,Lg=150,Fg=0.4;class ko extends kg{currentModel;sceneController;initErrorHandler;frame=null;device=null;canvas=null;context=null;webgpuRenderer=null;readbackBuffer=null;readbackSize=0;renderWidth=0;renderHeight=0;pending=!1;scheduled=!1;rendering=!1;failed=!1;destroyRequested=!1;warmedUp=!1;lowDetail=!1;lastModelUpdate=0;refineTimer=null;constructor(e,t){let{model:r,onInitError:n,...i}=t;super(e,{...i,buffered:!0,live:!1});this.currentModel=r??Ni(),this.sceneController=new Hn(this.currentModel,"raster"),this.initErrorHandler=n,this.scheduleRender(),setTimeout(()=>void this.warmUp(),Ng)}async warmUp(){if(this.warmedUp||this.rendering||this.failed||this.destroyRequested)return;this.rendering=!0;try{if(await this.ensureRenderer(fc,fc),this.destroyRequested)return;this.sceneController.update(this.currentModel,1);let e=performance.now();await this.webgpuRenderer.render(this.sceneController.scene,this.sceneController.camera),vr("voxel raster first render",e),this.warmedUp=!0}catch(e){this.failed=!0;let t=e instanceof Error?e.message:String(e);this.initErrorHandler?.(t)}finally{if(this.rendering=!1,this.destroyRequested)this.releaseGpu();else if(this.pending)this.scheduleRender()}}get model(){return this.currentModel}set model(e){this.currentModel=e;let t=performance.now();if(this.lowDetail=t-this.lastModelUpdate<Mg,this.lastModelUpdate=t,this.refineTimer)clearTimeout(this.refineTimer);this.refineTimer=setTimeout(()=>{if(this.refineTimer=null,!this.lowDetail)return;this.lowDetail=!1,this.scheduleRender()},Lg),this.scheduleRender()}set onInitError(e){this.initErrorHandler=e}renderSelf(e){e.clear(Ac);let t=this.frame,r=xt(this._ctx);if(!t||!r||!ir(this._ctx.capabilities)){if(!t&&!this.failed)Di(e,this.width,this.height,Ac);return}let n=Math.max(1,Math.round(this.width*r.width)),i=Math.max(1,Math.round(this.height*r.height));e.drawImage(t,0,0,this.width,this.height,n,i,0,0,t.width,t.height,"auto")}onResize(e,t){if(super.onResize(e,t),this.sceneController)this.scheduleRender()}set visible(e){if(super.visible=e,e&&this.pending)this.scheduleRender()}get visible(){return super.visible}destroySelf(){if(this.destroyRequested=!0,this.refineTimer)clearTimeout(this.refineTimer);if(this.releaseFrame(),!this.rendering)this.releaseGpu();super.destroySelf()}scheduleRender(){if(this.pending=!0,this.scheduled||this.rendering||this.failed||this.destroyRequested||!this.visible&&this.warmedUp)return;this.scheduled=!0,queueMicrotask(()=>{this.scheduled=!1,this.flushRender()})}async flushRender(){if(this.rendering||this.failed||this.destroyRequested)return;this.rendering=!0;try{while(this.pending&&!this.destroyRequested){if(!this.visible&&this.warmedUp)break;this.pending=!1,await this.renderFrame(),this.warmedUp=!0}}catch(e){this.failed=!0;let t=e instanceof Error?e.message:String(e);this.initErrorHandler?.(t)}finally{if(this.rendering=!1,this.destroyRequested)this.releaseGpu();else if(this.pending)this.scheduleRender()}}dimensions(){let e=xt(this._ctx);if(!e||this.width<=0||this.height<=0)return null;return Jl(this.width,this.height,e.width,e.height,this.lowDetail?{density:Fg}:void 0)}async renderFrame(){let e=this.dimensions();if(!e)return;if(await this.ensureRenderer(e.width,e.height),this.destroyRequested)return;this.resizeRenderer(e.width,e.height),this.sceneController.update(this.currentModel,e.width/e.height),await this.webgpuRenderer.render(this.sceneController.scene,this.sceneController.camera);let t=await this.captureFrame(e.width,e.height);if(!t)return;this.releaseFrame(),this.frame=t,this.requestRender()}async ensureRenderer(e,t){if(this.webgpuRenderer)return;let r=performance.now();await Pg();let n=await Og();vr("voxel raster device",r);let i=new Tg(n,e,t,Bg.NONE),s=new Dg({canvas:i,device:n,alpha:!0});s.outputColorSpace=Mi.SRGBColorSpace,s.toneMapping=Mi.NoToneMapping,s.setClearColor(new Mi.Color().setRGB(Li[0]/255,Li[1]/255,Li[2]/255,Mi.SRGBColorSpace),1),s.setSize(e,t,!1),await s.init(),vr("voxel raster renderer init",r),this.device=n,this.canvas=i,this.context=i.getContext("webgpu"),this.webgpuRenderer=s,this.renderWidth=e,this.renderHeight=t}resizeRenderer(e,t){if(e===this.renderWidth&&t===this.renderHeight)return;this.canvas.setSize(e,t),this.webgpuRenderer.setSize(e,t,!1),this.renderWidth=e,this.renderHeight=t,this.releaseReadback()}async captureFrame(e,t){let r=this.device,n=this.context,i=Math.ceil(e*4/256)*256,s=i*t;if(!this.readbackBuffer||this.readbackSize!==s)this.releaseReadback(),this.readbackBuffer=r.createBuffer({label:"Flatblox voxel image readback",size:s,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.readbackSize=s;let o=n.getCurrentTexture();n.switchTextures();let a=r.createCommandEncoder({label:"Flatblox voxel image capture"});if(a.copyTextureToBuffer({texture:o},{buffer:this.readbackBuffer,bytesPerRow:i,rowsPerImage:t},{width:e,height:t}),r.queue.submit([a.finish()]),await this.readbackBuffer.mapAsync(GPUMapMode.READ),this.destroyRequested)return this.readbackBuffer.unmap(),null;let l=new Uint8Array(this.readbackBuffer.getMappedRange().slice(0));this.readbackBuffer.unmap();let c=o.format,u=Ig.fromPixels(l,e,t,{stride:i,format:c==="bgra8unorm"?"bgra8":"rgba8",alpha:"opaque"});return u.ensureEncodedPng(),u}releaseFrame(){this.frame?.dispose(),this.frame=null}releaseReadback(){this.readbackBuffer?.destroy(),this.readbackBuffer=null,this.readbackSize=0}releaseGpu(){this.releaseReadback(),this.webgpuRenderer?.dispose(),this.canvas?.destroy(),this.device?.destroy(),this.webgpuRenderer=null,this.canvas=null,this.context=null,this.device=null,this.sceneController.dispose()}}var gc={name:"flatblox-tui",version:"0.2.9",description:"Flatblox pixel art editor for the terminal",homepage:"https://flatblox.com",keywords:["pixel-art","pixel art","voxel","tui","terminal","cli","editor","sprite","bun","opentui","solid","three"],author:{name:"Nico Pellerin",email:"hello@nicopellerin.io"},license:"MIT",type:"module",bin:{"flatblox-tui":"dist/index.js"},files:["dist","README.md"],publishConfig:{access:"public"},scripts:{build:"bun --env-file=../web/.env scripts/build.ts",dev:"bun --env-file=../web/.env --watch src/index.tsx",prepack:"bun run build",start:"bun --env-file=../web/.env src/index.tsx",typecheck:"tsc --noEmit",test:"bun test --preload ./scripts/preload.ts"},dependencies:{"@opentui/core":"^0.5.10","@opentui/solid":"^0.5.10","@opentui/three":"^0.5.10",bun:"^1.4.0","bun-webgpu":"0.1.7","solid-js":"1.9.12",three:"0.177.0"},devDependencies:{"@flatblox/editor-core":"workspace:*","@flatblox/shared":"workspace:*","@supabase/supabase-js":"^2.49.4","@types/bun":"latest","@types/three":"0.177.0",typescript:"~5.9.3"}};var Fi=`v${gc.version}`;import{NativeImage as mc,parseColor as Ug}from"@opentui/core";Yt({fitted_image:Ln});var Hg=new URL("./flatblox-logo.png",import.meta.url),jg=mc.load(Hg),Ro=new Map;function Kg(e){let t=Ro.get(e);if(!t)t=jg.then((r)=>{let[n,i,s]=Ug(e).toInts(),o=new Uint8Array(r.width*r.height*4);for(let l=0;l<o.length;l+=4)o[l]=n,o[l+1]=i,o[l+2]=s,o[l+3]=255;let a=mc.fromRgba(o,r.width,r.height);try{return a.composite(r)}finally{a.dispose()}}),t.catch(()=>Ro.delete(e)),Ro.set(e,t);return t}function $r(e){let t=ht(),r=Jr(),[n,i]=j(),s=!1;return gr(()=>{Kg(e.backgroundColor).then((o)=>{if(!s)i(o),t.requestRender()},()=>{})}),ot(()=>{s=!0}),Q(ke,{get when(){return lt(()=>!!r())()&&n()},get fallback(){return(()=>{var o=S("box");return h(o,"alignItems","center"),h(o,"justifyContent","center"),L(o,Q(ke,{get when(){return e.height>=2},get fallback(){return(()=>{var a=S("text"),l=S("b");return k(a,l),k(l,Re("FLATBLOX")),de((c)=>h(a,"fg",e.foregroundColor,c)),a})()},get children(){var a=S("ascii_font");return h(a,"text","FLATBLOX"),h(a,"font","tiny"),de((l)=>{var c=`${e.id}-ascii`,u=e.foregroundColor,d=e.backgroundColor;return c!==l.e&&(l.e=h(a,"id",c,l.e)),u!==l.t&&(l.t=h(a,"color",u,l.t)),d!==l.a&&(l.a=h(a,"backgroundColor",d,l.a)),l},{e:void 0,t:void 0,a:void 0}),a}})),de((a)=>{var{id:l,width:c,height:u,backgroundColor:d}=e;return l!==a.e&&(a.e=h(o,"id",l,a.e)),c!==a.t&&(a.t=h(o,"width",c,a.t)),u!==a.a&&(a.a=h(o,"height",u,a.a)),d!==a.o&&(a.o=h(o,"backgroundColor",d,a.o)),a},{e:void 0,t:void 0,a:void 0,o:void 0}),o})()},get children(){var o=S("fitted_image");return de((a)=>{var l=e.id,c=n(),u=e.width,d=e.height,A=e.backgroundColor;return l!==a.e&&(a.e=h(o,"id",l,a.e)),c!==a.t&&(a.t=h(o,"source",c,a.t)),u!==a.a&&(a.a=h(o,"width",u,a.a)),d!==a.o&&(a.o=h(o,"height",d,a.o)),A!==a.i&&(a.i=h(o,"background",A,a.i)),a},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),o}})}Yt({pixel_grid:Eo,voxel_raster:ko,voxel_preview:Io});var x={background:je("hsl(275 45% 12%)"),panel:je("hsl(275 45% 14%)"),panelActive:je("hsl(275 45% 17%)"),card:je("hsl(275 45% 19%)"),border:je("hsl(275 45% 31%)"),text:je("hsl(278 100% 80%)"),muted:je("hsl(278 41% 65%)"),accent:je("hsl(315 68% 71%)"),accentText:je("hsl(278 70% 80%)"),warning:je("hsl(37 100% 71%)"),textPink:je("hsl(308, 50%, 75%)"),orangeActive:je("hsl(28, 80%, 38%)")};function je(e){let t=nr(e);return t?En(t):"#ffffff"}function Zt(e){return e[0].toUpperCase()+e.slice(1)}function Yg(e){return(()=>{var t=S("box");return h(t,"flexDirection","column"),h(t,"gap",0),L(t,Q(wt,{get each(){return e.colors.slice(0,10)},children:(r,n)=>{let i=K(()=>(e.refresh(),e.session.selectedColorIndex===n())),s=n()===9?"0":String(n()+1);return(()=>{var o=S("box"),a=S("text"),l=Re(" ");return k(o,a),h(o,"height",1),h(o,"flexDirection","row"),h(o,"paddingX",1),L(o,Q(Fn,{get color(){return je(r)},get background(){return lt(()=>!!i())()?x.panelActive:x.panel}}),a),k(a,l),L(a,()=>i()?" \u203A ":" ",l),L(a,s,l),L(a,()=>je(r),null),de((c)=>{var u=i()?x.panelActive:x.panel,d=i()?x.text:x.muted;return u!==c.e&&(c.e=h(o,"backgroundColor",u,c.e)),d!==c.t&&(c.t=h(a,"fg",d,c.t)),c},{e:void 0,t:void 0}),o})()}})),t})()}function Qg(e){let t=K(()=>(e.refresh(),{tool:Zt(e.session.tool),mirrorX:e.session.mirrorX?"on":"off",mirrorY:e.session.mirrorY?"on":"off",cursor:`${e.session.cursor.x+1}, ${e.session.cursor.y+1}`}));return(()=>{var r=S("box"),n=S("box"),i=S("box"),s=S("text"),o=Re("Tool: "),a=S("text"),l=Re("Cursor: "),c=S("box"),u=S("box"),d=S("box"),A=S("text"),f=Re("Mirror X: "),g=S("text"),m=Re("Mirror Y: ");return k(r,n),h(r,"id","sidebar"),h(r,"flexDirection","column"),h(r,"paddingY",1),k(n,i),k(n,c),k(n,u),k(n,d),h(n,"width","100%"),h(n,"flexDirection","column"),h(n,"paddingX",1),k(i,s),k(i,a),h(i,"flexDirection","column"),k(s,o),L(s,()=>t().tool,null),k(a,l),L(a,()=>t().cursor,null),h(c,"height",1),L(n,Q(Yg,{get session(){return e.session},get colors(){return e.colors},get refresh(){return e.refresh}}),u),h(u,"height",1),k(d,A),k(d,g),h(d,"flexDirection","column"),k(A,f),L(A,()=>t().mirrorX,null),k(g,m),L(g,()=>t().mirrorY,null),de((p)=>{var v=e.visible?28:0,y=e.visible,E=x.panel,_=x.textPink,b=x.textPink,w=x.muted,C=x.muted;return v!==p.e&&(p.e=h(r,"width",v,p.e)),y!==p.t&&(p.t=h(r,"visible",y,p.t)),E!==p.a&&(p.a=h(r,"backgroundColor",E,p.a)),_!==p.o&&(p.o=h(s,"fg",_,p.o)),b!==p.i&&(p.i=h(a,"fg",b,p.i)),w!==p.n&&(p.n=h(A,"fg",w,p.n)),C!==p.s&&(p.s=h(g,"fg",C,p.s)),p},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0}),r})()}function Jg(e){let t=K(()=>{e.refresh();let r=`${e.session.mirrorX?"X":"-"}${e.session.mirrorY?"Y":"-"}`;return{tool:Zt(e.session.tool),color:je(e.colors[e.session.selectedColorIndex]??e.session.activeColor),mirror:r}});return(()=>{var r=S("box"),n=S("text"),i=Re("Tool "),s=Re(" Color "),o=S("text"),a=Re(" "),l=Re(" Mirror ");return k(r,n),k(r,o),h(r,"border",!0),h(r,"borderStyle","rounded"),h(r,"paddingX",1),h(r,"flexDirection","row"),k(n,i),k(n,s),L(n,()=>t().tool,s),L(r,Q(Fn,{get color(){return t().color},get background(){return x.panel}}),o),k(o,a),k(o,l),L(o,()=>t().color,l),L(o,()=>t().mirror,null),de((c)=>{var u=e.visible?3:0,d=e.visible,A=x.border,f=x.panel,g=x.textPink,m=x.textPink;return u!==c.e&&(c.e=h(r,"height",u,c.e)),d!==c.t&&(c.t=h(r,"visible",d,c.t)),A!==c.a&&(c.a=h(r,"borderColor",A,c.a)),f!==c.o&&(c.o=h(r,"backgroundColor",f,c.o)),g!==c.i&&(c.i=h(n,"fg",g,c.i)),m!==c.n&&(c.n=h(o,"fg",m,c.n)),c},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),r})()}var Vg=11;function $g(e){return[["Move","Arrow keys or H J K L"],["Paint","Space or Enter"],["Tools","D draw | E erase | F fill | R rectangle | O circle"],["Shapes","Space sets a corner, Space again draws, Esc cancels"],["Palette","1\u20130 direct | [ and ] cycle"],["Mirroring","X horizontal | Y vertical"],["Blender","B connect / disconnect"],["History","U undo | Ctrl+Z undo | Ctrl+Y redo"],["View","C toggle 2D / 3D | arrows orbit | R resets rotation"],["Zoom","- / +"],["Save","Ctrl+S"],["Export","Ctrl+E choose SVG / OBJ / PNG and a destination"],["Help","?"],...e?[["Artworks","Escape"],["Quit","Q"]]:[["Quit","Q or Escape"]],["",""],["Mouse","Click to paint | right-click to erase"],["","Shift+click targets the lower half-cell"],["",""],["","Press ? or Escape to close help."]]}function Zg(e){let t=K(()=>$g(e.canGoBack)),r=K(()=>Math.max(1,Math.min(70,e.width-2))),n=K(()=>Math.max(1,Math.min(t().length+4,e.height-2)));return(()=>{var i=S("box");return h(i,"id","help-overlay"),h(i,"position","absolute"),h(i,"zIndex",20),h(i,"border",!0),h(i,"title"," Keyboard & mouse "),h(i,"padding",1),L(i,Q(wt,{get each(){return t()},children:([s,o])=>(()=>{var a=S("box"),l=S("text"),c=S("text");return k(a,l),k(a,c),h(a,"flexDirection","row"),L(l,()=>s.padEnd(Vg)),L(c,o),de((u)=>{var{textPink:d,accentText:A}=x;return d!==u.e&&(u.e=h(l,"fg",d,u.e)),A!==u.t&&(u.t=h(c,"fg",A,u.t)),u},{e:void 0,t:void 0}),a})()})),de((s)=>{var o=Math.max(0,Math.floor((e.width-r())/2)),a=Math.max(0,Math.floor((e.height-n())/2)),l=r(),c=n(),u=e.visible,d=x.border,A=x.panel,f=x.accent;return o!==s.e&&(s.e=h(i,"left",o,s.e)),a!==s.t&&(s.t=h(i,"top",a,s.t)),l!==s.a&&(s.a=h(i,"width",l,s.a)),c!==s.o&&(s.o=h(i,"height",c,s.o)),u!==s.i&&(s.i=h(i,"visible",u,s.i)),d!==s.n&&(s.n=h(i,"borderColor",d,s.n)),A!==s.s&&(s.s=h(i,"backgroundColor",A,s.s)),f!==s.h&&(s.h=h(i,"titleColor",f,s.h)),s},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0}),i})()}function Xg(e){let t=K(()=>Math.max(1,Math.min(48,e.width-4))),r=K(()=>Math.max(1,Math.min(7,e.height-2))),n=K(()=>r()>=7?1:0);return(()=>{var i=S("box"),s=S("box"),o=S("input"),a=S("box"),l=S("text");return k(i,s),h(i,"id","filename-modal"),h(i,"position","absolute"),h(i,"zIndex",30),h(i,"border",!0),h(i,"title"," Save artwork "),h(i,"flexDirection","column"),k(s,o),k(s,a),k(s,l),h(s,"flexGrow",1),h(s,"width","100%"),h(s,"padding",1),h(s,"flexDirection","column"),h(o,"id","artwork-name-input"),h(o,"width","100%"),h(o,"maxLength",ro),h(o,"focused",!0),h(o,"onKeyDown",(c)=>{if(c.eventType!=="release"&&c.name==="escape")c.preventDefault(),e.onCancel()}),L(l,()=>e.error||"Enter save \xB7 Esc cancel"),de((c)=>{var u=Math.max(0,Math.floor((e.width-t())/2)),d=Math.max(0,Math.floor((e.height-r())/2)),A=t(),f=r(),g=x.border,m=x.panel,p=x.accent,v=x.panel,y=e.value,E=x.panelActive,_=x.panelActive,b=x.text,w=x.text,C=e.onInput,O=e.onSubmit,N=n(),P=e.error?x.warning:x.accentText;return u!==c.e&&(c.e=h(i,"left",u,c.e)),d!==c.t&&(c.t=h(i,"top",d,c.t)),A!==c.a&&(c.a=h(i,"width",A,c.a)),f!==c.o&&(c.o=h(i,"height",f,c.o)),g!==c.i&&(c.i=h(i,"borderColor",g,c.i)),m!==c.n&&(c.n=h(i,"backgroundColor",m,c.n)),p!==c.s&&(c.s=h(i,"titleColor",p,c.s)),v!==c.h&&(c.h=h(s,"backgroundColor",v,c.h)),y!==c.r&&(c.r=h(o,"value",y,c.r)),E!==c.d&&(c.d=h(o,"backgroundColor",E,c.d)),_!==c.l&&(c.l=h(o,"focusedBackgroundColor",_,c.l)),b!==c.u&&(c.u=h(o,"textColor",b,c.u)),w!==c.c&&(c.c=h(o,"focusedTextColor",w,c.c)),C!==c.w&&(c.w=h(o,"onInput",C,c.w)),O!==c.m&&(c.m=h(o,"on:enter",O,c.m)),N!==c.f&&(c.f=h(a,"height",N,c.f)),P!==c.y&&(c.y=h(l,"fg",P,c.y)),c},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0,u:void 0,c:void 0,w:void 0,m:void 0,f:void 0,y:void 0}),i})()}var zg={svg:"SVG flat vector",obj:"OBJ voxel mesh (+ .mtl)",png:"PNG 16px per cell"};function qg(e){let t=K(()=>Math.max(1,Math.min(66,e.width-4))),r=K(()=>Math.max(1,Math.min(12,e.height-2)));return(()=>{var n=S("box"),i=S("box"),s=S("box"),o=S("text"),a=S("input"),l=S("box"),c=S("text");return k(n,i),h(n,"id","export-modal"),h(n,"position","absolute"),h(n,"zIndex",30),h(n,"border",!0),h(n,"title"," Export artwork "),h(n,"flexDirection","column"),k(i,s),k(i,o),k(i,a),k(i,l),k(i,c),h(i,"flexGrow",1),h(i,"width","100%"),h(i,"padding",1),h(i,"flexDirection","column"),L(i,Q(wt,{each:Tt,children:(u,d)=>(()=>{var A=S("box"),f=S("text");return k(A,f),h(A,"flexDirection","row"),L(f,()=>e.focus==="formats"&&e.cursor===d()?"\u203A ":" ",null),L(f,()=>e.formats.includes(u)?"[x] ":"[ ] ",null),L(f,()=>zg[u],null),de((g)=>h(f,"fg",e.focus==="formats"&&e.cursor===d()?x.accent:x.text,g)),A})()}),s),h(s,"height",1),k(o,Re("Destination")),h(a,"id","export-path-input"),h(a,"width","100%"),h(a,"onKeyDown",(u)=>{if(u.name==="escape"||u.name==="tab")u.preventDefault()}),h(l,"height",1),L(c,()=>e.error||(e.focus==="formats"?"Space toggle \xB7 Tab destination \xB7 Enter export \xB7 Esc cancel":"Tab formats \xB7 Enter export \xB7 Esc cancel")),de((u)=>{var d=Math.max(0,Math.floor((e.width-t())/2)),A=Math.max(0,Math.floor((e.height-r())/2)),f=t(),g=r(),m=x.border,p=x.panel,v=x.accent,y=x.panel,E=x.textPink,_=e.path,b=x.panelActive,w=x.panelActive,C=x.text,O=x.text,N=e.focus==="path",P=e.onPathInput,R=e.onSubmit,U=e.error?x.warning:x.accentText;return d!==u.e&&(u.e=h(n,"left",d,u.e)),A!==u.t&&(u.t=h(n,"top",A,u.t)),f!==u.a&&(u.a=h(n,"width",f,u.a)),g!==u.o&&(u.o=h(n,"height",g,u.o)),m!==u.i&&(u.i=h(n,"borderColor",m,u.i)),p!==u.n&&(u.n=h(n,"backgroundColor",p,u.n)),v!==u.s&&(u.s=h(n,"titleColor",v,u.s)),y!==u.h&&(u.h=h(i,"backgroundColor",y,u.h)),E!==u.r&&(u.r=h(o,"fg",E,u.r)),_!==u.d&&(u.d=h(a,"value",_,u.d)),b!==u.l&&(u.l=h(a,"backgroundColor",b,u.l)),w!==u.u&&(u.u=h(a,"focusedBackgroundColor",w,u.u)),C!==u.c&&(u.c=h(a,"textColor",C,u.c)),O!==u.w&&(u.w=h(a,"focusedTextColor",O,u.w)),N!==u.m&&(u.m=h(a,"focused",N,u.m)),P!==u.f&&(u.f=h(a,"onInput",P,u.f)),R!==u.y&&(u.y=h(a,"on:enter",R,u.y)),U!==u.g&&(u.g=h(c,"fg",U,u.g)),u},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0,u:void 0,c:void 0,w:void 0,m:void 0,f:void 0,y:void 0,g:void 0}),n})()}function Zr(e){let t=ht(),r=Jr(),n=Lr(),[i,s]=j(0),[o,a]=j("Ready"),[l,c]=j(!1),[u,d]=j(null),[A,f]=j(null),[g,m]=j(!1),[p,v]=j(!1),[y,E]=j(""),[_,b]=j(""),[w,C]=j(!1),[O,N]=j(["svg"]),[P,R]=j(0),[U,X]=j("formats"),[V,te]=j(""),[ge,z]=j(""),[Me,Le]=j(2),[q,Z]=j(2),[ue,pe]=j(!1),[M,re]=j(""),ie=Vl(),[oe,qe]=j($t),[me,Se]=j(sr),[gt,Ze]=j(null),et=!e.blenderLive,ee=e.blenderLive??new go(()=>e.session.toDocument()),[mt,T]=j(ee.getStatus()),Y=ee.onStatus(T);ot(()=>{if(Y(),et)ee.dispose()});let he=K(()=>n().width>=88&&n().height>=19),it=()=>i(),[Ct,Fe]=j(0),be=(B=!1)=>{if(s((I)=>I+1),B)Fe((I)=>I+1),ee.sync()},Xe=()=>(i(),e.session.dirty),Lt=K(()=>(i(),Sn(e.session.palette,e.session.paletteColorAdjustment.saturation,e.session.paletteColorAdjustment.lightness))),se=K(()=>(Ct(),Qt(e.session.grid,e.session.paletteColorAdjustment.saturation,e.session.paletteColorAdjustment.lightness))),di=K(()=>{i();let B=u(),I=e.session.tool;if(!B||!Qr(I))return;let G=e.session;return{points:G.shapePreview(I,B,G.cursor).flatMap((_e)=>Si(G.size,_e,G.mirrorX,G.mirrorY)),color:je(Lt()[G.selectedColorIndex]??G.activeColor)}}),Ft=K(()=>(i(),{grid:se(),revision:Ct(),cursor:e.session.cursor,zoom:Me(),preview:di()})),hr=K(()=>({grid:se(),revision:Ct(),yaw:oe(),pitch:me(),zoom:q()})),Gt=()=>{if(A())f(null)},Ut=(B,I)=>{if(!Qr(B))return!1;let G=u();if(!G)return d({...I}),a(`${Zt(B)} from ${I.x+1}, ${I.y+1} \xB7 Space or click to finish \xB7 Esc cancels`),be(),!0;let Ie=e.session.applyShape(B,G,I);return d(null),be(Ie),a(Ie?`${Zt(B)} drawn`:"No change"),!0},qt=()=>{if(!u())return!1;return d(null),a(`${Zt(e.session.tool)} cancelled`),be(),!0},un=(B=e.session.tool)=>{if(Gt(),Ut(B,e.session.cursor))return;let I=e.session.applyAtCursor(B);be(I),a(I?`${Zt(B)} applied`:"No change")},dn=(B,I)=>{Gt(),e.session.moveCursor(B,I);let G=gt(),Ie=G?e.session.applyAtCursor(G):!1;be(Ie),a(G&&Ie?`${Zt(G)} at ${e.session.cursor.x+1}, ${e.session.cursor.y+1}`:`Cell ${e.session.cursor.x+1}, ${e.session.cursor.y+1}`)},Ar=(B)=>{let I=B==="undo"?e.session.undo():e.session.redo();a(I?B==="undo"?"Undo":"Redo":`Nothing to ${B}`),be(I)},hn=(B)=>{e.session.selectNextColor(B),Gt(),a(`Color ${e.session.selectedColorIndex+1}`),be()},An=async()=>{if(g())return;let B=e.session.revision,I=e.session.toDocument();m(!0),a("Saving\u2026");try{let G;if(e.saveDocument)G=await e.saveDocument(I);else{let _e=e.filePath??`${e.session.filename}.flatblox.json`,pt=Dn(I);if(e.writeFile)await e.writeFile(_e,pt);else await Bun.write(_e,pt);G=`Saved ${_e}`}let Ie=e.session.markSaved(B);f(null),a(Ie?G||"Saved":`${G||"Saved"}; newer edits remain unsaved`),be()}catch(G){let Ie=G instanceof Error?G.message:String(G);a(`Save failed: ${Ie}`)}finally{m(!1)}},Ae=()=>Ti("",e.session.filename,Gn(e.filePath,e.session.filename)),we="",We=async()=>{if(g())return;let B=await ec();we=B?Ti(`${B}/`,e.session.filename,Ae()):Ae(),te(we),z(""),R(0),X("formats"),C(!0),a("Choose export formats and destination")},xe=()=>{C(!1),a("Export cancelled")},fe=(B)=>{N((I)=>I.includes(B)?I.filter((G)=>G!==B):Tt.filter((G)=>G===B||I.includes(G))),z("")},ne=async()=>{let B=O();if(B.length===0){z("Select at least one format");return}let I=Ti(V(),e.session.filename,Ae());C(!1),m(!0),a("Exporting\u2026");try{let Ie=(await Bi(e.session.toDocument(),I,B,e.writeFile)).map((_e)=>Wg(_e));if(a(`Exported ${Ie.join(", ")} to ${Gi(I)}`),Gi(I)!==Gi(we))await tc(Gi(I)).catch(()=>{})}catch(G){let Ie=G instanceof Error?G.message:String(G);a(`Export failed: ${Ie}`)}finally{m(!1)}},ae=(B)=>{let I=B.name.toLowerCase();if(I==="escape")xe();else if(I==="tab")X((G)=>G==="path"?"formats":"path");else if(U()==="path")return;else if(I==="return"||I==="enter")ne();else if(I==="up"||I==="k")R((G)=>(G+Tt.length-1)%Tt.length);else if(I==="down"||I==="j")R((G)=>(G+1)%Tt.length);else if(or(B))fe(Tt[P()])},Ge=()=>{if(e.promptForFilenameOnSave){E(""),b(""),v(!0),a("Name artwork before saving");return}An()},Ye=(B)=>{let I=In(B);if(!I){b("Enter an artwork name");return}e.session.rename(I),b(""),v(!1),be(),An()},Pe=()=>{v(!1),b(""),a("Save cancelled")},Qe=(B)=>{if(!Xe()||A()===B){if(B==="back"&&e.onBack)e.onBack();else t.destroy();return}f(B),a(B==="back"?"Unsaved changes \u2014 press Escape again to return":"Unsaved changes \u2014 press Q again to quit")},De=(B)=>{e.session.setTool(B),d(null),Gt(),a(`${Zt(B)} tool`),be()},at=(B)=>{let I=ue(),G=I?q():Me(),Ie=I?0.25:1,_e=I&&B>0&&G<1?1:G+B,pt=Math.max(Ie,Math.min(8,_e));if(I)Z(pt);else Le(pt);a(`Zoom ${pt}\xD7`)},xs=()=>{if(!ue()&&!ie){a("3D preview is unavailable on this platform");return}if(!ue()&&M()){a(`3D unavailable: ${M()}`);return}Ze(null),d(null),pe((B)=>(a(B?"2D editor":"Voxel preview"),!B))},Es=(B,I)=>{qe((G)=>G+B*0.16),Se((G)=>Math.max(0.18,Math.min(1.15,G-I*0.12))),a("3D orbit")},Ss=()=>{qe($t),Se(sr),a("Rotation reset")},Aa=(B)=>{if(re(B),!ue())return;pe(!1),a(`3D unavailable: ${B}`)},Pd=async()=>{let B=ee.getStatus();if(B.state==="connected"||B.state==="connecting"){ee.disconnect(),a("Blender Live disconnected");return}a("Connecting to Blender\u2026");let I=await ee.connect();a(I.state==="connected"?"Drawing live in Blender":I.message??"Blender Live disconnected")},Dd=(B)=>{e.session.setCursor(B.x,B.y);let I=B.tool??e.session.tool;if(Gt(),Ut(I,{x:B.x,y:B.y}))return;let G=e.session.applyAt(B.x,B.y,I);a(G?`${Zt(I)} at ${B.x+1}, ${B.y+1}`:`Cell ${B.x+1}, ${B.y+1}`),be(G)};Fr((B)=>{let I=B.name.toLowerCase(),G=B.sequence,Ie=or(B),_e=wr(I);if(B.eventType==="release"){if(Ie)Ze(null);return}if(p())return;if(w()){ae(B);return}if(l()){if(I==="escape"||G==="?")c(!1);return}let pt=I==="q"||I==="escape"||B.ctrl&&I==="c";if(A()&&!pt)f(null);if(B.ctrl){if(I==="s")Ge();else if(I==="e")We();else if(I==="z"&&B.shift)Ar("redo");else if(I==="z")Ar("undo");else if(I==="y")Ar("redo");else if(I==="c")Qe("quit");return}if(G==="?"){c(!0);return}if(I==="escape"&&qt())return;if(I==="escape"&&e.onBack){Qe("back");return}if(I==="q"||I==="escape"){Qe("quit");return}if(I==="c"){xs();return}if(ue()){if(I==="r")Ss();else if(_e)Es(_e.dx,_e.dy);else if(G==="+"||I==="+"||I==="=")at(1);else if(G==="-"||I==="-")at(-1);return}if(_e)dn(_e.dx,_e.dy);else if(Ie){let st=e.session.tool;Ze(B.source==="kitty"&&(st==="draw"||st==="erase")?st:null),un(st)}else if(I==="b")Pd();else if(I==="d")De("draw");else if(I==="e")De("erase");else if(I==="f")De("fill");else if(I==="r")De("rectangle");else if(I==="o")De("circle");else if(I==="x")e.session.toggleMirrorX(),a(`Mirror X ${e.session.mirrorX?"on":"off"}`),be();else if(I==="y")e.session.toggleMirrorY(),a(`Mirror Y ${e.session.mirrorY?"on":"off"}`),be();else if(I==="u")Ar("undo");else if(G==="+"||I==="+"||I==="=")at(1);else if(G==="-"||I==="-")at(-1);else if(G==="[")hn(-1);else if(G==="]")hn(1);else if(/^[0-9]$/.test(I))e.session.selectColor(I==="0"?9:Number(I)-1),a(`Color ${e.session.selectedColorIndex+1}`),be()},{release:!0});let Nd=()=>{i();let B=e.session.dirty?" \u25CF":"";return`${e.session.filename}${B} ${e.session.size}\xD7${e.session.size}`},Md=()=>{switch(mt().state){case"connecting":return"connecting";case"connected":return"live";case"error":return"error";default:return"off"}},fa=K(()=>`Blender:${Md()} | ${o()}`),ga=K(()=>`C ${ue()?"2D":"3D"} \xB7 ${ue()?"R reset \xB7 ":""}`+"-/+ zoom \xB7 ? help \xB7 Ctrl+S save \xB7 Ctrl+E export \xB7 "+`${e.onBack?"Esc artworks \xB7 ":""}Q quit`),Ld=K(()=>fa().length+ga().length+1<=n().width-2);return(()=>{var B=S("box"),I=S("box"),G=S("text"),Ie=S("b"),_e=S("box"),pt=S("text"),st=S("box"),Pr=S("box"),Ht=S("pixel_grid"),jt=S("box"),Is=S("text");return k(B,I),k(B,st),k(B,jt),h(B,"width","100%"),h(B,"height","100%"),h(B,"flexDirection","column"),k(I,G),k(I,_e),k(I,pt),h(I,"height",3),h(I,"paddingX",1),h(I,"paddingY",1),h(I,"flexDirection","row"),h(I,"justifyContent","space-between"),k(G,Ie),L(Ie,Fi),h(_e,"height",1),h(_e,"flexBasis",0),h(_e,"flexGrow",1),h(_e,"flexDirection","row"),h(_e,"justifyContent","center"),L(_e,Q($r,{id:"dashboard-wordmark",width:14,height:1,get backgroundColor(){return x.panel},get foregroundColor(){return x.accent}})),L(pt,Nd),k(st,Pr),h(st,"flexGrow",1),h(st,"flexDirection","row"),h(st,"paddingLeft",1),h(st,"paddingY",1),h(st,"gap",1),k(Pr,Ht),h(Pr,"flexGrow",1),h(Pr,"overflow","hidden"),L(Pr,Q(ke,{when:ie,get children(){return Q(ke,{get when(){return r()},get fallback(){return(()=>{var H=S("voxel_preview");return h(H,"id","voxel-preview"),h(H,"width","100%"),h(H,"height","100%"),h(H,"flexGrow",1),h(H,"onInitError",Aa),de((Ne)=>{var er=ue(),tr=hr();return er!==Ne.e&&(Ne.e=h(H,"visible",er,Ne.e)),tr!==Ne.t&&(Ne.t=h(H,"model",tr,Ne.t)),Ne},{e:void 0,t:void 0}),H})()},get children(){var H=S("voxel_raster");return h(H,"id","voxel-preview"),h(H,"width","100%"),h(H,"height","100%"),h(H,"flexGrow",1),h(H,"onInitError",Aa),de((Ne)=>{var er=ue(),tr=hr();return er!==Ne.e&&(Ne.e=h(H,"visible",er,Ne.e)),tr!==Ne.t&&(Ne.t=h(H,"model",tr,Ne.t)),Ne},{e:void 0,t:void 0}),H}})}}),Ht),h(Ht,"id","pixel-grid"),h(Ht,"width","100%"),h(Ht,"height","100%"),h(Ht,"flexGrow",1),h(Ht,"onCell",Dd),L(st,Q(ke,{get when(){return lt(()=>!!he())()&&!ue()},get children(){return Q(Qg,{get session(){return e.session},get colors(){return Lt()},refresh:it,visible:!0})}}),null),L(B,Q(ke,{get when(){return lt(()=>!he())()&&!ue()},get children(){return Q(Jg,{get session(){return e.session},get colors(){return Lt()},refresh:it,visible:!0})}}),jt),k(jt,Is),h(jt,"height",1),h(jt,"paddingX",1),h(jt,"flexDirection","row"),h(jt,"justifyContent","space-between"),L(Is,fa),L(jt,Q(ke,{get when(){return Ld()},get children(){var H=S("text");return L(H,ga),de((Ne)=>h(H,"fg",x.muted,Ne)),H}}),null),L(B,Q(Zg,{get width(){return n().width},get height(){return n().height},get visible(){return l()},get canGoBack(){return Boolean(e.onBack)}}),null),L(B,Q(ke,{get when(){return w()},get children(){return Q(qg,{get width(){return n().width},get height(){return n().height},get formats(){return O()},get cursor(){return P()},get focus(){return U()},get path(){return V()},get error(){return ge()},onPathInput:(H)=>{if(te(H),ge())z("")},onSubmit:()=>void ne(),onCancel:xe})}}),null),L(B,Q(ke,{get when(){return p()},get children(){return Q(Xg,{get width(){return n().width},get height(){return n().height},get value(){return y()},get error(){return _()},onInput:(H)=>{if(E(H),_())b("")},onSubmit:Ye,onCancel:Pe})}}),null),de((H)=>{var{background:Ne,panel:er}=x,tr=mt().state==="error"?x.warning:x.accentText,ma=Xe()?x.warning:x.muted,pa=he()&&!ue()?0:1,ba=x.background,ya=x.background,wa=!ue(),va=Ft(),_a=x.panelActive,Ca=o().startsWith("Save failed")||mt().state==="error"?x.warning:x.textPink;return Ne!==H.e&&(H.e=h(B,"backgroundColor",Ne,H.e)),er!==H.t&&(H.t=h(I,"backgroundColor",er,H.t)),tr!==H.a&&(H.a=h(G,"fg",tr,H.a)),ma!==H.o&&(H.o=h(pt,"fg",ma,H.o)),pa!==H.i&&(H.i=h(st,"paddingRight",pa,H.i)),ba!==H.n&&(H.n=h(st,"backgroundColor",ba,H.n)),ya!==H.s&&(H.s=h(Pr,"backgroundColor",ya,H.s)),wa!==H.h&&(H.h=h(Ht,"visible",wa,H.h)),va!==H.r&&(H.r=h(Ht,"model",va,H.r)),_a!==H.d&&(H.d=h(jt,"backgroundColor",_a,H.d)),Ca!==H.l&&(H.l=h(Is,"fg",Ca,H.l)),H},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0}),B})()}import{chmod as Yp,mkdir as Qp,readFile as Jp,rename as Vp,unlink as $p,writeFile as Zp}from"fs/promises";import{homedir as Xp}from"os";import{dirname as zp,join as ad}from"path";var Qc=Yd(Yc(),1),{__extends:Ax,__assign:fx,__rest:_r,__decorate:gx,__param:mx,__esDecorate:px,__runInitializers:bx,__propKey:yx,__setFunctionName:wx,__metadata:vx,__awaiter:Jc,__generator:_x,__exportStar:Cx,__createBinding:xx,__values:Ex,__read:Sx,__spread:Ix,__spreadArrays:kx,__spreadArray:Rx,__await:Tx,__asyncGenerator:Bx,__asyncDelegator:Ox,__asyncValues:Px,__makeTemplateObject:Dx,__importStar:Nx,__importDefault:Mx,__classPrivateFieldGet:Lx,__classPrivateFieldSet:Fx,__classPrivateFieldIn:Gx,__addDisposableResource:Ux,__disposeResources:Hx,__rewriteRelativeImportExtension:jx}=Qc.default;var Vc=(e)=>{if(e)return(...t)=>e(...t);return(...t)=>fetch(...t)};class Kn extends Error{constructor(e,t="FunctionsError",r){super(e);this.name=t,this.context=r}toJSON(){return{name:this.name,message:this.message,context:this.context}}}class Ki extends Kn{constructor(e){super("Failed to send a request to the Edge Function","FunctionsFetchError",e)}}class Wn extends Kn{constructor(e){super("Relay Error invoking the Edge Function","FunctionsRelayError",e)}}class Yn extends Kn{constructor(e){super("Edge Function returned a non-2xx status code","FunctionsHttpError",e)}}var jn;(function(e){e.Any="any",e.ApNortheast1="ap-northeast-1",e.ApNortheast2="ap-northeast-2",e.ApSouth1="ap-south-1",e.ApSoutheast1="ap-southeast-1",e.ApSoutheast2="ap-southeast-2",e.CaCentral1="ca-central-1",e.EuCentral1="eu-central-1",e.EuWest1="eu-west-1",e.EuWest2="eu-west-2",e.EuWest3="eu-west-3",e.SaEast1="sa-east-1",e.UsEast1="us-east-1",e.UsWest1="us-west-1",e.UsWest2="us-west-2"})(jn||(jn={}));class Wi{constructor(e,{headers:t={},customFetch:r,region:n=jn.Any}={}){this.url=e,this.headers=t,this.region=n,this.fetch=Vc(r)}setAuth(e){this.headers.Authorization=`Bearer ${e}`}invoke(e){return Jc(this,arguments,void 0,function*(t,r={}){var n;let i,s;try{let{headers:o,method:a,body:l,signal:c,timeout:u}=r,d={},{region:A}=r;if(!A)A=this.region;let f=new URL(`${this.url}/${t}`);if(A&&A!=="any")d["x-region"]=A,f.searchParams.set("forceFunctionRegion",A);let g;if(l&&(o&&!Object.prototype.hasOwnProperty.call(o,"Content-Type")||!o))if(typeof Blob<"u"&&l instanceof Blob||l instanceof ArrayBuffer)d["Content-Type"]="application/octet-stream",g=l;else if(typeof l==="string")d["Content-Type"]="text/plain",g=l;else if(typeof FormData<"u"&&l instanceof FormData)g=l;else d["Content-Type"]="application/json",g=JSON.stringify(l);else if(l&&typeof l!=="string"&&!(typeof Blob<"u"&&l instanceof Blob)&&!(l instanceof ArrayBuffer)&&!(typeof FormData<"u"&&l instanceof FormData))g=JSON.stringify(l);else g=l;let m=c;if(u)if(s=new AbortController,i=setTimeout(()=>s.abort(),u),c)m=s.signal,c.addEventListener("abort",()=>s.abort());else m=s.signal;let p=yield this.fetch(f.toString(),{method:a||"POST",headers:Object.assign(Object.assign(Object.assign({},d),this.headers),o),body:g,signal:m}).catch((_)=>{throw new Ki(_)}),v=p.headers.get("x-relay-error");if(v&&v==="true")throw new Wn(p);if(!p.ok)throw new Yn(p);let y=((n=p.headers.get("Content-Type"))!==null&&n!==void 0?n:"text/plain").split(";")[0].trim(),E;if(y==="application/json")E=yield p.json();else if(y==="application/octet-stream"||y==="application/pdf")E=yield p.blob();else if(y==="text/event-stream")E=p;else if(y==="multipart/form-data")E=yield p.formData();else E=yield p.text();return{data:E,error:null,response:p}}catch(o){return{data:null,error:o,response:o instanceof Yn||o instanceof Wn?o.context:void 0}}finally{if(i)clearTimeout(i)}})}}var $c=(e)=>Math.min(1000*2**e,30000),em=[520,503],qc=["GET","HEAD","OPTIONS"],eu=class extends Error{constructor(e){super(e.message);this.name="PostgrestError",this.details=e.details,this.hint=e.hint,this.code=e.code}toJSON(){return{name:this.name,message:this.message,details:this.details,hint:this.hint,code:this.code}}};function Zc(e,t){return new Promise((r)=>{if(t===null||t===void 0?void 0:t.aborted){r();return}let n=setTimeout(()=>{t===null||t===void 0||t.removeEventListener("abort",i),r()},e);function i(){clearTimeout(n),r()}t===null||t===void 0||t.addEventListener("abort",i)})}function tm(e,t,r,n){if(!n||r>=3)return!1;if(!qc.includes(e))return!1;if(!em.includes(t))return!1;return!0}var rm=class{constructor(e){var t,r,n,i,s;if(this.shouldThrowOnError=!1,this.retryEnabled=!0,this.method=e.method,this.url=e.url,this.headers=new Headers(e.headers),this.schema=e.schema,this.body=e.body,this.shouldThrowOnError=(t=e.shouldThrowOnError)!==null&&t!==void 0?t:!1,this.signal=e.signal,this.isMaybeSingle=(r=e.isMaybeSingle)!==null&&r!==void 0?r:!1,this.shouldStripNulls=(n=e.shouldStripNulls)!==null&&n!==void 0?n:!1,this.urlLengthLimit=(i=e.urlLengthLimit)!==null&&i!==void 0?i:8000,this.retryEnabled=(s=e.retry)!==null&&s!==void 0?s:!0,e.fetch)this.fetch=e.fetch;else this.fetch=fetch}throwOnError(){return this.shouldThrowOnError=!0,this}stripNulls(){if(this.headers.get("Accept")==="text/csv")throw Error("stripNulls() cannot be used with csv()");return this.shouldStripNulls=!0,this}setHeader(e,t){return this.headers=new Headers(this.headers),this.headers.set(e,t),this}retry(e){return this.retryEnabled=e,this}then(e,t){var r=this;if(this.schema===void 0);else if(["GET","HEAD"].includes(this.method))this.headers.set("Accept-Profile",this.schema);else this.headers.set("Content-Profile",this.schema);if(this.method!=="GET"&&this.method!=="HEAD")this.headers.set("Content-Type","application/json");if(this.shouldStripNulls){let o=this.headers.get("Accept");if(o==="application/vnd.pgrst.object+json")this.headers.set("Accept","application/vnd.pgrst.object+json;nulls=stripped");else if(!o||o==="application/json")this.headers.set("Accept","application/vnd.pgrst.array+json;nulls=stripped")}let n=this.fetch,s=(async()=>{let o=0;while(!0){let c=new Headers(r.headers);if(o>0)c.set("X-Retry-Count",String(o));let u;try{u=await n(r.url.toString(),{method:r.method,headers:c,body:JSON.stringify(r.body),signal:r.signal})}catch(d){if((d===null||d===void 0?void 0:d.name)==="AbortError"||(d===null||d===void 0?void 0:d.code)==="ABORT_ERR")throw d;if(!qc.includes(r.method))throw d;if(r.retryEnabled&&o<3){let A=$c(o);o++,await Zc(A,r.signal);continue}throw d}if(tm(r.method,u.status,o,r.retryEnabled)){var a,l;let d=(a=(l=u.headers)===null||l===void 0?void 0:l.get("Retry-After"))!==null&&a!==void 0?a:null,A=d!==null?Math.max(0,parseInt(d,10)||0)*1000:$c(o);await u.text(),o++,await Zc(A,r.signal);continue}return await r.processResponse(u)}})();if(!this.shouldThrowOnError)s=s.catch((o)=>{var a;let l="",c="",u="",d=o===null||o===void 0?void 0:o.cause;if(d){var A,f,g,m;let y=(A=d===null||d===void 0?void 0:d.message)!==null&&A!==void 0?A:"",E=(f=d===null||d===void 0?void 0:d.code)!==null&&f!==void 0?f:"";if(l=`${(g=o===null||o===void 0?void 0:o.name)!==null&&g!==void 0?g:"FetchError"}: ${o===null||o===void 0?void 0:o.message}`,l+=`
18
18
 
19
19
  Caused by: ${(m=d===null||d===void 0?void 0:d.name)!==null&&m!==void 0?m:"Error"}: ${y}`,E)l+=` (${E})`;if(d===null||d===void 0?void 0:d.stack)l+=`
20
20
  ${d.stack}`}else{var p;l=(p=o===null||o===void 0?void 0:o.stack)!==null&&p!==void 0?p:""}let v=this.url.toString().length;if((o===null||o===void 0?void 0:o.name)==="AbortError"||(o===null||o===void 0?void 0:o.code)==="ABORT_ERR"){if(u="",c="Request was aborted (timeout or manual cancellation)",v>this.urlLengthLimit)c+=`. Note: Your request URL is ${v} characters, which may exceed server limits. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [many IDs])), consider using an RPC function to pass values server-side.`}else if((d===null||d===void 0?void 0:d.name)==="HeadersOverflowError"||(d===null||d===void 0?void 0:d.code)==="UND_ERR_HEADERS_OVERFLOW"){if(u="",c="HTTP headers exceeded server limits (typically 16KB)",v>this.urlLengthLimit)c+=`. Your request URL is ${v} characters. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [200+ IDs])), consider using an RPC function instead.`}return{success:!1,error:{message:`${(a=o===null||o===void 0?void 0:o.name)!==null&&a!==void 0?a:"FetchError"}: ${o===null||o===void 0?void 0:o.message}`,details:l,hint:c,code:u},data:null,count:null,status:0,statusText:""}});return s.then(e,t)}async processResponse(e){var t=this;let r=null,n=null,i=null,s=e.status,o=e.statusText;if(e.ok){var a,l;if(t.method!=="HEAD"){var c;let A=await e.text();if(A==="");else if(t.headers.get("Accept")==="text/csv")n=A;else if(t.headers.get("Accept")&&((c=t.headers.get("Accept"))===null||c===void 0?void 0:c.includes("application/vnd.pgrst.plan+text")))n=A;else n=JSON.parse(A)}let u=(a=t.headers.get("Prefer"))===null||a===void 0?void 0:a.match(/count=(exact|planned|estimated)/),d=(l=e.headers.get("content-range"))===null||l===void 0?void 0:l.split("/");if(u&&d&&d.length>1)i=parseInt(d[1]);if(t.isMaybeSingle&&Array.isArray(n))if(n.length>1)r={code:"PGRST116",details:`Results contain ${n.length} rows, application/vnd.pgrst.object+json requires 1 row`,hint:null,message:"JSON object requested, multiple (or no) rows returned"},n=null,i=null,s=406,o="Not Acceptable";else if(n.length===1)n=n[0];else n=null}else{let u=await e.text();try{if(r=JSON.parse(u),Array.isArray(r)&&e.status===404)n=[],r=null,s=200,o="OK"}catch(d){if(e.status===404&&u==="")s=204,o="No Content";else r={message:u}}if(r&&t.shouldThrowOnError)throw new eu(r)}return{success:r===null,error:r,data:n,count:i,status:s,statusText:o}}returns(){return this}overrideTypes(){return this}},nm=class extends rm{select(e){let t=!1,r=(e!==null&&e!==void 0?e:"*").split("").map((n)=>{if(/\s/.test(n)&&!t)return"";if(n==='"')t=!t;return n}).join("");return this.url.searchParams.set("select",r),this.headers.append("Prefer","return=representation"),this}order(e,{ascending:t=!0,nullsFirst:r,foreignTable:n,referencedTable:i=n}={}){let s=i?`${i}.order`:"order",o=this.url.searchParams.get(s);return this.url.searchParams.set(s,`${o?`${o},`:""}${e}.${t?"asc":"desc"}${r===void 0?"":r?".nullsfirst":".nullslast"}`),this}limit(e,{foreignTable:t,referencedTable:r=t}={}){let n=typeof r>"u"?"limit":`${r}.limit`;return this.url.searchParams.set(n,`${e}`),this}range(e,t,{foreignTable:r,referencedTable:n=r}={}){let i=typeof n>"u"?"offset":`${n}.offset`,s=typeof n>"u"?"limit":`${n}.limit`;return this.url.searchParams.set(i,`${e}`),this.url.searchParams.set(s,`${t-e+1}`),this}abortSignal(e){return this.signal=e,this}single(){return this.headers.set("Accept","application/vnd.pgrst.object+json"),this}maybeSingle(){return this.isMaybeSingle=!0,this}csv(){return this.headers.set("Accept","text/csv"),this}geojson(){return this.headers.set("Accept","application/geo+json"),this}explain({analyze:e=!1,verbose:t=!1,settings:r=!1,buffers:n=!1,wal:i=!1,format:s="text"}={}){var o;let a=[e?"analyze":null,t?"verbose":null,r?"settings":null,n?"buffers":null,i?"wal":null].filter(Boolean).join("|"),l=(o=this.headers.get("Accept"))!==null&&o!==void 0?o:"application/json";if(this.headers.set("Accept",`application/vnd.pgrst.plan+${s}; for="${l}"; options=${a};`),s==="json")return this;else return this}rollback(){return this.headers.append("Prefer","tx=rollback"),this}returns(){return this}maxAffected(e){return this.headers.append("Prefer","handling=strict"),this.headers.append("Prefer",`max-affected=${e}`),this}},Xc=new RegExp("[,()]"),zr=class extends nm{eq(e,t){return this.url.searchParams.append(e,`eq.${t}`),this}neq(e,t){return this.url.searchParams.append(e,`neq.${t}`),this}gt(e,t){return this.url.searchParams.append(e,`gt.${t}`),this}gte(e,t){return this.url.searchParams.append(e,`gte.${t}`),this}lt(e,t){return this.url.searchParams.append(e,`lt.${t}`),this}lte(e,t){return this.url.searchParams.append(e,`lte.${t}`),this}like(e,t){return this.url.searchParams.append(e,`like.${t}`),this}likeAllOf(e,t){return this.url.searchParams.append(e,`like(all).{${t.join(",")}}`),this}likeAnyOf(e,t){return this.url.searchParams.append(e,`like(any).{${t.join(",")}}`),this}ilike(e,t){return this.url.searchParams.append(e,`ilike.${t}`),this}ilikeAllOf(e,t){return this.url.searchParams.append(e,`ilike(all).{${t.join(",")}}`),this}ilikeAnyOf(e,t){return this.url.searchParams.append(e,`ilike(any).{${t.join(",")}}`),this}regexMatch(e,t){return this.url.searchParams.append(e,`match.${t}`),this}regexIMatch(e,t){return this.url.searchParams.append(e,`imatch.${t}`),this}is(e,t){return this.url.searchParams.append(e,`is.${t}`),this}isDistinct(e,t){return this.url.searchParams.append(e,`isdistinct.${t}`),this}in(e,t){let r=Array.from(new Set(t)).map((n)=>{if(typeof n==="string"&&Xc.test(n))return`"${n}"`;else return`${n}`}).join(",");return this.url.searchParams.append(e,`in.(${r})`),this}notIn(e,t){let r=Array.from(new Set(t)).map((n)=>{if(typeof n==="string"&&Xc.test(n))return`"${n}"`;else return`${n}`}).join(",");return this.url.searchParams.append(e,`not.in.(${r})`),this}contains(e,t){if(typeof t==="string")this.url.searchParams.append(e,`cs.${t}`);else if(Array.isArray(t))this.url.searchParams.append(e,`cs.{${t.join(",")}}`);else this.url.searchParams.append(e,`cs.${JSON.stringify(t)}`);return this}containedBy(e,t){if(typeof t==="string")this.url.searchParams.append(e,`cd.${t}`);else if(Array.isArray(t))this.url.searchParams.append(e,`cd.{${t.join(",")}}`);else this.url.searchParams.append(e,`cd.${JSON.stringify(t)}`);return this}rangeGt(e,t){return this.url.searchParams.append(e,`sr.${t}`),this}rangeGte(e,t){return this.url.searchParams.append(e,`nxl.${t}`),this}rangeLt(e,t){return this.url.searchParams.append(e,`sl.${t}`),this}rangeLte(e,t){return this.url.searchParams.append(e,`nxr.${t}`),this}rangeAdjacent(e,t){return this.url.searchParams.append(e,`adj.${t}`),this}overlaps(e,t){if(typeof t==="string")this.url.searchParams.append(e,`ov.${t}`);else this.url.searchParams.append(e,`ov.{${t.join(",")}}`);return this}textSearch(e,t,{config:r,type:n}={}){let i="";if(n==="plain")i="pl";else if(n==="phrase")i="ph";else if(n==="websearch")i="w";let s=r===void 0?"":`(${r})`;return this.url.searchParams.append(e,`${i}fts${s}.${t}`),this}match(e){return Object.entries(e).filter(([t,r])=>r!==void 0).forEach(([t,r])=>{this.url.searchParams.append(t,`eq.${r}`)}),this}not(e,t,r){return this.url.searchParams.append(e,`not.${t}.${r}`),this}or(e,{foreignTable:t,referencedTable:r=t}={}){let n=r?`${r}.or`:"or";return this.url.searchParams.append(n,`(${e})`),this}filter(e,t,r){return this.url.searchParams.append(e,`${t}.${r}`),this}},im=class{constructor(e,{headers:t={},schema:r,fetch:n,urlLengthLimit:i=8000,retry:s}){this.url=e,this.headers=new Headers(t),this.schema=r,this.fetch=n,this.urlLengthLimit=i,this.retry=s}cloneRequestState(){return{url:new URL(this.url.toString()),headers:new Headers(this.headers)}}select(e,t){let{head:r=!1,count:n}=t!==null&&t!==void 0?t:{},i=r?"HEAD":"GET",s=!1,o=(e!==null&&e!==void 0?e:"*").split("").map((c)=>{if(/\s/.test(c)&&!s)return"";if(c==='"')s=!s;return c}).join(""),{url:a,headers:l}=this.cloneRequestState();if(a.searchParams.set("select",o),n)l.append("Prefer",`count=${n}`);return new zr({method:i,url:a,headers:l,schema:this.schema,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}insert(e,{count:t,defaultToNull:r=!0}={}){var n;let i="POST",{url:s,headers:o}=this.cloneRequestState();if(t)o.append("Prefer",`count=${t}`);if(!r)o.append("Prefer","missing=default");if(Array.isArray(e)){let a=e.reduce((l,c)=>l.concat(Object.keys(c)),[]);if(a.length>0){let l=[...new Set(a)].map((c)=>`"${c}"`);s.searchParams.set("columns",l.join(","))}}return new zr({method:"POST",url:s,headers:o,schema:this.schema,body:e,fetch:(n=this.fetch)!==null&&n!==void 0?n:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}upsert(e,{onConflict:t,ignoreDuplicates:r=!1,count:n,defaultToNull:i=!0}={}){var s;let o="POST",{url:a,headers:l}=this.cloneRequestState();if(l.append("Prefer",`resolution=${r?"ignore":"merge"}-duplicates`),t!==void 0)a.searchParams.set("on_conflict",t);if(n)l.append("Prefer",`count=${n}`);if(!i)l.append("Prefer","missing=default");if(Array.isArray(e)){let c=e.reduce((u,d)=>u.concat(Object.keys(d)),[]);if(c.length>0){let u=[...new Set(c)].map((d)=>`"${d}"`);a.searchParams.set("columns",u.join(","))}}return new zr({method:"POST",url:a,headers:l,schema:this.schema,body:e,fetch:(s=this.fetch)!==null&&s!==void 0?s:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}update(e,{count:t}={}){var r;let n="PATCH",{url:i,headers:s}=this.cloneRequestState();if(t)s.append("Prefer",`count=${t}`);return new zr({method:"PATCH",url:i,headers:s,schema:this.schema,body:e,fetch:(r=this.fetch)!==null&&r!==void 0?r:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}delete({count:e}={}){var t;let r="DELETE",{url:n,headers:i}=this.cloneRequestState();if(e)i.append("Prefer",`count=${e}`);return new zr({method:"DELETE",url:n,headers:i,schema:this.schema,fetch:(t=this.fetch)!==null&&t!==void 0?t:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};function Qn(e){return Qn=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Qn(e)}function sm(e,t){if(Qn(e)!="object"||!e)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var n=r.call(e,t||"default");if(Qn(n)!="object")return n;throw TypeError("@@toPrimitive must return a primitive value.")}return(t==="string"?String:Number)(e)}function om(e){var t=sm(e,"string");return Qn(t)=="symbol"?t:t+""}function am(e,t,r){return(t=om(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function zc(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),r.push.apply(r,n)}return r}function Yi(e){for(var t=1;t<arguments.length;t++){var r=arguments[t]!=null?arguments[t]:{};t%2?zc(Object(r),!0).forEach(function(n){am(e,n,r[n])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):zc(Object(r)).forEach(function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))})}return e}var tu=class e{constructor(t,{headers:r={},schema:n,fetch:i,timeout:s,urlLengthLimit:o=8000,retry:a}={}){this.url=t,this.headers=new Headers(r),this.schemaName=n,this.urlLengthLimit=o;let l=i!==null&&i!==void 0?i:globalThis.fetch;if(s!==void 0&&s>0)this.fetch=(c,u)=>{let d=new AbortController,A=setTimeout(()=>d.abort(),s),f=u===null||u===void 0?void 0:u.signal;if(f){if(f.aborted)return clearTimeout(A),l(c,u);let g=()=>{clearTimeout(A),d.abort()};return f.addEventListener("abort",g,{once:!0}),l(c,Yi(Yi({},u),{},{signal:d.signal})).finally(()=>{clearTimeout(A),f.removeEventListener("abort",g)})}return l(c,Yi(Yi({},u),{},{signal:d.signal})).finally(()=>clearTimeout(A))};else this.fetch=l;this.retry=a}from(t){if(!t||typeof t!=="string"||t.trim()==="")throw Error("Invalid relation name: relation must be a non-empty string.");return new im(new URL(`${this.url}/${t}`),{headers:new Headers(this.headers),schema:this.schemaName,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}schema(t){return new e(this.url,{headers:this.headers,schema:t,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}rpc(t,r={},{head:n=!1,get:i=!1,count:s}={}){var o;let a,l=new URL(`${this.url}/rpc/${t}`),c,u=(f)=>f!==null&&typeof f==="object"&&(!Array.isArray(f)||f.some(u)),d=n&&Object.values(r).some(u);if(d)a="POST",c=r;else if(n||i)a=n?"HEAD":"GET",Object.entries(r).filter(([f,g])=>g!==void 0).map(([f,g])=>[f,Array.isArray(g)?`{${g.join(",")}}`:`${g}`]).forEach(([f,g])=>{l.searchParams.append(f,g)});else a="POST",c=r;let A=new Headers(this.headers);if(d)A.set("Prefer",s?`count=${s},return=minimal`:"return=minimal");else if(s)A.set("Prefer",`count=${s}`);return new zr({method:a,url:l,headers:A,schema:this.schemaName,body:c,fetch:(o=this.fetch)!==null&&o!==void 0?o:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};class ru{constructor(){}static detectEnvironment(){var e;if(typeof WebSocket<"u")return{type:"native",constructor:WebSocket};if(typeof globalThis<"u"&&typeof globalThis.WebSocket<"u")return{type:"native",constructor:globalThis.WebSocket};if(typeof global<"u"&&typeof global.WebSocket<"u")return{type:"native",constructor:global.WebSocket};if(typeof globalThis<"u"&&typeof globalThis.WebSocketPair<"u"&&typeof globalThis.WebSocket>"u")return{type:"cloudflare",error:"Cloudflare Workers detected. WebSocket clients are not supported in Cloudflare Workers.",workaround:"Use Cloudflare Workers WebSocket API for server-side WebSocket handling, or deploy to a different runtime."};if(typeof globalThis<"u"&&globalThis.EdgeRuntime||typeof navigator<"u"&&((e=navigator.userAgent)===null||e===void 0?void 0:e.includes("Vercel-Edge")))return{type:"unsupported",error:"Edge runtime detected (Vercel Edge/Netlify Edge). WebSockets are not supported in edge functions.",workaround:"Use serverless functions or a different deployment target for WebSocket functionality."};let t=globalThis.process;if(t){let r=t.versions;if(r&&r.node){let n=r.node,i=parseInt(n.replace(/^v/,"").split(".")[0]);if(i>=22){if(typeof globalThis.WebSocket<"u")return{type:"native",constructor:globalThis.WebSocket};return{type:"unsupported",error:`Node.js ${i} detected but native WebSocket not found.`,workaround:"Provide a WebSocket implementation via the transport option."}}return{type:"unsupported",error:`Node.js ${i} detected without native WebSocket support.`,workaround:`For Node.js < 22, install "ws" package and provide it via the transport option:
package/package.json CHANGED
@@ -1,8 +1,26 @@
1
1
  {
2
2
  "name": "flatblox-tui",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Flatblox pixel art editor for the terminal",
5
5
  "homepage": "https://flatblox.com",
6
+ "keywords": [
7
+ "pixel-art",
8
+ "pixel art",
9
+ "voxel",
10
+ "tui",
11
+ "terminal",
12
+ "cli",
13
+ "editor",
14
+ "sprite",
15
+ "bun",
16
+ "opentui",
17
+ "solid",
18
+ "three"
19
+ ],
20
+ "author": {
21
+ "name": "Nico Pellerin",
22
+ "email": "hello@nicopellerin.io"
23
+ },
6
24
  "license": "MIT",
7
25
  "type": "module",
8
26
  "bin": {