@primitiv/client 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,204 @@
1
+ "use strict";var W=Object.defineProperty;var nt=Object.getOwnPropertyDescriptor;var ot=Object.getOwnPropertyNames;var ht=Object.prototype.hasOwnProperty;var lt=(t,e)=>{for(var i in e)W(t,i,{get:e[i],enumerable:!0})},ct=(t,e,i,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of ot(e))!ht.call(t,a)&&a!==i&&W(t,a,{get:()=>e[a],enumerable:!(s=nt(e,a))||s.enumerable});return t};var dt=t=>ct(W({},"__esModule",{value:!0}),t);var jt={};lt(jt,{AutoplayOverlay:()=>zt,DEFAULT_PALETTE:()=>G,GridOverlay:()=>F,ImageFontAtlas:()=>X,PostProcessOverlay:()=>_t,ScalingMode:()=>m,Terminal2D:()=>Xt,TerminalANSI:()=>$t,TerminalGL:()=>Gt,colorToPaletteIndex:()=>Wt,createTestRenderState:()=>qt,getAtlasColumns:()=>B,getAtlasDimensions:()=>Ot,getCharGridPosition:()=>Y,getMaxCharCode:()=>L,hexToRGB:()=>Vt,paletteIndexToColor:()=>Yt,rgbToHex:()=>Kt});module.exports=dt(jt);var ut=(t=>(t[t.Keyboard=0]="Keyboard",t[t.Mouse=1]="Mouse",t[t.Gamepad=2]="Gamepad",t[t.Touch=3]="Touch",t[t.TVRemote=4]="TVRemote",t[t.TextInput=5]="TextInput",t[t.Motion=6]="Motion",t[t.TouchZone=7]="TouchZone",t))(ut||{}),ft=(t=>(t[t.KeyA=0]="KeyA",t[t.KeyB=1]="KeyB",t[t.KeyC=2]="KeyC",t[t.KeyD=3]="KeyD",t[t.KeyE=4]="KeyE",t[t.KeyF=5]="KeyF",t[t.KeyG=6]="KeyG",t[t.KeyH=7]="KeyH",t[t.KeyI=8]="KeyI",t[t.KeyJ=9]="KeyJ",t[t.KeyK=10]="KeyK",t[t.KeyL=11]="KeyL",t[t.KeyM=12]="KeyM",t[t.KeyN=13]="KeyN",t[t.KeyO=14]="KeyO",t[t.KeyP=15]="KeyP",t[t.KeyQ=16]="KeyQ",t[t.KeyR=17]="KeyR",t[t.KeyS=18]="KeyS",t[t.KeyT=19]="KeyT",t[t.KeyU=20]="KeyU",t[t.KeyV=21]="KeyV",t[t.KeyW=22]="KeyW",t[t.KeyX=23]="KeyX",t[t.KeyY=24]="KeyY",t[t.KeyZ=25]="KeyZ",t[t.Digit0=26]="Digit0",t[t.Digit1=27]="Digit1",t[t.Digit2=28]="Digit2",t[t.Digit3=29]="Digit3",t[t.Digit4=30]="Digit4",t[t.Digit5=31]="Digit5",t[t.Digit6=32]="Digit6",t[t.Digit7=33]="Digit7",t[t.Digit8=34]="Digit8",t[t.Digit9=35]="Digit9",t[t.ArrowUp=36]="ArrowUp",t[t.ArrowDown=37]="ArrowDown",t[t.ArrowLeft=38]="ArrowLeft",t[t.ArrowRight=39]="ArrowRight",t[t.Space=40]="Space",t[t.Enter=41]="Enter",t[t.Escape=42]="Escape",t[t.Backspace=43]="Backspace",t[t.Tab=44]="Tab",t[t.ShiftLeft=45]="ShiftLeft",t[t.ShiftRight=46]="ShiftRight",t[t.ControlLeft=47]="ControlLeft",t[t.ControlRight=48]="ControlRight",t[t.AltLeft=49]="AltLeft",t[t.AltRight=50]="AltRight",t[t.MetaLeft=51]="MetaLeft",t[t.MetaRight=52]="MetaRight",t[t.CapsLock=53]="CapsLock",t[t.Delete=54]="Delete",t[t.Insert=55]="Insert",t[t.Home=56]="Home",t[t.End=57]="End",t[t.PageUp=58]="PageUp",t[t.PageDown=59]="PageDown",t[t.F1=60]="F1",t[t.F2=61]="F2",t[t.F3=62]="F3",t[t.F4=63]="F4",t[t.F5=64]="F5",t[t.F6=65]="F6",t[t.F7=66]="F7",t[t.F8=67]="F8",t[t.F9=68]="F9",t[t.F10=69]="F10",t[t.F11=70]="F11",t[t.F12=71]="F12",t[t.Minus=72]="Minus",t[t.Equal=73]="Equal",t[t.BracketLeft=74]="BracketLeft",t[t.BracketRight=75]="BracketRight",t[t.Backslash=76]="Backslash",t[t.Semicolon=77]="Semicolon",t[t.Quote=78]="Quote",t[t.Comma=79]="Comma",t[t.Period=80]="Period",t[t.Slash=81]="Slash",t[t.Backquote=82]="Backquote",t[t.Numpad0=91]="Numpad0",t[t.Numpad1=92]="Numpad1",t[t.Numpad2=93]="Numpad2",t[t.Numpad3=94]="Numpad3",t[t.Numpad4=95]="Numpad4",t[t.Numpad5=96]="Numpad5",t[t.Numpad6=97]="Numpad6",t[t.Numpad7=98]="Numpad7",t[t.Numpad8=99]="Numpad8",t[t.Numpad9=100]="Numpad9",t[t.NumpadAdd=101]="NumpadAdd",t[t.NumpadSubtract=102]="NumpadSubtract",t[t.NumpadMultiply=103]="NumpadMultiply",t[t.NumpadDivide=104]="NumpadDivide",t[t.NumpadDecimal=105]="NumpadDecimal",t[t.NumpadEnter=106]="NumpadEnter",t[t.NumLock=107]="NumLock",t[t.PrintScreen=111]="PrintScreen",t[t.ScrollLock=112]="ScrollLock",t[t.Pause=113]="Pause",t[t.ContextMenu=114]="ContextMenu",t))(ft||{});var gt=(t=>(t[t.LeftButton=0]="LeftButton",t[t.MiddleButton=1]="MiddleButton",t[t.RightButton=2]="RightButton",t[t.Button4=3]="Button4",t[t.Button5=4]="Button5",t[t.PositionX=100]="PositionX",t[t.PositionY=101]="PositionY",t[t.DeltaX=102]="DeltaX",t[t.DeltaY=103]="DeltaY",t[t.WheelDeltaY=104]="WheelDeltaY",t[t.WheelDeltaX=105]="WheelDeltaX",t))(gt||{});var pt=(t=>(t[t.ButtonA=0]="ButtonA",t[t.ButtonB=1]="ButtonB",t[t.ButtonX=2]="ButtonX",t[t.ButtonY=3]="ButtonY",t[t.LeftShoulder=4]="LeftShoulder",t[t.RightShoulder=5]="RightShoulder",t[t.LeftTrigger=6]="LeftTrigger",t[t.RightTrigger=7]="RightTrigger",t[t.Select=8]="Select",t[t.Start=9]="Start",t[t.LeftStick=10]="LeftStick",t[t.RightStick=11]="RightStick",t[t.DPadUp=12]="DPadUp",t[t.DPadDown=13]="DPadDown",t[t.DPadLeft=14]="DPadLeft",t[t.DPadRight=15]="DPadRight",t[t.Home=16]="Home",t[t.Touchpad=17]="Touchpad",t[t.LeftStickX=100]="LeftStickX",t[t.LeftStickY=101]="LeftStickY",t[t.RightStickX=102]="RightStickX",t[t.RightStickY=103]="RightStickY",t[t.LeftTriggerAxis=104]="LeftTriggerAxis",t[t.RightTriggerAxis=105]="RightTriggerAxis",t))(pt||{});var mt=(t=>(t[t.Touch0=0]="Touch0",t[t.Touch1=1]="Touch1",t[t.Touch2=2]="Touch2",t[t.Touch3=3]="Touch3",t[t.Touch4=4]="Touch4",t[t.Touch5=5]="Touch5",t[t.Touch6=6]="Touch6",t[t.Touch7=7]="Touch7",t[t.Touch8=8]="Touch8",t[t.Touch9=9]="Touch9",t[t.Touch0X=100]="Touch0X",t[t.Touch0Y=101]="Touch0Y",t[t.Touch1X=102]="Touch1X",t[t.Touch1Y=103]="Touch1Y",t[t.Touch2X=104]="Touch2X",t[t.Touch2Y=105]="Touch2Y",t[t.Touch3X=106]="Touch3X",t[t.Touch3Y=107]="Touch3Y",t[t.Touch4X=108]="Touch4X",t[t.Touch4Y=109]="Touch4Y",t[t.Touch5X=110]="Touch5X",t[t.Touch5Y=111]="Touch5Y",t[t.Touch6X=112]="Touch6X",t[t.Touch6Y=113]="Touch6Y",t[t.Touch7X=114]="Touch7X",t[t.Touch7Y=115]="Touch7Y",t[t.Touch8X=116]="Touch8X",t[t.Touch8Y=117]="Touch8Y",t[t.Touch9X=118]="Touch9X",t[t.Touch9Y=119]="Touch9Y",t[t.PinchScale=200]="PinchScale",t[t.RotationAngle=201]="RotationAngle",t[t.SwipeVelocityX=202]="SwipeVelocityX",t[t.SwipeVelocityY=203]="SwipeVelocityY",t))(mt||{});var xt=(t=>(t[t.Zone0=0]="Zone0",t[t.Zone1=1]="Zone1",t[t.Zone2=2]="Zone2",t[t.Zone3=3]="Zone3",t[t.Zone4=4]="Zone4",t[t.Zone5=5]="Zone5",t[t.Zone6=6]="Zone6",t[t.Zone7=7]="Zone7",t[t.Zone8=8]="Zone8",t[t.Zone9=9]="Zone9",t[t.Zone10=10]="Zone10",t[t.Zone11=11]="Zone11",t[t.Zone12=12]="Zone12",t[t.Zone13=13]="Zone13",t[t.Zone14=14]="Zone14",t[t.Zone15=15]="Zone15",t[t.Zone16=16]="Zone16",t[t.Zone17=17]="Zone17",t[t.Zone18=18]="Zone18",t[t.Zone19=19]="Zone19",t[t.Zone20=20]="Zone20",t[t.Zone21=21]="Zone21",t[t.Zone22=22]="Zone22",t[t.Zone23=23]="Zone23",t[t.Zone24=24]="Zone24",t[t.Zone25=25]="Zone25",t[t.Zone26=26]="Zone26",t[t.Zone27=27]="Zone27",t[t.Zone28=28]="Zone28",t[t.Zone29=29]="Zone29",t[t.Zone30=30]="Zone30",t[t.Zone31=31]="Zone31",t[t.Zone0X=100]="Zone0X",t[t.Zone0Y=101]="Zone0Y",t[t.Zone1X=102]="Zone1X",t[t.Zone1Y=103]="Zone1Y",t[t.Zone2X=104]="Zone2X",t[t.Zone2Y=105]="Zone2Y",t[t.Zone3X=106]="Zone3X",t[t.Zone3Y=107]="Zone3Y",t[t.Zone4X=108]="Zone4X",t[t.Zone4Y=109]="Zone4Y",t[t.Zone5X=110]="Zone5X",t[t.Zone5Y=111]="Zone5Y",t[t.Zone6X=112]="Zone6X",t[t.Zone6Y=113]="Zone6Y",t[t.Zone7X=114]="Zone7X",t[t.Zone7Y=115]="Zone7Y",t[t.Zone8X=116]="Zone8X",t[t.Zone8Y=117]="Zone8Y",t[t.Zone9X=118]="Zone9X",t[t.Zone9Y=119]="Zone9Y",t[t.Zone10X=120]="Zone10X",t[t.Zone10Y=121]="Zone10Y",t[t.Zone11X=122]="Zone11X",t[t.Zone11Y=123]="Zone11Y",t[t.Zone12X=124]="Zone12X",t[t.Zone12Y=125]="Zone12Y",t[t.Zone13X=126]="Zone13X",t[t.Zone13Y=127]="Zone13Y",t[t.Zone14X=128]="Zone14X",t[t.Zone14Y=129]="Zone14Y",t[t.Zone15X=130]="Zone15X",t[t.Zone15Y=131]="Zone15Y",t[t.Zone16X=132]="Zone16X",t[t.Zone16Y=133]="Zone16Y",t[t.Zone17X=134]="Zone17X",t[t.Zone17Y=135]="Zone17Y",t[t.Zone18X=136]="Zone18X",t[t.Zone18Y=137]="Zone18Y",t[t.Zone19X=138]="Zone19X",t[t.Zone19Y=139]="Zone19Y",t[t.Zone20X=140]="Zone20X",t[t.Zone20Y=141]="Zone20Y",t[t.Zone21X=142]="Zone21X",t[t.Zone21Y=143]="Zone21Y",t[t.Zone22X=144]="Zone22X",t[t.Zone22Y=145]="Zone22Y",t[t.Zone23X=146]="Zone23X",t[t.Zone23Y=147]="Zone23Y",t[t.Zone24X=148]="Zone24X",t[t.Zone24Y=149]="Zone24Y",t[t.Zone25X=150]="Zone25X",t[t.Zone25Y=151]="Zone25Y",t[t.Zone26X=152]="Zone26X",t[t.Zone26Y=153]="Zone26Y",t[t.Zone27X=154]="Zone27X",t[t.Zone27Y=155]="Zone27Y",t[t.Zone28X=156]="Zone28X",t[t.Zone28Y=157]="Zone28Y",t[t.Zone29X=158]="Zone29X",t[t.Zone29Y=159]="Zone29Y",t[t.Zone30X=160]="Zone30X",t[t.Zone30Y=161]="Zone30Y",t[t.Zone31X=162]="Zone31X",t[t.Zone31Y=163]="Zone31Y",t))(xt||{});var vt=(t=>(t[t.DPadUp=0]="DPadUp",t[t.DPadDown=1]="DPadDown",t[t.DPadLeft=2]="DPadLeft",t[t.DPadRight=3]="DPadRight",t[t.DPadCenter=4]="DPadCenter",t[t.Play=5]="Play",t[t.Pause=6]="Pause",t[t.PlayPause=7]="PlayPause",t[t.Stop=8]="Stop",t[t.Rewind=9]="Rewind",t[t.FastForward=10]="FastForward",t[t.Previous=11]="Previous",t[t.Next=12]="Next",t[t.Record=13]="Record",t[t.VolumeUp=15]="VolumeUp",t[t.VolumeDown=16]="VolumeDown",t[t.Mute=17]="Mute",t[t.ChannelUp=18]="ChannelUp",t[t.ChannelDown=19]="ChannelDown",t[t.Back=20]="Back",t[t.Home=21]="Home",t[t.Menu=22]="Menu",t[t.Info=23]="Info",t[t.Guide=24]="Guide",t[t.Exit=25]="Exit",t[t.Red=30]="Red",t[t.Green=31]="Green",t[t.Yellow=32]="Yellow",t[t.Blue=33]="Blue",t[t.Digit0=40]="Digit0",t[t.Digit1=41]="Digit1",t[t.Digit2=42]="Digit2",t[t.Digit3=43]="Digit3",t[t.Digit4=44]="Digit4",t[t.Digit5=45]="Digit5",t[t.Digit6=46]="Digit6",t[t.Digit7=47]="Digit7",t[t.Digit8=48]="Digit8",t[t.Digit9=49]="Digit9",t[t.Input=50]="Input",t[t.Settings=51]="Settings",t[t.Subtitle=52]="Subtitle",t[t.Audio=53]="Audio",t[t.Power=54]="Power",t[t.PointerX=100]="PointerX",t[t.PointerY=101]="PointerY",t[t.GyroX=102]="GyroX",t[t.GyroY=103]="GyroY",t[t.GyroZ=104]="GyroZ",t))(vt||{});var Ct=(t=>(t.TerminalGL="webgl",t.Terminal2D="terminal2d",t.TerminalANSI="ansi",t))(Ct||{}),m=(t=>(t[t.None=0]="None",t[t.Eighth=1]="Eighth",t[t.Quarter=2]="Quarter",t[t.Half=3]="Half",t[t.Integer=4]="Integer",t[t.Responsive=5]="Responsive",t))(m||{}),y={scanlines:{opacity:.15,pattern:"horizontal",spacing:2,thickness:1,color:{r:0,g:0,b:0}},ambientEffect:{blur:30,scale:1.3,opacity:.7}};var bt=(t=>(t[t.Char=1]="Char",t[t.Text=2]="Text",t[t.SubFrame=3]="SubFrame",t[t.SubFrameMulti=4]="SubFrameMulti",t[t.FullFrame=5]="FullFrame",t[t.FullFrameMulti=6]="FullFrameMulti",t[t.Sprite=7]="Sprite",t[t.SpriteMulti=8]="SpriteMulti",t[t.ColorMap=9]="ColorMap",t[t.Shape=10]="Shape",t[t.DotCloud=11]="DotCloud",t[t.DotCloudMulti=12]="DotCloudMulti",t[t.SpriteCloud=13]="SpriteCloud",t[t.SpriteCloudMulti=14]="SpriteCloudMulti",t[t.SpriteCloudVaried=15]="SpriteCloudVaried",t[t.SpriteCloudVariedMulti=16]="SpriteCloudVariedMulti",t[t.Bitmask=17]="Bitmask",t[t.Bitmask4=18]="Bitmask4",t[t.Fill=19]="Fill",t[t.FillChar=20]="FillChar",t[t.FillSprite=21]="FillSprite",t[t.FillSpriteMulti=22]="FillSpriteMulti",t[t.TextMultiline=23]="TextMultiline",t[t.Bitmask16=24]="Bitmask16",t[t.Polyline=25]="Polyline",t[t.Audio=32]="Audio",t[t.Vibration=33]="Vibration",t[t.PostProcess=34]="PostProcess",t))(bt||{}),yt=(t=>(t[t.Rectangle=1]="Rectangle",t[t.Circle=2]="Circle",t[t.Line=3]="Line",t[t.Ellipse=4]="Ellipse",t[t.Triangle=5]="Triangle",t))(yt||{}),Et=(t=>(t[t.FastPath=255]="FastPath",t[t.Fragment=254]="Fragment",t))(Et||{});var wt=(t=>(t[t.Enabled=1]="Enabled",t[t.SetMode=2]="SetMode",t[t.Position=4]="Position",t[t.ZOrder=8]="ZOrder",t[t.Orders=16]="Orders",t[t.IsMacroLayer=32]="IsMacroLayer",t[t.Is16BitMode=64]="Is16BitMode",t))(wt||{}),Tt=(t=>(t.WAITING_FOR_WELCOME="waiting_for_welcome",t.AUTHENTICATING="authenticating",t.LOADING="loading",t.ACTIVE="active",t.DISCONNECTED="disconnected",t))(Tt||{});var M={trace:0,debug:1,info:2,warn:3,error:4,silent:5},E=[],z="info",P=new Map,R=new Map,At=typeof performance<"u"&&typeof performance.now=="function"?()=>performance.now():()=>Date.now(),U=null;function Q(t){let e=null,i=-1;for(let[s,a]of P)if(Rt(s,t)){let r=s.length;r>i&&(i=r,e=a)}return e??z}function Rt(t,e){if(t==="*")return!0;if(t.endsWith(":*")){let i=t.slice(0,-1);return e===t.slice(0,-2)||e.startsWith(i)}return t===e}function K(){for(let[t,e]of R)e.c(Q(t))}var w=class I{namespace;r;i;s;constructor(e,i,s){this.namespace=e,this.i=i,this.s=s,this.r=M[Q(e)]}static create(e){let i=R.get(e);return i||(i=new I(e),R.set(e,i)),i}child(e){return I.create(`${this.namespace}:${e}`)}forClient(e,i){let s=`${this.namespace}:client:${e}`,a=R.get(s);return a?(a.i=e,a.s=i):(a=new I(s,e,i),R.set(s,a)),a}static dispose(e){R.delete(e)}trace(e,i){this.n("trace",e,i)}debug(e,i){this.n("debug",e,i)}info(e,i){this.n("info",e,i)}warn(e,i){this.n("warn",e,i)}error(e,i){this.n("error",e,i)}isEnabled(e){return M[e]>=this.r}c(e){this.r=M[e]}n(e,i,s){if(M[e]<this.r||E.length===0)return;let a=typeof i=="function"?i():i,r={timestamp:At(),level:e,namespace:this.namespace,message:a};U!==null&&(r.tick=U()),s!==void 0&&(r.data=s),this.i!==void 0&&(r.clientId=this.i),this.s!==void 0&&(r.username=this.s);for(let n=0;n<E.length;n++)E[n](r)}static setLevel(e,i){i===void 0?z=e:P.set(e,i),K()}static clearLevelOverrides(){P.clear(),K()}static enable(e){I.setLevel(e,"trace")}static disable(e){I.setLevel(e,"silent")}static addHandler(e){return E.push(e),()=>{let i=E.indexOf(e);i!==-1&&E.splice(i,1)}}static clearHandlers(){E.length=0}static get handlerCount(){return E.length}static setTickProvider(e){U=e}static reset(){E.length=0,P.clear(),R.clear(),z="info",U=null}},S="\x1B[0m",Dt={trace:"\x1B[90m",debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m"},It="\x1B[35m",q="\x1B[2m",Bt="\x1B[93m",St={trace:"color:#888",debug:"color:#0cc",info:"color:#0a0",warn:"color:#cc0",error:"color:#c00;font-weight:bold"},Ft="color:#c0c;font-weight:bold",j="color:#888",Mt="color:#c90;font-weight:bold",J={trace:"debug",debug:"debug",info:"info",warn:"warn",error:"error"},Ut=typeof globalThis<"u"&&typeof globalThis.process=="object"&&typeof globalThis.process?.versions=="object";function _(t,e){return String(t).padStart(e,"0")}function tt(t){let e=Math.floor(t/1e3)%60,i=Math.floor(t/6e4)%60,s=Math.floor(t%1e3);return`${_(i,2)}:${_(e,2)}.${_(s,3)}`}function et(t){return t.toUpperCase().padEnd(5)}function it(t){if(t.clientId===void 0)return"";let e=t.username?`/${t.username}`:"";return` [client:${t.clientId}${e}]`}function Pt(t){let e=`${q}${tt(t.timestamp)}${S}`,i=t.tick!==void 0?` ${Bt}#${t.tick}${S}`:"",s=`${Dt[t.level]}${et(t.level)}${S}`,a=`${It}${t.namespace}${S}`,r=t.clientId!==void 0?`${q}${it(t)}${S}`:"",n=J[t.level],o=`${e}${i} ${s} ${a}${r}`;t.data!==void 0?console[n](o,t.message,t.data):console[n](o,t.message)}function Zt(t){let e=J[t.level],i=it(t),s=t.tick!==void 0?` %c#${t.tick}`:"",a=t.tick!==void 0?[Mt]:[],r=`%c${tt(t.timestamp)}${s} %c${et(t.level)} %c${t.namespace}%c${i} %c${t.message}`,n=[j,...a,St[t.level],Ft,j,""];t.data!==void 0?console[e](r,...n,t.data):console[e](r,...n)}var Lt=Ut?Pt:Zt;w.handlerCount===0&&w.addHandler(Lt);var F=class{canvas;ctx;container;cols=0;rows=0;cellWidth=0;cellHeight=0;offsetX=0;offsetY=0;strokeColor="rgba(80, 80, 80, 0.4)";lineWidth=1;constructor(t,e){this.container=t,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let i=e?.zIndex??10;this.canvas.style.cssText=`
2
+ display: block !important;
3
+ position: absolute !important;
4
+ pointer-events: none !important;
5
+ image-rendering: pixelated !important;
6
+ image-rendering: crisp-edges !important;
7
+ z-index: ${i} !important;
8
+ `,this.container.appendChild(this.canvas);let s=this.canvas.getContext("2d");if(!s)throw new Error("[GridOverlay] Failed to create 2D context");this.ctx=s,e&&(e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth))}setDimensions(t,e,i,s,a=0,r=0){this.cols=t,this.rows=e,this.cellWidth=i,this.cellHeight=s,this.offsetX=a,this.offsetY=r}setCanvasSize(t,e){this.canvas.width=t,this.canvas.height=e,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(t){t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth)}setTransform(t,e,i,s,a){let r=s.left-a.left,n=s.top-a.top,o=s.width,l=s.height;(this.canvas.width!==o||this.canvas.height!==l)&&(this.canvas.width=o,this.canvas.height=l);let h=this.canvas.style;h.width=`${o}px`,h.height=`${l}px`,h.left=`${r}px`,h.top=`${n}px`}render(){if(!this.ctx)return;let t=this.cols*this.cellWidth,e=this.rows*this.cellHeight,i=t>0?this.canvas.width/t:1,s=e>0?this.canvas.height/e:1,a=Math.min(i,s),r=this.cellWidth*a,n=this.cellHeight*a,o=this.cols*r,l=this.rows*n,h=this.offsetX*a,c=this.offsetY*a;if(!(o===0||l===0)){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.strokeStyle=this.strokeColor,this.ctx.lineWidth=Math.max(1,this.lineWidth*a),this.ctx.beginPath();for(let u=0;u<=this.cols;u++){let d=h+u*r+.5;this.ctx.moveTo(d,c),this.ctx.lineTo(d,c+l)}for(let u=0;u<=this.rows;u++){let d=c+u*n+.5;this.ctx.moveTo(h,d),this.ctx.lineTo(h+o,d)}this.ctx.stroke()}}update(t,e,i,s,a,r,n=0,o=0){this.setDimensions(t,e,i,s,n,o),this.setCanvasSize(a,r),this.render()}setVisible(t){this.canvas.style.display=t?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}},G=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff","#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a80000","#00a800","#a8a800","#0000a8","#a800a8","#00a8a8","#a8a8a8","#545454","#fc5454","#54fc54","#fcfc54","#5454fc","#fc54fc","#54fcfc","#fcfcfc","#000000",...Array(192).fill("#808080")];function Yt(t,e=G){return t<0||t>=e.length?"#ff00ff":e[t]}function Wt(t,e=G){let i=e.indexOf(t.toLowerCase());return i>=0?i:0}var _t=class{canvas;ctx;containerDiv;parentElement;resizeObserver;width=0;height=0;currentConfig=null;configHash="";constructor(t,e){this.parentElement=t,this.containerDiv=document.createElement("div"),this.containerDiv.className="postprocess-container",this.containerDiv.style.cssText=`
9
+ position: absolute !important;
10
+ top: 0 !important;
11
+ left: 0 !important;
12
+ right: 0 !important;
13
+ bottom: 0 !important;
14
+ width: 100% !important;
15
+ height: 100% !important;
16
+ pointer-events: none !important;
17
+ z-index: 10 !important;
18
+ overflow: hidden !important;
19
+ `,this.canvas=document.createElement("canvas"),this.canvas.className="postprocess-canvas",this.canvas.style.cssText=`
20
+ position: absolute !important;
21
+ top: 0 !important;
22
+ left: 0 !important;
23
+ width: 100% !important;
24
+ height: 100% !important;
25
+ pointer-events: none !important;
26
+ `;let i=this.canvas.getContext("2d",{alpha:!0});if(!i)throw new Error("PostProcessOverlay: Failed to get 2D context");this.ctx=i,this.containerDiv.appendChild(this.canvas),this.parentElement.appendChild(this.containerDiv),this.resizeObserver=new ResizeObserver(a=>{for(let r of a){let{width:n,height:o}=r.contentRect;n>0&&o>0&&this.handleResize(Math.floor(n),Math.floor(o))}}),this.resizeObserver.observe(this.parentElement);let s=this.parentElement.getBoundingClientRect();s.width>0&&s.height>0&&this.handleResize(Math.floor(s.width),Math.floor(s.height)),this.hide()}handleResize(t,e){this.width===t&&this.height===e||(this.width=t,this.height=e,this.canvas.width=t,this.canvas.height=e,this.currentConfig&&this.isActive()&&this.render())}setConfig(t){let e=this.hashConfig(t);if(e!==this.configHash){if(this.currentConfig=t,this.configHash=e,!t||!this.isActiveConfig(t)){this.clear(),this.hide();return}this.show(),this.render()}}setScanlines(t){t===null?this.setConfig({scanlines:{enabled:!1}}):this.setConfig({scanlines:t})}setScanlinesEnabled(t){if(t){let e=this.currentConfig?.scanlines;this.setScanlines({enabled:!0,opacity:e?.opacity??y.scanlines.opacity,pattern:e?.pattern??"horizontal",spacing:e?.spacing??2,thickness:e?.thickness??1,color:e?.color??{r:0,g:0,b:0}})}else this.setScanlines({enabled:!1})}setScanlinesOpacity(t){let e=Math.max(0,Math.min(1,t)),i=this.currentConfig?.scanlines;this.setScanlines({enabled:i?.enabled??!0,opacity:e,pattern:i?.pattern??"horizontal",spacing:i?.spacing??2,thickness:i?.thickness??1,color:i?.color??{r:0,g:0,b:0}})}setScanlinesPattern(t){let e=this.currentConfig?.scanlines;this.setScanlines({enabled:e?.enabled??!0,opacity:e?.opacity??y.scanlines.opacity,pattern:t,spacing:e?.spacing??2,thickness:e?.thickness??1,color:e?.color??{r:0,g:0,b:0}})}setScanlinesSpacing(t){let e=Math.max(2,Math.round(t)),i=this.currentConfig?.scanlines;this.setScanlines({enabled:i?.enabled??!0,opacity:i?.opacity??y.scanlines.opacity,pattern:i?.pattern??"horizontal",spacing:e,thickness:i?.thickness??1,color:i?.color??{r:0,g:0,b:0}})}getConfig(){return this.currentConfig}isActive(){return this.isActiveConfig(this.currentConfig)}destroy(){this.resizeObserver.disconnect(),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv)}syncWithRenderer(t){}resize(t,e){}setCellDimensions(t,e){}show(){this.containerDiv.style.display="block"}hide(){this.containerDiv.style.display="none"}clear(){this.ctx.clearRect(0,0,this.width,this.height)}isActiveConfig(t){return t?.scanlines?.enabled??!1}render(){this.clear(),this.currentConfig?.scanlines?.enabled&&this.renderScanlines(this.currentConfig.scanlines)}renderScanlines(t){let e=t.opacity??y.scanlines.opacity,i=t.pattern??"horizontal",s=t.spacing??2,a=t.thickness??1,r=t.color??{r:0,g:0,b:0},n=this.ctx;switch(n.fillStyle=`rgba(${r.r}, ${r.g}, ${r.b}, ${e})`,i){case"horizontal":for(let o=s-1;o<this.height;o+=s)n.fillRect(0,o,this.width,a);break;case"vertical":for(let o=s-1;o<this.width;o+=s)n.fillRect(o,0,a,this.height);break;case"grid":for(let o=s-1;o<this.height;o+=s)n.fillRect(0,o,this.width,a);for(let o=s-1;o<this.width;o+=s)n.fillRect(o,0,a,this.height);break}}hashConfig(t){return t?JSON.stringify(t):"null"}},zt=class{container;overlayDiv=null;button=null;options;started=!1;onStartCallback;constructor(t,e={}){this.container=t,this.options={buttonText:e.buttonText??"Click to Start",onStart:e.onStart??(()=>{}),backgroundColor:e.backgroundColor??"rgba(0, 0, 0, 0.8)",buttonColor:e.buttonColor??"#4a90d9",buttonHoverColor:e.buttonHoverColor??"#357abd",buttonTextColor:e.buttonTextColor??"#ffffff",zIndex:e.zIndex??1e3},this.onStartCallback=e.onStart,this.createOverlay()}createOverlay(){let t=window.getComputedStyle(this.container).position;t!=="relative"&&t!=="absolute"&&t!=="fixed"&&(this.container.style.position="relative"),this.overlayDiv=document.createElement("div"),this.overlayDiv.className="primitiv-autoplay-overlay",this.overlayDiv.style.cssText=`
27
+ position: absolute !important;
28
+ top: 0 !important;
29
+ left: 0 !important;
30
+ right: 0 !important;
31
+ bottom: 0 !important;
32
+ width: 100% !important;
33
+ height: 100% !important;
34
+ background-color: ${this.options.backgroundColor} !important;
35
+ display: flex !important;
36
+ justify-content: center !important;
37
+ align-items: center !important;
38
+ z-index: ${this.options.zIndex} !important;
39
+ cursor: pointer !important;
40
+ `,this.button=document.createElement("button"),this.button.className="primitiv-autoplay-button",this.button.textContent=this.options.buttonText,this.button.style.cssText=`
41
+ padding: 16px 32px !important;
42
+ font-size: 18px !important;
43
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif !important;
44
+ font-weight: 600 !important;
45
+ color: ${this.options.buttonTextColor} !important;
46
+ background-color: ${this.options.buttonColor} !important;
47
+ border: none !important;
48
+ border-radius: 8px !important;
49
+ cursor: pointer !important;
50
+ transition: background-color 0.2s ease, transform 0.1s ease !important;
51
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
52
+ `,this.button.addEventListener("mouseenter",()=>{this.button&&(this.button.style.backgroundColor=`${this.options.buttonHoverColor} !important`,this.button.style.transform="scale(1.05)")}),this.button.addEventListener("mouseleave",()=>{this.button&&(this.button.style.backgroundColor=`${this.options.buttonColor} !important`,this.button.style.transform="scale(1)")}),this.button.addEventListener("click",e=>{e.stopPropagation(),this.start()}),this.overlayDiv.addEventListener("click",()=>{this.start()}),this.overlayDiv.appendChild(this.button),this.container.appendChild(this.overlayDiv)}start(){this.started||(this.started=!0,this.overlayDiv&&(this.overlayDiv.style.transition="opacity 0.3s ease",this.overlayDiv.style.opacity="0",setTimeout(()=>{this.removeOverlay()},300)),this.onStartCallback&&this.onStartCallback())}isStarted(){return this.started}isVisible(){return this.overlayDiv!==null&&!this.started}removeOverlay(){this.overlayDiv&&this.overlayDiv.parentElement&&this.overlayDiv.parentElement.removeChild(this.overlayDiv),this.overlayDiv=null,this.button=null}setButtonText(t){this.options.buttonText=t,this.button&&(this.button.textContent=t)}setOnStart(t){this.onStartCallback=t}destroy(){this.removeOverlay(),this.started=!1}};function B(t){return Math.sqrt(t)*16}function L(t){return t*256-1}function Ot(t,e){return B(t)*e}function Y(t,e){let i=Math.floor(t/256),s=t%256,a=Math.sqrt(e),r=i%a,n=Math.floor(i/a),o=s%16,l=Math.floor(s/16);return{col:r*16+o,row:n*16+l}}var X=class{atlasCanvas=null;atlasCtx=null;atlasImage=null;glyphWidth;glyphHeight;cellWidth;cellHeight;atlasBlocks;atlasColumns;maxCharCode;isLoaded=!1;colorCache=new Map;MAX_CACHE_SIZE=1024;constructor(t){this.glyphWidth=t.glyphWidth,this.glyphHeight=t.glyphHeight,this.cellWidth=t.cellWidth??t.glyphWidth,this.cellHeight=t.cellHeight??t.glyphHeight,this.atlasBlocks=t.atlasBlocks,this.atlasColumns=B(t.atlasBlocks),this.maxCharCode=L(t.atlasBlocks)}getCanvas(){return this.atlasCanvas}getGlyphWidth(){return this.glyphWidth}getGlyphHeight(){return this.glyphHeight}prepare(){let t=this.atlasColumns*this.glyphWidth,e=this.atlasColumns*this.glyphHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=t,this.atlasCanvas.height=e,this.atlasCtx=this.atlasCanvas.getContext("2d",{alpha:!0,willReadFrequently:!0}),this.atlasCtx&&(this.atlasCtx.imageSmoothingEnabled=!1,this.atlasCtx.clearRect(0,0,t,e)),this.isLoaded=!0}async loadBlock(t,e){return(!this.atlasCanvas||!this.atlasCtx)&&this.prepare(),new Promise((i,s)=>{let a=new Uint8Array(e),r=new Blob([a],{type:"image/png"}),n=URL.createObjectURL(r),o=new Image;o.onload=()=>{URL.revokeObjectURL(n);let l=Math.sqrt(this.atlasBlocks),h=t%l,c=Math.floor(t/l),u=h*16*this.glyphWidth,d=c*16*this.glyphHeight;this.atlasCtx.drawImage(o,u,d),this.colorCache.clear(),i()},o.onerror=()=>{URL.revokeObjectURL(n),s(new Error(`Failed to load PNG for block ${t}`))},o.src=n})}async loadFromPNG(t){return new Promise((e,i)=>{let s=new Uint8Array(t),a=new Blob([s],{type:"image/png"}),r=URL.createObjectURL(a),n=new Image;n.onload=()=>{URL.revokeObjectURL(r);let o=this.atlasColumns*this.glyphWidth,l=this.atlasColumns*this.glyphHeight;if((n.width!==o||n.height!==l)&&w.create("render:atlas").warn(`Image size ${n.width}\xD7${n.height} doesn't match expected ${o}\xD7${l} for ${this.atlasBlocks} block(s) with ${this.glyphWidth}\xD7${this.glyphHeight} glyphs`),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=n.width,this.atlasCanvas.height=n.height,this.atlasCtx=this.atlasCanvas.getContext("2d",{alpha:!0,willReadFrequently:!0}),!this.atlasCtx){i(new Error("Failed to create 2D context for atlas"));return}this.atlasCtx.imageSmoothingEnabled=!1,this.atlasCtx.drawImage(n,0,0),this.atlasImage=n,this.isLoaded=!0,e()},n.onerror=()=>{URL.revokeObjectURL(r),i(new Error("Failed to load PNG image for atlas"))},n.src=r})}isReady(){return this.isLoaded}getGlyphPosition(t){if(t<0||t>this.maxCharCode)return null;let{col:e,row:i}=Y(t,this.atlasBlocks);return{x:e*this.glyphWidth,y:i*this.glyphHeight}}getCharUV(t){if(t<0||t>this.maxCharCode)return null;let{col:e,row:i}=Y(t,this.atlasBlocks),s=e/this.atlasColumns,a=i/this.atlasColumns,r=(e+1)/this.atlasColumns,n=(i+1)/this.atlasColumns;return{u1:s,v1:a,u2:r,v2:n}}drawChar(t,e,i,s,a,r,n){if(!this.isLoaded||!this.atlasCanvas)return;let o=this.getGlyphPosition(e);if(!o)return;let l=`${e}:${n}`,h=this.colorCache.get(l);if(h)h.lastUsed=performance.now();else{let c=this.createColoredGlyph(e,n,o);if(!c)return;h={canvas:c,lastUsed:performance.now()},this.colorCache.set(l,h),this.colorCache.size>this.MAX_CACHE_SIZE&&this.evictLRU()}if(t.imageSmoothingEnabled=!1,a===this.cellWidth&&r===this.cellHeight){let c=Math.floor((this.cellWidth-this.glyphWidth)/2),u=Math.floor((this.cellHeight-this.glyphHeight)/2);t.drawImage(h.canvas,Math.floor(i)+c,Math.floor(s)+u)}else{let c=a/this.cellWidth,u=r/this.cellHeight,d=Math.floor((this.cellWidth-this.glyphWidth)/2*c),p=Math.floor((this.cellHeight-this.glyphHeight)/2*u),g=Math.ceil(this.glyphWidth*c),f=Math.ceil(this.glyphHeight*u);t.drawImage(h.canvas,Math.floor(i)+d,Math.floor(s)+p,g,f)}}createColoredGlyph(t,e,i){if(!this.atlasCtx)return null;let s=this.atlasCtx.getImageData(i.x,i.y,this.glyphWidth,this.glyphHeight),a=s.data,r=this.parseColor(e);for(let l=0;l<a.length;l+=4)a[l+3]>0&&(a[l]=a[l]*r.r/255,a[l+1]=a[l+1]*r.g/255,a[l+2]=a[l+2]*r.b/255);let n=document.createElement("canvas");n.width=this.glyphWidth,n.height=this.glyphHeight;let o=n.getContext("2d",{alpha:!0});return o?(o.putImageData(s,0,0),n):null}parseColor(t){if(t.startsWith("#")){let i=t.slice(1);return i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),{r:parseInt(i.slice(0,2),16),g:parseInt(i.slice(2,4),16),b:parseInt(i.slice(4,6),16)}}let e=/rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(t);return e?{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10)}:{r:255,g:255,b:255}}evictLRU(){let t=null,e=1/0;for(let[i,s]of this.colorCache)s.lastUsed<e&&(e=s.lastUsed,t=i);if(t){let i=this.colorCache.get(t);i&&(i.canvas.width=0,i.canvas.height=0),this.colorCache.delete(t)}}getAtlasCanvas(){return this.atlasCanvas}getAtlasImage(){return this.atlasImage}getConfig(){return{glyphWidth:this.glyphWidth,glyphHeight:this.glyphHeight,cellWidth:this.cellWidth,cellHeight:this.cellHeight,atlasBlocks:this.atlasBlocks}}getGlyphDimensions(){return{width:this.glyphWidth,height:this.glyphHeight}}getCellDimensions(){return{width:this.cellWidth,height:this.cellHeight}}getAtlasDimensions(){return{width:this.atlasColumns*this.glyphWidth,height:this.atlasColumns*this.glyphHeight}}getAtlasColumns(){return this.atlasColumns}getMaxCharCode(){return this.maxCharCode}isValidCharCode(t){return t>=0&&t<=this.maxCharCode}clearCache(){for(let t of this.colorCache.values())t.canvas.width=0,t.canvas.height=0;this.colorCache.clear()}getCacheStats(){return{size:this.colorCache.size,maxSize:this.MAX_CACHE_SIZE}}destroy(){this.clearCache(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=null),this.atlasCtx=null,this.atlasImage=null,this.isLoaded=!1}},Z=w.create("render:2d"),Xt=class{containerDiv;canvas;ctx;parentElement;cells;cols=0;rows=0;defaultFgColor;defaultBgColor;canvasBgColor;cellWidth;cellHeight;offsetX=0;offsetY=0;imageAtlas;showDebugGrid;debugGridColor;gridOverlay;fixedGridMode;fixedCols;fixedRows;cellAspectRatio;resizeObserver;paletteCache;scalingMode=m.None;currentScale=1;customCellSize=!1;constructor(t,e={}){if(!t)throw new Error("Render: parent element is required");this.parentElement=t,this.fixedGridMode=!!(e.fixedCols&&e.fixedRows),this.fixedCols=e.fixedCols,this.fixedRows=e.fixedRows,this.cellAspectRatio=e.cellAspectRatio??1,this.cellWidth=e.cellWidth??8,this.cellHeight=e.cellHeight??8,this.defaultFgColor=e.defaultFgColor??"#ffffff",this.defaultBgColor=e.defaultBgColor??"#000000",this.canvasBgColor=e.canvasBgColor!==void 0?e.canvasBgColor:null,this.showDebugGrid=e.showDebugGrid??!1,this.debugGridColor=e.debugGridColor??"rgba(144, 24, 24, 1)",this.scalingMode=e.scalingMode??m.None,window.getComputedStyle(this.parentElement).position==="static"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminal2d-container",this.containerDiv.style.cssText=`
53
+ position: absolute !important;
54
+ top: 0 !important;
55
+ left: 0 !important;
56
+ right: 0 !important;
57
+ bottom: 0 !important;
58
+ width: 100% !important;
59
+ height: 100% !important;
60
+ overflow: visible !important;
61
+ contain: layout style !important;
62
+ display: flex !important;
63
+ justify-content: center !important;
64
+ align-items: center !important;
65
+ isolation: isolate !important;
66
+ pointer-events: none !important;
67
+ `,this.canvas=document.createElement("canvas"),this.canvas.className="terminal2d-canvas",e.className&&(this.canvas.className+=" "+e.className),e.style&&Object.assign(this.canvas.style,e.style),this.canvas.style.imageRendering="pixelated",this.canvas.style.imageRendering="crisp-edges",this.containerDiv.appendChild(this.canvas),this.parentElement.appendChild(this.containerDiv);let i=this.canvas.getContext("2d",{alpha:!0,desynchronized:!1});if(!i)throw new Error("Render: Failed to obtain 2D canvas context");this.ctx=i,this.ctx.imageSmoothingEnabled=!1,this.calculateGridSize(),this.cells=this.createEmptyGrid(),this.showDebugGrid&&(this.gridOverlay=new F(this.parentElement,{strokeColor:this.debugGridColor,lineWidth:1,zIndex:10})),this.enableAutoResize(),this.render()}calculateGridSize(){let t=this.parentElement.clientWidth||800,e=this.parentElement.clientHeight||600;if(!this.customCellSize){let l,h;if(this.imageAtlas){let c=this.imageAtlas.getCellDimensions();l=c.width,h=c.height}else l=this.cellWidth,h=this.cellHeight;this.cellWidth=Math.round(l),this.cellHeight=Math.round(h)}this.scalingMode===m.Responsive?(this.cols=Math.floor(t/this.cellWidth)||1,this.rows=Math.floor(e/this.cellHeight)||1):this.fixedGridMode&&this.fixedCols&&this.fixedRows?(this.cols=this.fixedCols,this.rows=this.fixedRows):(this.cols=Math.floor(t/this.cellWidth)||1,this.rows=Math.floor(e/this.cellHeight)||1);let i=this.cols*this.cellWidth,s=this.rows*this.cellHeight,a=t/i,r=e/s,n=Math.min(a,r),o;switch(this.scalingMode){case m.Integer:o=Math.max(1,Math.floor(n));break;case m.Half:o=Math.max(.5,Math.floor(n*2)/2);break;case m.Quarter:o=Math.max(.25,Math.floor(n*4)/4);break;case m.Eighth:o=Math.max(.125,Math.floor(n*8)/8);break;case m.Responsive:o=1;break;case m.None:default:o=Math.max(.1,n);break}this.currentScale=o,this.canvas.width=i,this.canvas.height=s,this.ctx.imageSmoothingEnabled=!1,this.canvas.style.cssText=`
68
+ flex-shrink: 0 !important;
69
+ flex-grow: 0 !important;
70
+ width: ${i}px !important;
71
+ height: ${s}px !important;
72
+ image-rendering: pixelated !important;
73
+ image-rendering: crisp-edges !important;
74
+ -ms-interpolation-mode: nearest-neighbor !important;
75
+ transform-origin: center center !important;
76
+ transform: scale(${o}) !important;
77
+ will-change: transform !important;
78
+ backface-visibility: hidden !important;
79
+ pointer-events: auto !important;
80
+ touch-action: manipulation !important;
81
+ `,this.offsetX=0,this.offsetY=0}createEmptyGrid(){let t=[];for(let e=0;e<this.rows;e++){let i=[];for(let s=0;s<this.cols;s++)i.push({char:" ",fgColor:this.defaultFgColor,bgColor:this.defaultBgColor});t.push(i)}return t}enableAutoResize(){this.resizeObserver=new ResizeObserver(()=>{let t=this.cols,e=this.rows;if(this.calculateGridSize(),this.cols!==t||this.rows!==e){let i=this.cells;this.cells=this.createEmptyGrid();let s=Math.min(t,this.cols),a=Math.min(e,this.rows);for(let r=0;r<a;r++)for(let n=0;n<s;n++)this.cells[r][n]=i[r][n]}this.render()}),this.resizeObserver.observe(this.parentElement)}setCell(t,e,i,s,a){if(e<0||e>=this.rows||t<0||t>=this.cols)return;let r=i&&typeof i=="string"?i.charAt(0):" ";this.cells[e][t]={char:r,fgColor:s??this.defaultFgColor,bgColor:a??this.defaultBgColor}}getCell(t,e){return e<0||e>=this.rows||t<0||t>=this.cols?null:this.cells[e][t]}write(t,e,i,s,a){for(let r=0;r<i.length;r++)this.setCell(t+r,e,i[r],s,a)}fillRect(t,e,i,s,a=" ",r,n){for(let o=e;o<e+s;o++)for(let l=t;l<t+i;l++)this.setCell(l,o,a,r,n)}clear(){this.cells=this.createEmptyGrid()}setFromArray(t){let e=t.width*t.height;if(t.cells.length!==e)throw new Error(`Invalid array length: expected ${e} (${t.width}\xD7${t.height}), got ${t.cells.length}`);let i=0;for(let s=0;s<t.height;s++)for(let a=0;a<t.width;a++){let r=t.cells[i];s<this.rows&&a<this.cols&&this.setCell(a,s,r.char,r.fgColor,r.bgColor),i++}}render(t=!0){this.renderClassic(t)}renderClassic(t=!0){t&&(this.canvasBgColor!==null?(this.ctx.fillStyle=this.canvasBgColor,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)):this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)),this.ctx.imageSmoothingEnabled=!1,this.canvas.style.imageRendering="pixelated",this.canvas.style.imageRendering="crisp-edges";for(let e=0;e<this.rows;e++)for(let i=0;i<this.cols;i++){let s=this.cells[e][i],a=Math.floor(this.offsetX+i*this.cellWidth),r=Math.floor(this.offsetY+e*this.cellHeight),n=Math.floor(this.offsetX+(i+1)*this.cellWidth),o=Math.floor(this.offsetY+(e+1)*this.cellHeight),l=n-a,h=o-r;if((this.canvasBgColor!==null||s.bgColor!==this.defaultBgColor)&&(this.ctx.fillStyle=s.bgColor,this.ctx.fillRect(a,r,l,h)),s.char!==" "&&this.imageAtlas){let c=s.char.charCodeAt(0);this.imageAtlas.drawChar(this.ctx,c,a,r,l,h,s.fgColor)}}this.showDebugGrid&&this.drawDebugGrid()}drawDebugGrid(){if(!this.gridOverlay)return;let t=this.parentElement.clientWidth||800,e=this.parentElement.clientHeight||600;this.gridOverlay.update(this.cols,this.rows,this.cellWidth,this.cellHeight,t,e,this.offsetX,this.offsetY)}getCanvas(){return this.canvas}getContext(){return this.ctx}getDimensions(){return{cols:this.cols,rows:this.rows}}getCellDimensions(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getScalingMode(){return this.scalingMode}getOffsets(){return{offsetX:this.offsetX,offsetY:this.offsetY}}setDebugGrid(t){this.showDebugGrid=t,t&&!this.gridOverlay?(this.gridOverlay=new F(this.parentElement,{strokeColor:this.debugGridColor,lineWidth:1,zIndex:10}),this.drawDebugGrid()):!t&&this.gridOverlay?(this.gridOverlay.destroy(),this.gridOverlay=void 0):t&&this.gridOverlay&&this.gridOverlay.setVisible(!0)}setCanvasBackgroundColor(t){this.canvasBgColor=t}getCanvasBackgroundColor(){return this.canvasBgColor}setFixedGrid(t,e,i){this.fixedGridMode=!0,this.fixedCols=t,this.fixedRows=e,i!==void 0&&(this.cellAspectRatio=i);let s=this.cols,a=this.rows,r=this.cells;if(this.calculateGridSize(),this.cols!==s||this.rows!==a){this.cells=this.createEmptyGrid();let n=Math.min(s,this.cols),o=Math.min(a,this.rows);for(let l=0;l<o;l++)for(let h=0;h<n;h++)this.cells[l][h]=r[l][h]}this.render()}setAdaptiveGrid(t,e){this.fixedGridMode=!1,this.fixedCols=void 0,this.fixedRows=void 0,t!==void 0&&(this.cellWidth=t),e!==void 0&&(this.cellHeight=e);let i=this.cols,s=this.rows,a=this.cells;if(this.calculateGridSize(),this.cols!==i||this.rows!==s){this.cells=this.createEmptyGrid();let r=Math.min(i,this.cols),n=Math.min(s,this.rows);for(let o=0;o<n;o++)for(let l=0;l<r;l++)this.cells[o][l]=a[o][l]}this.render()}isFixedGridMode(){return this.fixedGridMode}setDebugGridColor(t){this.debugGridColor=t}isDebugGridEnabled(){return this.showDebugGrid}async setImageFont(t,e,i,s,a,r){this.imageAtlas=new X({glyphWidth:e,glyphHeight:i,cellWidth:s,cellHeight:a,atlasBlocks:r}),await this.imageAtlas.loadFromPNG(t),this.cellWidth=s,this.cellHeight=a,this.calculateGridSize(),this.fixedGridMode||(this.calculateGridSize(),this.cells=this.createEmptyGrid()),this.render()}async setImageFontStructure(t,e,i,s,a){let r=this.imageAtlas;if(this.imageAtlas=new X({glyphWidth:t,glyphHeight:e,cellWidth:i,cellHeight:s,atlasBlocks:a}),this.imageAtlas.prepare(),r){let n=r.getCanvas();if(n&&r.getGlyphWidth()===t&&r.getGlyphHeight()===e){let o=this.imageAtlas.getCanvas()?.getContext("2d");if(o){let l=16*t,h=16*e;n.width>=l&&n.height>=h&&o.drawImage(n,0,0,l,h,0,0,l,h)}}}this.cellWidth=i,this.cellHeight=s,this.fixedGridMode||(this.calculateGridSize(),this.cells=this.createEmptyGrid())}async setImageFontBlock(t,e){if(!this.imageAtlas){Z.warn("Cannot load block: no atlas initialized");return}await this.imageAtlas.loadBlock(t,e),this.render()}setPalette(t){this.paletteCache=t}convertColor(t,e){if(t==null||isNaN(t))return this.defaultFgColor;if(t===255)return"rgba(0, 0, 0, 0)";if(t<0||t>=e.length)return this.defaultFgColor;let i=e[t];return!i||typeof i.r!="number"?this.defaultFgColor:`rgba(${i.r}, ${i.g}, ${i.b}, ${i.a/255})`}renderDirect(t,e,i,s,a){for(let r=0;r<e&&r<this.rows;r++)for(let n=0;n<t&&n<this.cols;n++){let o=r*t+n;if(o>=i.length)break;let l=i[o];if(!l)continue;let h=this.convertColor(l.fgColorIndex,s),c=this.convertColor(l.bgColorIndex,s);this.setCell(n,r,l.char??" ",h,c)}this.render(a)}renderDisplayData(t){if(!t||!t.cells||t.cells.length===0){Z.warn("Empty display data");return}if(t.width===0||t.height===0){Z.warn("Invalid display dimensions",{width:t.width,height:t.height});return}(t.width!==this.cols||t.height!==this.rows)&&this.setFixedGrid(t.width,t.height,this.cellAspectRatio);let e=this.paletteCache??t.palette;if(!e||e.length===0){Z.error("No palette available (neither cached nor in display)");return}if(t.passes&&t.passes.length>0)for(let i=0;i<t.passes.length;i++){let s=t.passes[i];this.renderDirect(t.width,t.height,s.cells,e,i===0)}else this.renderDirect(t.width,t.height,t.cells,e,!0)}isReady(){return!0}getCols(){return this.cols}getRows(){return this.rows}resize(t,e){this.setFixedGrid(t,e)}setScalingMode(t){if(this.scalingMode===t)return;let e=this.cols,i=this.rows;if(this.scalingMode=t,this.calculateGridSize(),this.cols!==e||this.rows!==i){let s=this.cells;if(this.cells=this.createEmptyGrid(),s&&s.length>0){let a=Math.min(e,this.cols),r=Math.min(i,this.rows);for(let n=0;n<r;n++)for(let o=0;o<a;o++)s[n]&&s[n][o]&&(this.cells[n][o]=s[n][o])}}this.render()}setCellSize(t,e){let i=Math.max(1,Math.min(255,Math.round(t))),s=Math.max(1,Math.min(255,Math.round(e)));if(this.cellWidth===i&&this.cellHeight===s)return;let a=this.cols,r=this.rows;if(this.cellWidth=i,this.cellHeight=s,this.customCellSize=!0,this.calculateGridSize(),this.cols!==a||this.rows!==r){let n=this.cells;if(this.cells=this.createEmptyGrid(),n&&n.length>0){let o=Math.min(a,this.cols),l=Math.min(r,this.rows);for(let h=0;h<l;h++)for(let c=0;c<o;c++)n[h]&&n[h][c]&&(this.cells[h][c]=n[h][c])}}this.render()}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}getMaxCells(){return 65536}destroy(){this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=void 0),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv)}},v=w.create("render:gl"),Gt=class rt{static checkCompatibility(){let e={webgl1:!1,uint32Indices:!1,maxTextureSize:0,maxViewportDims:[0,0],maxCellsUint16:0,maxCellsUint32:0,recommendedMaxCells:0,warnings:[],errors:[]},i=document.createElement("canvas"),s=i.getContext("webgl")||i.getContext("experimental-webgl");if(!s||!(s instanceof WebGLRenderingContext))return e.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),e;let a=s;e.webgl1=!0;try{e.maxTextureSize=a.getParameter(a.MAX_TEXTURE_SIZE);let o=a.getParameter(a.MAX_VIEWPORT_DIMS);e.maxViewportDims=[o[0],o[1]]}catch(o){return e.errors.push(`\u274C Failed to query WebGL parameters: ${o}`),e}let r=a.getExtension("OES_element_index_uint");e.uint32Indices=!!r;let n=8;if(e.maxCellsUint16=Math.floor(65535/n),e.uint32Indices){let o=Math.floor(e.maxTextureSize*e.maxTextureSize/64);e.maxCellsUint32=Math.min(o,262144)}else e.maxCellsUint32=e.maxCellsUint16,e.warnings.push(`\u26A0\uFE0F OES_element_index_uint not supported - limited to ${e.maxCellsUint16} cells (e.g., 90\xD790 or 127\xD764)`);return e.recommendedMaxCells=Math.floor((e.uint32Indices?e.maxCellsUint32:e.maxCellsUint16)*.8),e.maxTextureSize<256?e.errors.push(`\u274C MAX_TEXTURE_SIZE too small: ${e.maxTextureSize} (minimum 256 required for font atlas)`):e.maxTextureSize<2048&&e.warnings.push(`\u26A0\uFE0F Small MAX_TEXTURE_SIZE: ${e.maxTextureSize} (may limit font atlas)`),(e.maxViewportDims[0]<1024||e.maxViewportDims[1]<768)&&e.warnings.push(`\u26A0\uFE0F Small MAX_VIEWPORT_DIMS: ${e.maxViewportDims[0]}\xD7${e.maxViewportDims[1]}`),a.getExtension("WEBGL_lose_context")||e.warnings.push("\u26A0\uFE0F WEBGL_lose_context not supported - may cause memory leaks"),e}canvas;gl;parentElement;containerDiv;cols;rows;charWidth;charHeight;cellWidth=8;cellHeight=8;glyphOffsetX=0;glyphOffsetY=0;canvasBgColor;showGrid;supportsUint32Indices=!1;useUint16Indices=!1;gridOverlay;bitmapFont;atlasTexture=null;atlasCanvas;atlasColumns=0;fontLoaded=!1;paletteTexture=null;program=null;positionBuffer=null;texCoordBuffer=null;colorIndexBuffer=null;indexBuffer=null;aPosition;aTexCoord;aColorIndex;uResolution=null;uTexture=null;uPalette=null;resizeObserver;boundWindowResize;charCodeToAtlasIndex=new Uint16Array(65536).fill(65535);atlasUVs=new Float32Array(0);cachedAtlasWidth=0;cachedAtlasHeight=0;paletteFloat=new Float32Array(256*4);maxCells=0;renderPositions=new Float32Array(0);renderTexCoords=new Float32Array(0);renderColorIndices=new Float32Array(0);renderIndices=new Uint32Array(0);cachedResolution=[0,0];cachedTextureUnit=-1;cachedPaletteUnit=-1;cachedTextureUniform=!1;cachedPaletteUniform=!1;paletteHash=0;currentScale=1;scalingMode=m.None;ambientEffectEnabled=!1;ambientEffectCanvas=null;ambientEffectCtx=null;ambientEffectBlur=y.ambientEffect.blur;ambientEffectScale=y.ambientEffect.scale;ambientEffectOpacity=.7;onResizeCallback;staticPositionsInitialized=!1;vaoExtension=null;vao=null;instancedExtension=null;useInstancing=!1;instanceDataBuffer=null;instanceData=new Float32Array(0);templateQuadPositions=new Float32Array(0);templateQuadIndices=new Uint16Array(0);aInstanceOffset=-1;aInstanceUVs=-1;aInstanceColors=-1;uCellSize=null;constructor(e,i){if(!e)throw new Error("TerminalGL: Parent element is required");if(!Number.isInteger(i.cols)||i.cols<=0)throw new Error(`TerminalGL: Invalid cols: ${i.cols}. Must be a positive integer.`);if(!Number.isInteger(i.rows)||i.rows<=0)throw new Error(`TerminalGL: Invalid rows: ${i.rows}. Must be a positive integer.`);let s=i.cols*i.rows,a=rt.checkCompatibility();if(a.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${a.errors.join(", ")}`);let r=i.forceUint16??!1;if(r&&s>a.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${i.cols}\xD7${i.rows} (${s} cells) exceeds Uint16 limit of ${a.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(a.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(a.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!a.uint32Indices&&s>a.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${i.cols}\xD7${i.rows} (${s} cells) exceeds device limit of ${a.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(a.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(a.maxCellsUint16))}`);let n=i.charWidth??8,o=i.charHeight??8;if(!Number.isFinite(n)||n<=0)throw new Error(`TerminalGL: Invalid charWidth: ${n}. Must be a positive number.`);if(!Number.isFinite(o)||o<=0)throw new Error(`TerminalGL: Invalid charHeight: ${o}. Must be a positive number.`);for(this.parentElement=e,this.cols=i.cols,this.rows=i.rows,this.charWidth=n,this.charHeight=o,this.canvasBgColor=i.canvasBgColor!==void 0?i.canvasBgColor:null,this.showGrid=i.showGrid??!1,this.scalingMode=i.scalingMode??m.None,i.ambientEffect&&(this.ambientEffectEnabled=!0,typeof i.ambientEffect=="object"&&(this.ambientEffectBlur=i.ambientEffect.blur??y.ambientEffect.blur,this.ambientEffectScale=i.ambientEffect.scale??y.ambientEffect.scale,this.ambientEffectOpacity=i.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let l=window.getComputedStyle(this.parentElement).position;l!=="relative"&&l!=="absolute"&&l!=="fixed"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminalgl-container",this.containerDiv.style.cssText=`
82
+ position: absolute !important;
83
+ top: 0 !important;
84
+ left: 0 !important;
85
+ right: 0 !important;
86
+ bottom: 0 !important;
87
+ width: 100% !important;
88
+ height: 100% !important;
89
+ overflow: visible !important;
90
+ contain: layout style !important;
91
+ display: flex !important;
92
+ justify-content: center !important;
93
+ align-items: center !important;
94
+ isolation: isolate !important;
95
+ pointer-events: none !important;
96
+ `,this.canvas=document.createElement("canvas"),this.canvas.className="terminalgl-webgl-canvas",this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.canvas.style.cssText=`
97
+ flex-shrink: 0 !important;
98
+ width: ${this.canvas.width}px !important;
99
+ height: ${this.canvas.height}px !important;
100
+ image-rendering: pixelated !important;
101
+ image-rendering: crisp-edges !important;
102
+ -ms-interpolation-mode: nearest-neighbor !important;
103
+ transform-origin: center center !important;
104
+ transform: scale(1) !important;
105
+ will-change: transform !important;
106
+ backface-visibility: hidden !important;
107
+ position: relative !important;
108
+ z-index: 1 !important;
109
+ pointer-events: auto !important;
110
+ touch-action: manipulation !important;
111
+ `;let h=this.canvas.getContext("webgl",{alpha:this.canvasBgColor===null,premultipliedAlpha:!1});if(!h)throw new Error("TerminalGL: WebGL not supported");this.gl=h,this.supportsUint32Indices=!!h.getExtension("OES_element_index_uint"),this.useUint16Indices=r||!this.supportsUint32Indices,this.vaoExtension=h.getExtension("OES_vertex_array_object"),this.instancedExtension=h.getExtension("ANGLE_instanced_arrays"),this.instancedExtension&&(this.useInstancing=!0),this.containerDiv.appendChild(this.canvas),this.ambientEffectEnabled&&this.createAmbientEffectCanvas(),this.parentElement.appendChild(this.containerDiv),this.initRenderBuffers();try{this.initWebGL()}catch(c){throw v.error("Failed to initialize WebGL",c),c}this.showGrid&&this.initGridOverlay(),this.setupResizeObserver()}initInstancedBuffers(){let e=this.gl;this.templateQuadPositions=new Float32Array([0,0,this.cellWidth,0,0,this.cellHeight,this.cellWidth,this.cellHeight]),this.templateQuadIndices=new Uint16Array([0,1,2,2,1,3]),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.templateQuadPositions,e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.templateQuadIndices,e.STATIC_DRAW),this.instanceData=new Float32Array(this.maxCells*8),e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer),e.bufferData(e.ARRAY_BUFFER,this.instanceData.byteLength,e.DYNAMIC_DRAW)}initRenderBuffers(){let e=this.cols*this.rows*2;this.maxCells=Math.ceil(e*2),this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.staticPositionsInitialized=!1}precomputeStaticPositions(){let e=this.cellWidth,i=this.cellHeight,s=this.glyphOffsetX,a=this.glyphOffsetY,r=this.charWidth,n=this.charHeight,o=0,l=0,h=0;for(let u=0;u<this.rows;u++){let d=Math.round(u*i),p=Math.round(d+i);for(let g=0;g<this.cols;g++){let f=Math.round(g*e),T=Math.round(f+e);this.renderPositions[o++]=f,this.renderPositions[o++]=d,this.renderPositions[o++]=T,this.renderPositions[o++]=d,this.renderPositions[o++]=f,this.renderPositions[o++]=p,this.renderPositions[o++]=T,this.renderPositions[o++]=p,this.renderIndices[l++]=h,this.renderIndices[l++]=h+1,this.renderIndices[l++]=h+2,this.renderIndices[l++]=h+2,this.renderIndices[l++]=h+1,this.renderIndices[l++]=h+3,h+=4;let C=Math.round(f+s),x=Math.round(d+a),D=Math.round(C+r),b=Math.round(x+n);this.renderPositions[o++]=C,this.renderPositions[o++]=x,this.renderPositions[o++]=D,this.renderPositions[o++]=x,this.renderPositions[o++]=C,this.renderPositions[o++]=b,this.renderPositions[o++]=D,this.renderPositions[o++]=b,this.renderIndices[l++]=h,this.renderIndices[l++]=h+1,this.renderIndices[l++]=h+2,this.renderIndices[l++]=h+2,this.renderIndices[l++]=h+1,this.renderIndices[l++]=h+3,h+=4}}let c=this.gl;c.bindBuffer(c.ARRAY_BUFFER,this.positionBuffer),c.bufferSubData(c.ARRAY_BUFFER,0,this.renderPositions),c.bindBuffer(c.ELEMENT_ARRAY_BUFFER,this.indexBuffer),c.bufferSubData(c.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let e=this.gl,i;this.useInstancing?i=`
112
+ // Per-vertex attributes (template quad)
113
+ attribute vec2 aPosition; // Local quad position (0,0 to cellW,cellH)
114
+
115
+ // Per-instance attributes (different for each cell)
116
+ attribute vec2 aInstanceOffset; // Cell grid position (col, row)
117
+ attribute vec4 aInstanceUVs; // Atlas UVs (u1, v1, u2, v2)
118
+ attribute vec2 aInstanceColors; // (bgColorIdx, fgColorIdx)
119
+
120
+ uniform vec2 uResolution;
121
+ uniform vec2 uCellSize; // (cellWidth, cellHeight)
122
+ uniform sampler2D uPalette;
123
+
124
+ varying vec2 vTexCoord;
125
+ varying vec4 vColor;
126
+
127
+ void main() {
128
+ // Compute world position: instance offset + local quad position
129
+ vec2 worldPos = aInstanceOffset * uCellSize + aPosition;
130
+ vec2 clipSpace = (worldPos / uResolution) * 2.0 - 1.0;
131
+ gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
132
+
133
+ // Interpolate UVs based on local position
134
+ vec2 localUV = aPosition / uCellSize; // (0,0) to (1,1)
135
+ vTexCoord = mix(
136
+ aInstanceUVs.xy, // top-left (u1, v1)
137
+ aInstanceUVs.zw, // bottom-right (u2, v2)
138
+ localUV
139
+ );
140
+
141
+ // Choose background or foreground color based on instance UVs
142
+ // If instance UVs are all (0,0), it's a background quad
143
+ float isBg = step(length(aInstanceUVs), 0.001);
144
+ float colorIndex = mix(aInstanceColors.y, aInstanceColors.x, isBg);
145
+
146
+ // Lookup color in palette
147
+ float paletteU = (colorIndex + 0.5) / 256.0;
148
+ vColor = texture2D(uPalette, vec2(paletteU, 0.5));
149
+ }
150
+ `:i=`
151
+ attribute vec2 aPosition;
152
+ attribute vec2 aTexCoord;
153
+ attribute float aColorIndex; // \u{1F680} Index dans palette (0-255)
154
+
155
+ uniform vec2 uResolution;
156
+ uniform sampler2D uPalette; // \u{1F680} Texture palette 256\xD71 RGBA
157
+
158
+ varying vec2 vTexCoord;
159
+ varying vec4 vColor;
160
+
161
+ void main() {
162
+ // Convert from pixels to clip space (-1 to 1)
163
+ vec2 clipSpace = (aPosition / uResolution) * 2.0 - 1.0;
164
+ gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
165
+
166
+ vTexCoord = aTexCoord;
167
+
168
+ // \u{1F680} Lookup couleur dans la palette texture (GPU-side)
169
+ float paletteU = (aColorIndex + 0.5) / 256.0;
170
+ vColor = texture2D(uPalette, vec2(paletteU, 0.5));
171
+ }
172
+ `;let s=`
173
+ precision mediump float;
174
+
175
+ uniform sampler2D uTexture;
176
+
177
+ varying vec2 vTexCoord;
178
+ varying vec4 vColor;
179
+
180
+ void main() {
181
+ // If texCoord is (0, 0), it's a background without texture
182
+ if (vTexCoord.x == 0.0 && vTexCoord.y == 0.0) {
183
+ gl_FragColor = vColor;
184
+ } else {
185
+ // Textured character: multiply atlas color by uniform color
186
+ // - White glyph (1,1,1) \u2192 uniform color applied normally
187
+ // - Colored glyph \u2192 atlas color \xD7 uniform color (multiply blend)
188
+ vec4 texColor = texture2D(uTexture, vTexCoord);
189
+ gl_FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a);
190
+ }
191
+ }
192
+ `,a=this.compileShader(e.VERTEX_SHADER,i),r=this.compileShader(e.FRAGMENT_SHADER,s);if(!a||!r)throw new Error("Shader compilation error");let n=e.createProgram();if(!n)throw new Error("Unable to create WebGL program");if(e.attachShader(n,a),e.attachShader(n,r),e.linkProgram(n),!e.getProgramParameter(n,e.LINK_STATUS)){let o=e.getProgramInfoLog(n);throw new Error("Program linking error: "+o)}this.program=n,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=e.getAttribLocation(n,"aPosition"),this.useInstancing?(this.aInstanceOffset=e.getAttribLocation(n,"aInstanceOffset"),this.aInstanceUVs=e.getAttribLocation(n,"aInstanceUVs"),this.aInstanceColors=e.getAttribLocation(n,"aInstanceColors"),this.uCellSize=e.getUniformLocation(n,"uCellSize"),this.instanceDataBuffer=e.createBuffer(),this.aTexCoord=this.aInstanceOffset,this.aColorIndex=this.aInstanceUVs):(this.aTexCoord=e.getAttribLocation(n,"aTexCoord"),this.aColorIndex=e.getAttribLocation(n,"aColorIndex")),this.uResolution=e.getUniformLocation(n,"uResolution"),this.uTexture=e.getUniformLocation(n,"uTexture"),this.uPalette=e.getUniformLocation(n,"uPalette"),this.positionBuffer=e.createBuffer(),this.texCoordBuffer=e.createBuffer(),this.colorIndexBuffer=e.createBuffer(),this.indexBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderPositions.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderTexCoords.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderColorIndices.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,e.DYNAMIC_DRAW),this.vaoExtension&&(this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(this.aPosition),e.vertexAttribPointer(this.aPosition,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.enableVertexAttribArray(this.aTexCoord),e.vertexAttribPointer(this.aTexCoord,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.enableVertexAttribArray(this.aColorIndex),e.vertexAttribPointer(this.aColorIndex,1,e.FLOAT,!1,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null))),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.viewport(0,0,this.canvas.width,this.canvas.height)}compileShader(e,i){let s=this.gl,a=s.createShader(e);return a?(s.shaderSource(a,i),s.compileShader(a),s.getShaderParameter(a,s.COMPILE_STATUS)?a:(v.error("Shader compilation error",s.getShaderInfoLog(a)),s.deleteShader(a),null)):null}initGridOverlay(){this.gridOverlay=new F(this.containerDiv,{strokeColor:"rgba(144, 24, 24, 1)",lineWidth:1,zIndex:10}),this.updateGridOverlay()}updateGridOverlay(){if(!this.gridOverlay)return;let e=this.cols*this.cellWidth,i=this.rows*this.cellHeight,s=this.canvas.getBoundingClientRect(),a=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,e,i,s,a),this.gridOverlay.render()}setBitmapFont(e,i,s,a=i,r=s){this.bitmapFont=e,this.fontLoaded=!0,this.charWidth=i,this.charHeight=s,this.cellWidth=a,this.cellHeight=r,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.generateAtlas(),this.updateCanvasSize()}generateAtlas(){if(!this.bitmapFont)return;this.atlasColumns=16;let e=256,i=this.atlasColumns*this.charWidth,s=Math.ceil(e/this.atlasColumns)*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=i,this.atlasCanvas.height=s;let a=this.atlasCanvas.getContext("2d",{willReadFrequently:!0});if(!a)return;a.clearRect(0,0,i,s);let r=Array.from(this.bitmapFont.keys());for(let n of r){let o=this.bitmapFont.get(n);if(!o)continue;let l=n%this.atlasColumns,h=Math.floor(n/this.atlasColumns),c=l*this.charWidth,u=h*this.charHeight;for(let d=0;d<this.charHeight&&!(d>=o.length);d++){let p=o[d];for(let g=0;g<this.charWidth;g++){let f=1<<7-g;p&f&&(a.fillStyle="#FFFFFF",a.fillRect(c+g,u+d,1,1))}}}this.cachedAtlasWidth=i,this.cachedAtlasHeight=s,this.createAtlasTexture(),this.charCodeToAtlasIndex.fill(65535);for(let n=0;n<e;n++)this.charCodeToAtlasIndex[n]=n}async setImageFontStructure(e,i,s,a,r){let n=this.atlasCanvas&&this.fontLoaded&&this.charWidth===Math.round(e)&&this.charHeight===Math.round(i),o=this.atlasCanvas;this.fontLoaded=!0,this.charWidth=Math.round(e),this.charHeight=Math.round(i),this.cellWidth=Math.round(s),this.cellHeight=Math.round(a),this.atlasColumns=B(r);let l=L(r);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers();let h=B(r);if(this.cachedAtlasWidth=h*this.charWidth,this.cachedAtlasHeight=h*this.charHeight,this.allocateAtlasTexture(this.cachedAtlasWidth,this.cachedAtlasHeight),n&&o){let c=this.gl;c.bindTexture(c.TEXTURE_2D,this.atlasTexture),c.texSubImage2D(c.TEXTURE_2D,0,0,0,c.RGBA,c.UNSIGNED_BYTE,o)}this.charCodeToAtlasIndex.fill(65535);for(let c=0;c<=l;c++)this.charCodeToAtlasIndex[c]=c;this.precomputeImageFontUVs(r),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions()}async setImageFontBlock(e,i){let s=this.gl;if(!this.atlasTexture)return;let a=new Blob([i],{type:"image/png"}),r=await createImageBitmap(a),n=this.atlasColumns/16,o=e%n,l=Math.floor(e/n),h=o*16*this.charWidth,c=l*16*this.charHeight;s.bindTexture(s.TEXTURE_2D,this.atlasTexture),s.texSubImage2D(s.TEXTURE_2D,0,h,c,s.RGBA,s.UNSIGNED_BYTE,r),r.close()}async setImageFont(e,i,s,a,r,n){this.fontLoaded=!0,this.charWidth=Math.round(i),this.charHeight=Math.round(s),this.cellWidth=Math.round(a),this.cellHeight=Math.round(r),this.atlasColumns=B(n);let o=L(n);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),await this.loadImageFontAtlas(e),this.charCodeToAtlasIndex.fill(65535);for(let l=0;l<=o;l++)this.charCodeToAtlasIndex[l]=l;this.precomputeImageFontUVs(n),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async loadImageFontAtlas(e){return new Promise((i,s)=>{let a=new Uint8Array(e),r=new Blob([a],{type:"image/png"}),n=URL.createObjectURL(r),o=new Image;o.onload=()=>{URL.revokeObjectURL(n),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=o.width,this.atlasCanvas.height=o.height;let l=this.atlasCanvas.getContext("2d");if(!l){s(new Error("Failed to create 2D context for atlas"));return}l.drawImage(o,0,0),this.cachedAtlasWidth=o.width,this.cachedAtlasHeight=o.height,this.createAtlasTexture(),i()},o.onerror=()=>{URL.revokeObjectURL(n),s(new Error("Failed to load PNG image for ImageFont atlas"))},o.src=n})}precomputeImageFontUVs(e){let i=e*256;this.atlasUVs=new Float32Array(i*4);let s=this.cachedAtlasWidth,a=this.cachedAtlasHeight,r=.5/s,n=.5/a;for(let o=0;o<i;o++){let{col:l,row:h}=Y(o,e),c=(l*this.charWidth+r)/s,u=(h*this.charHeight+n)/a,d=((l+1)*this.charWidth-r)/s,p=((h+1)*this.charHeight-n)/a,g=o*4;this.atlasUVs[g]=c,this.atlasUVs[g+1]=u,this.atlasUVs[g+2]=d,this.atlasUVs[g+3]=p}}allocateAtlasTexture(e,i){try{let s=this.gl,a=s.createTexture();if(!a)throw new Error("Unable to create texture");s.bindTexture(s.TEXTURE_2D,a),s.texImage2D(s.TEXTURE_2D,0,s.RGBA,e,i,0,s.RGBA,s.UNSIGNED_BYTE,null),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_WRAP_S,s.CLAMP_TO_EDGE),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_WRAP_T,s.CLAMP_TO_EDGE),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_MIN_FILTER,s.NEAREST),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_MAG_FILTER,s.NEAREST),this.atlasTexture=a}catch(s){throw v.error("Failed to create atlas texture",s),s}}createAtlasTexture(){if(this.atlasCanvas)try{let e=this.gl,i=e.createTexture();if(!i)throw new Error("Unable to create texture");e.bindTexture(e.TEXTURE_2D,i),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.atlasCanvas),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),this.atlasTexture=i}catch(e){throw v.error("Failed to create atlas texture",e),e}}clear(){let e=this.gl;e&&e.clear(e.COLOR_BUFFER_BIT)}parseColor(e){if(e.startsWith("#")){let i=e.slice(1),s=0,a=0,r=0;return i.length===3?(s=parseInt(i[0]+i[0],16),a=parseInt(i[1]+i[1],16),r=parseInt(i[2]+i[2],16)):i.length===6&&(s=parseInt(i.slice(0,2),16),a=parseInt(i.slice(2,4),16),r=parseInt(i.slice(4,6),16)),[s/255,a/255,r/255,1]}if(e.startsWith("rgb")){let i=e.match(/rgba?\(([^)]+)\)/);if(i){let s=i[1].split(",").map(a=>parseFloat(a.trim()));return[s[0]/255,s[1]/255,s[2]/255,s[3]!==void 0?s[3]:1]}}return[1,1,1,1]}setupResizeObserver(){if(!(typeof ResizeObserver>"u")){try{this.resizeObserver=new ResizeObserver(()=>{try{this.updateCanvasSize()}catch(e){v.error("Error in resize callback",e)}}),this.resizeObserver.observe(this.parentElement),this.updateCanvasSize()}catch(e){v.error("Failed to setup ResizeObserver",e)}this.boundWindowResize=()=>{try{this.updateCanvasSize()}catch(e){v.error("Error in window resize callback",e)}},window.addEventListener("resize",this.boundWindowResize)}}updateCanvasSize(){let e=this.parentElement.clientWidth,i=this.parentElement.clientHeight;if(e===0||i===0)return;let s=this.cols*this.cellWidth,a=this.rows*this.cellHeight;if(s===0||a===0)return;let r=e/s,n=i/a,o=Math.min(r,n),l;switch(this.scalingMode){case m.Integer:l=Math.max(1,Math.floor(o));break;case m.Half:l=Math.max(1,Math.floor(o*2)/2);break;case m.Quarter:l=Math.max(1,Math.floor(o*4)/4);break;case m.Eighth:l=Math.max(1,Math.floor(o*8)/8);break;case m.Responsive:l=1;break;case m.None:default:l=Math.max(.1,o);break}if(this.canvas.style.transform=`scale(${l})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let h=l*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${h})`}this.currentScale=l,this.onResizeCallback&&this.onResizeCallback(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}updateAmbientEffect(){!this.ambientEffectCanvas||!this.ambientEffectCtx||this.ambientEffectCtx.drawImage(this.canvas,0,0)}setPalette(e){let i=0,s=Math.min(e.length,256);for(let r=0;r<s;r++){let n=e[r];i=(i<<5)-i+n.r,i=(i<<5)-i+n.g,i=(i<<5)-i+n.b,i=(i<<5)-i+n.a,i=i|0}if(i===this.paletteHash)return;this.paletteHash=i,this.paletteFloat.fill(0);let a=15*4;this.paletteFloat[a]=1,this.paletteFloat[a+1]=1,this.paletteFloat[a+2]=1,this.paletteFloat[a+3]=1;for(let r=0;r<s;r++){let n=e[r],o=r*4;this.paletteFloat[o]=n.r/255,this.paletteFloat[o+1]=n.g/255,this.paletteFloat[o+2]=n.b/255,this.paletteFloat[o+3]=n.a/255}this.updatePaletteTexture()}updatePaletteTexture(){try{let e=this.gl;this.paletteTexture||(this.paletteTexture=e.createTexture()),e.bindTexture(e.TEXTURE_2D,this.paletteTexture);let i=new Uint8Array(256*4);for(let s=0;s<256;s++){let a=s*4;i[a]=this.paletteFloat[a]*255,i[a+1]=this.paletteFloat[a+1]*255,i[a+2]=this.paletteFloat[a+2]*255,i[a+3]=this.paletteFloat[a+3]*255}e.texImage2D(e.TEXTURE_2D,0,e.RGBA,256,1,0,e.RGBA,e.UNSIGNED_BYTE,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null)}catch(e){throw v.error("Failed to update palette texture",e),e}}renderDisplayData(e){try{if(!this.isReady())return;(e.width!==this.cols||e.height!==this.rows)&&this.resize(e.width,e.height),e.passes&&e.passes.length>0?this.renderMultiPass(e,e.passes):this.renderDirect(e),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(i){v.error("Error rendering display data",i)}}renderMultiPass(e,i){for(let s=0;s<i.length;s++){let a=i[s],r={id:e.id,width:e.width,height:e.height,palette:e.palette,cells:a.cells};this.renderDirect(r,s===0)}}renderDirect(e,i=!0){let s=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),i){if(this.canvasBgColor!==null){let a=this.parseColor(this.canvasBgColor);s.clearColor(a[0],a[1],a[2],a[3])}else s.clearColor(0,0,0,0);s.clear(s.COLOR_BUFFER_BIT)}this.useInstancing?this.renderInstanced(e):this.renderDirectBuffers(e)}renderInstanced(e){let i=this.gl,s=this.instancedExtension;if(!this.instanceData||this.instanceData.length===0){this.renderDirectBuffers(e);return}let a=0,r=this.instanceData.length/8,n=e.width*e.height*2;if(n>r){v.error(`Instance buffer too small! Need ${n}, have ${r}. Display size: ${e.width}\xD7${e.height}, buffer was sized for smaller terminal.`),this.renderDirectBuffers(e);return}for(let l=0;l<e.height;l++)for(let h=0;h<e.width;h++){let c=e.cells[l*e.width+h],u=c.bgColorIndex,d=c.fgColorIndex,p=this.canvasBgColor!==null&&u===255,g=c.char===" "||d===255;if(!p){if(a>=r){v.error(`Instance buffer overflow! instanceIdx=${a}, max=${r}`);break}let f=a*8;this.instanceData[f]=h,this.instanceData[f+1]=l,this.instanceData[f+2]=0,this.instanceData[f+3]=0,this.instanceData[f+4]=0,this.instanceData[f+5]=0,this.instanceData[f+6]=u,this.instanceData[f+7]=0,a++}if(!g){let f=c.char.charCodeAt(0),T=this.charCodeToAtlasIndex[f];if(T!==65535){if(a>=r){v.error(`Instance buffer overflow! instanceIdx=${a}, max=${r}`);break}let C=T*4,x=a*8;this.instanceData[x]=h,this.instanceData[x+1]=l,this.instanceData[x+2]=this.atlasUVs[C],this.instanceData[x+3]=this.atlasUVs[C+1],this.instanceData[x+4]=this.atlasUVs[C+2],this.instanceData[x+5]=this.atlasUVs[C+3],this.instanceData[x+6]=0,this.instanceData[x+7]=d,a++}}}if(a===0)return;i.bindBuffer(i.ARRAY_BUFFER,this.instanceDataBuffer),i.bufferSubData(i.ARRAY_BUFFER,0,this.instanceData.subarray(0,a*8)),i.useProgram(this.program),i.bindBuffer(i.ARRAY_BUFFER,this.positionBuffer),i.enableVertexAttribArray(this.aPosition),i.vertexAttribPointer(this.aPosition,2,i.FLOAT,!1,0,0),s.vertexAttribDivisorANGLE(this.aPosition,0),i.bindBuffer(i.ARRAY_BUFFER,this.instanceDataBuffer);let o=8*Float32Array.BYTES_PER_ELEMENT;i.enableVertexAttribArray(this.aInstanceOffset),i.vertexAttribPointer(this.aInstanceOffset,2,i.FLOAT,!1,o,0),s.vertexAttribDivisorANGLE(this.aInstanceOffset,1),i.enableVertexAttribArray(this.aInstanceUVs),i.vertexAttribPointer(this.aInstanceUVs,4,i.FLOAT,!1,o,2*Float32Array.BYTES_PER_ELEMENT),s.vertexAttribDivisorANGLE(this.aInstanceUVs,1),i.enableVertexAttribArray(this.aInstanceColors),i.vertexAttribPointer(this.aInstanceColors,2,i.FLOAT,!1,o,6*Float32Array.BYTES_PER_ELEMENT),s.vertexAttribDivisorANGLE(this.aInstanceColors,1),i.uniform2f(this.uResolution,this.canvas.width,this.canvas.height),i.uniform2f(this.uCellSize,this.cellWidth,this.cellHeight),i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,this.atlasTexture),i.uniform1i(this.uTexture,0),i.activeTexture(i.TEXTURE1),i.bindTexture(i.TEXTURE_2D,this.paletteTexture),i.uniform1i(this.uPalette,1),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,this.indexBuffer),s.drawElementsInstancedANGLE(i.TRIANGLES,6,i.UNSIGNED_SHORT,0,a),s.vertexAttribDivisorANGLE(this.aPosition,0),s.vertexAttribDivisorANGLE(this.aInstanceOffset,0),s.vertexAttribDivisorANGLE(this.aInstanceUVs,0),s.vertexAttribDivisorANGLE(this.aInstanceColors,0)}renderDirectBuffers(e){let i=this.gl,s=e.width*e.height,a=s*2;if(a>this.maxCells){v.error(`Buffer overflow detected! Trying to render ${a} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let r=0,n=0,o=e.cells,l=s;for(let p=0;p<l;p++){let g=o[p],f=g.bgColorIndex,T=this.canvasBgColor!==null&&f===255?255:f,C=0;for(let b=0;b<4;b++)this.renderTexCoords[r++]=C,this.renderTexCoords[r++]=C,this.renderColorIndices[n++]=T;let x=g.fgColorIndex,D=g.char;if(D===" "||D==="\0"||x===255)for(let b=0;b<4;b++)this.renderTexCoords[r++]=0,this.renderTexCoords[r++]=0,this.renderColorIndices[n++]=255;else{let b=D.charCodeAt(0),k=this.charCodeToAtlasIndex[b];if(k!==65535){let A=k*4,H=this.atlasUVs[A],N=this.atlasUVs[A+1],$=this.atlasUVs[A+2],V=this.atlasUVs[A+3];this.renderTexCoords[r++]=H,this.renderTexCoords[r++]=N,this.renderColorIndices[n++]=x,this.renderTexCoords[r++]=$,this.renderTexCoords[r++]=N,this.renderColorIndices[n++]=x,this.renderTexCoords[r++]=H,this.renderTexCoords[r++]=V,this.renderColorIndices[n++]=x,this.renderTexCoords[r++]=$,this.renderTexCoords[r++]=V,this.renderColorIndices[n++]=x}else for(let A=0;A<4;A++)this.renderTexCoords[r++]=0,this.renderTexCoords[r++]=0,this.renderColorIndices[n++]=255}}(r!==l*2*4*2||n!==l*2*4)&&v.error("Buffer index mismatch!",{texIdx:r,colorIdx:n,expected:l*2*4}),i.useProgram(this.program),this.vao&&this.vaoExtension?(this.vaoExtension.bindVertexArrayOES(this.vao),i.bindBuffer(i.ARRAY_BUFFER,this.texCoordBuffer),i.bufferSubData(i.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,r)),i.bindBuffer(i.ARRAY_BUFFER,this.colorIndexBuffer),i.bufferSubData(i.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,n))):(i.bindBuffer(i.ARRAY_BUFFER,this.positionBuffer),i.enableVertexAttribArray(this.aPosition),i.vertexAttribPointer(this.aPosition,2,i.FLOAT,!1,0,0),i.bindBuffer(i.ARRAY_BUFFER,this.texCoordBuffer),i.bufferSubData(i.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,r)),i.enableVertexAttribArray(this.aTexCoord),i.vertexAttribPointer(this.aTexCoord,2,i.FLOAT,!1,0,0),i.bindBuffer(i.ARRAY_BUFFER,this.colorIndexBuffer),i.bufferSubData(i.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,n)),i.enableVertexAttribArray(this.aColorIndex),i.vertexAttribPointer(this.aColorIndex,1,i.FLOAT,!1,0,0));let h=this.canvas.width,c=this.canvas.height;(this.cachedResolution[0]!==h||this.cachedResolution[1]!==c)&&(i.uniform2f(this.uResolution,h,c),this.cachedResolution[0]=h,this.cachedResolution[1]=c),this.cachedTextureUnit!==0&&(i.activeTexture(i.TEXTURE0),this.cachedTextureUnit=0),i.bindTexture(i.TEXTURE_2D,this.atlasTexture),this.cachedTextureUniform||(i.uniform1i(this.uTexture,0),this.cachedTextureUniform=!0),this.cachedPaletteUnit!==1&&(i.activeTexture(i.TEXTURE1),this.cachedPaletteUnit=1),i.bindTexture(i.TEXTURE_2D,this.paletteTexture),this.cachedPaletteUniform||(i.uniform1i(this.uPalette,1),this.cachedPaletteUniform=!0),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,this.indexBuffer);let u=e.width*e.height*2*6,d=this.useUint16Indices?i.UNSIGNED_SHORT:i.UNSIGNED_INT;i.drawElements(i.TRIANGLES,u,d,0)}resize(e,i){if(!Number.isInteger(e)||e<=0){v.error(`Invalid cols: ${e}. Must be positive integer.`);return}if(!Number.isInteger(i)||i<=0){v.error(`Invalid rows: ${i}. Must be positive integer.`);return}if(e===this.cols&&i===this.rows)return;let s=e*i,a=this.useInstancing?262144:this.useUint16Indices?8191:262144;if(s>a){let h=Math.floor(Math.sqrt(a));v.error(`Cannot resize to ${e}\xD7${i} (${s} cells). Device limit: ${a} cells (max ~${h}\xD7${h}). ${!this.useInstancing&&this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}this.cols=e,this.rows=i,this.staticPositionsInitialized=!1;let r=this.cols*this.rows*2,n=Math.ceil(r*1.5),o=r>this.maxCells,l=this.maxCells>n*4;if(o||l){if(this.maxCells=n,this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.useInstancing&&this.instanceDataBuffer){this.instanceData=new Float32Array(this.maxCells*8);let c=this.gl;c.bindBuffer(c.ARRAY_BUFFER,this.instanceDataBuffer),c.bufferData(c.ARRAY_BUFFER,this.instanceData.byteLength,c.DYNAMIC_DRAW)}let h=this.gl;this.useInstancing||(h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderPositions.byteLength,h.DYNAMIC_DRAW)),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderTexCoords.byteLength,h.DYNAMIC_DRAW),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderColorIndices.byteLength,h.DYNAMIC_DRAW),this.useInstancing||(h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),h.bufferData(h.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,h.DYNAMIC_DRAW)),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.enableVertexAttribArray(this.aPosition),h.vertexAttribPointer(this.aPosition,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.enableVertexAttribArray(this.aTexCoord),h.vertexAttribPointer(this.aTexCoord,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.enableVertexAttribArray(this.aColorIndex),h.vertexAttribPointer(this.aColorIndex,1,h.FLOAT,!1,0,0),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)))}this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.canvas.style.width=`${this.canvas.width}px`,this.canvas.style.height=`${this.canvas.height}px`,this.ambientEffectEnabled&&this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.width=`${this.canvas.width}px`,this.ambientEffectCanvas.style.height=`${this.canvas.height}px`),this.showGrid&&this.gridOverlay&&this.updateGridOverlay(),this.updateCanvasSize()}getCanvas(){return this.canvas}getGridSize(){return{cols:this.cols,rows:this.rows}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getBaseDimensions(){return{width:this.cols*this.cellWidth,height:this.rows*this.cellHeight}}setOnResizeCallback(e){this.onResizeCallback=e}clearOnResizeCallback(){this.onResizeCallback=void 0}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}setScalingMode(e){this.scalingMode!==e&&(this.scalingMode=e,this.updateCanvasSize())}getScalingMode(){return this.scalingMode}setCellSize(e,i){let s=Math.max(1,Math.min(255,Math.round(e))),a=Math.max(1,Math.min(255,Math.round(i)));this.cellWidth===s&&this.cellHeight===a||(this.cellWidth=s,this.cellHeight=a,this.charWidth=s,this.charHeight=a,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.updateCanvasSize())}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getMaxCells(){return this.useInstancing?262144:this.useUint16Indices?8191:262144}setGrid(e){e.enabled?(this.gridOverlay?this.gridOverlay.setStyle({strokeColor:e.color,lineWidth:e.lineWidth}):this.gridOverlay=new F(this.containerDiv,{strokeColor:e.color??"rgba(144, 24, 24, 1)",lineWidth:e.lineWidth??1,zIndex:10}),this.showGrid=!0,this.gridOverlay.setVisible(!0),this.updateGridOverlay()):(this.showGrid=!1,this.gridOverlay&&this.gridOverlay.setVisible(!1))}isGridEnabled(){return this.showGrid}setAmbientEffect(e){typeof e=="boolean"?this.ambientEffectEnabled=e:(this.ambientEffectEnabled=!0,e.blur!==void 0&&(this.ambientEffectBlur=e.blur),e.scale!==void 0&&(this.ambientEffectScale=e.scale)),this.ambientEffectEnabled&&!this.ambientEffectCanvas&&this.createAmbientEffectCanvas(),this.ambientEffectCanvas&&(this.ambientEffectEnabled?(this.ambientEffectCanvas.style.display="block",this.ambientEffectCanvas.style.filter=`blur(${this.ambientEffectBlur}px)`,this.ambientEffectCanvas.style.transform=`scale(${this.ambientEffectScale})`,this.updateAmbientEffect()):this.ambientEffectCanvas.style.display="none")}createAmbientEffectCanvas(){this.ambientEffectCanvas||(this.ambientEffectCanvas=document.createElement("canvas"),this.ambientEffectCanvas.className="terminalgl-ambient-effect-canvas",this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.cssText=`
193
+ display: block !important;
194
+ position: absolute !important;
195
+ width: ${this.canvas.width}px !important;
196
+ height: ${this.canvas.height}px !important;
197
+ filter: blur(${this.ambientEffectBlur}px) !important;
198
+ opacity: ${this.ambientEffectOpacity} !important;
199
+ transform-origin: center center !important;
200
+ transform: scale(${this.ambientEffectScale}) !important;
201
+ pointer-events: none !important;
202
+ z-index: 0 !important;
203
+ `,this.ambientEffectCtx=this.ambientEffectCanvas.getContext("2d",{alpha:!0}),this.containerDiv.insertBefore(this.ambientEffectCanvas,this.canvas))}isAmbientEffectEnabled(){return this.ambientEffectEnabled}getAmbientEffectConfig(){return{enabled:this.ambientEffectEnabled,blur:this.ambientEffectBlur,scale:this.ambientEffectScale}}getCols(){return this.cols}getRows(){return this.rows}isReady(){return!!(this.fontLoaded&&this.atlasTexture&&this.program)}destroy(){this.dispose()}dispose(){this.resizeObserver&&this.resizeObserver.disconnect(),this.boundWindowResize&&(window.removeEventListener("resize",this.boundWindowResize),this.boundWindowResize=void 0);let e=this.gl;this.program&&e.deleteProgram(this.program),this.positionBuffer&&e.deleteBuffer(this.positionBuffer),this.texCoordBuffer&&e.deleteBuffer(this.texCoordBuffer),this.colorIndexBuffer&&e.deleteBuffer(this.colorIndexBuffer),this.indexBuffer&&e.deleteBuffer(this.indexBuffer),this.instanceDataBuffer&&e.deleteBuffer(this.instanceDataBuffer),this.atlasTexture&&e.deleteTexture(this.atlasTexture),this.paletteTexture&&e.deleteTexture(this.paletteTexture),this.vao&&this.vaoExtension&&this.vaoExtension.deleteVertexArrayOES(this.vao);let i=e.getExtension("WEBGL_lose_context");i&&i.loseContext(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv),this.canvas.width=0,this.canvas.height=0,this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=0,this.ambientEffectCanvas.height=0,this.ambientEffectCanvas=null),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.renderPositions=new Float32Array(0),this.renderTexCoords=new Float32Array(0),this.renderColorIndices=new Float32Array(0),this.renderIndices=new Uint32Array(0),this.paletteFloat=new Float32Array(0),this.atlasUVs=new Float32Array(0),this.instanceData=new Float32Array(0),this.templateQuadPositions=new Float32Array(0),this.templateQuadIndices=new Uint16Array(0)}},O="\x1B[0m",st="\x1B[H",kt="\x1B[2J",at="\x1B[?25l",Ht="\x1B[?25h",Nt=`
204
+ `,$t=class{options;fgCache=[];bgCache=[];lastPalette=null;constructor(t={}){this.options={optimizeColors:t.optimizeColors??!0,includeHome:t.includeHome??!0,hideCursor:t.hideCursor??!0,includeNewlines:t.includeNewlines??!0,includeReset:t.includeReset??!0}}buildColorCache(t){if(this.lastPalette!==t){this.fgCache=new Array(t.length),this.bgCache=new Array(t.length);for(let e=0;e<t.length;e++){let i=t[e];this.fgCache[e]=`\x1B[38;2;${i.r};${i.g};${i.b}m`,this.bgCache[e]=`\x1B[48;2;${i.r};${i.g};${i.b}m`}this.lastPalette=t}}render(t){let{width:e,height:i,cells:s,palette:a}=t;this.buildColorCache(a);let r="";this.options.hideCursor&&(r+=at),this.options.includeHome&&(r+=st);let n=-1,o=-1,l=this.options.optimizeColors,h=this.options.includeNewlines;for(let c=0;c<i;c++){let u=c*e;for(let d=0;d<e;d++){let p=s[u+d],g=p.fgColorIndex,f=p.bgColorIndex;l?(f!==o&&(r+=this.bgCache[f],o=f),g!==n&&(r+=this.fgCache[g],n=g)):(r+=this.bgCache[f],r+=this.fgCache[g]),r+=p.char||" "}h&&c<i-1&&(r+=Nt)}return this.options.includeReset&&(r+=O),r}renderRow(t,e){let{width:i,cells:s,palette:a}=t;this.buildColorCache(a);let r=`\x1B[${e+1};1H`,n=-1,o=-1,l=this.options.optimizeColors,h=e*i;for(let c=0;c<i;c++){let u=s[h+c],d=u.fgColorIndex,p=u.bgColorIndex;l?(p!==o&&(r+=this.bgCache[p],o=p),d!==n&&(r+=this.fgCache[d],n=d)):(r+=this.bgCache[p],r+=this.fgCache[d]),r+=u.char||" "}return this.options.includeReset&&(r+=O),r}clear(){return kt+st}showCursor(){return Ht}hideCursor(){return at}reset(){return O}moveTo(t,e){return`\x1B[${t+1};${e+1}H`}};function Vt(t){let e=t.startsWith("#")?t.slice(1):t,i=e.length===3?e[0]+e[0]+e[1]+e[1]+e[2]+e[2]:e,s=parseInt(i,16);return{r:s>>16&255,g:s>>8&255,b:s&255,a:255}}function Kt(t){let e=t.r.toString(16).padStart(2,"0"),i=t.g.toString(16).padStart(2,"0"),s=t.b.toString(16).padStart(2,"0");return`#${e}${i}${s}`}function qt(t,e){let i=[{r:0,g:0,b:0,a:255},{r:128,g:0,b:0,a:255},{r:0,g:128,b:0,a:255},{r:128,g:128,b:0,a:255},{r:0,g:0,b:128,a:255},{r:128,g:0,b:128,a:255},{r:0,g:128,b:128,a:255},{r:192,g:192,b:192,a:255},{r:128,g:128,b:128,a:255},{r:255,g:0,b:0,a:255},{r:0,g:255,b:0,a:255},{r:255,g:255,b:0,a:255},{r:0,g:0,b:255,a:255},{r:255,g:0,b:255,a:255},{r:0,g:255,b:255,a:255},{r:255,g:255,b:255,a:255}];for(;i.length<256;)i.push({r:128,g:128,b:128,a:255});let s=[];for(let a=0;a<e;a++)for(let r=0;r<t;r++)s.push({char:String.fromCharCode(65+(r+a)%26),fgColorIndex:15,bgColorIndex:(r+a)%16,fgEmission:0,bgEmission:0});return{id:0,width:t,height:e,cells:s,palette:i}}
@@ -0,0 +1 @@
1
+ export * from '@primitiv/render';