diff --git a/basalt.lua b/basalt.lua index b852a5c..aa21070 100644 --- a/basalt.lua +++ b/basalt.lua @@ -1 +1 @@ -local a={basaltBG=colors.lightGray,basaltFG=colors.black,FrameBG=colors.gray,FrameFG=colors.black,ButtonBG=colors.gray,ButtonFG=colors.black,CheckboxBG=colors.gray,CheckboxFG=colors.black,InputBG=colors.gray,InputFG=colors.black,textfieldBG=colors.gray,textfieldFG=colors.black,listBG=colors.gray,listFG=colors.black,dropdownBG=colors.gray,dropdownFG=colors.black,radioBG=colors.gray,radioFG=colors.black,selectionBG=colors.black,selectionFG=colors.lightGray}local b={debugger=true,version=1}local c;local d={}local e={}local f=term.current()local g=string.sub;local function h(i,j,k)local i=string.sub(i,1,j)local l=j-string.len(i)if k=="right"then i=string.rep(" ",l)..i elseif k=="center"then i=string.rep(" ",math.floor(l/2))..i..string.rep(" ",math.floor(l/2))i=i..(string.len(i)=1 and M<=n then if L+i:len()>0 and L<=j then local N=v[M]local O;local P=L+#i-1;if L<1 then local Q=1-L+1;local R=j-L+1;i=g(i,Q,R)elseif P>j then local R=j-L+1;i=g(i,1,R)end;if L>1 then local R=L-1;O=g(N,1,R)..i else O=i end;if P=1 and M<=n then if L+T:len()>0 and L<=j then local N=w[M]local O;local P=L+#T-1;if L<1 then T=g(T,1-L+1,j-L+1)elseif P>j then T=g(T,1,j-L+1)end;if L>1 then O=g(N,1,L-1)..T else O=T end;if P=1 and M<=n then if L+T:len()>0 and L<=j then local N=x[M]local O;local P=L+#T-1;if L<1 then local Q=1-L+1;local R=j-L+1;T=g(T,Q,R)elseif P>j then local R=j-L+1;T=g(T,1,R)end;if L>1 then local R=L-1;O=g(N,1,R)..T else O=T end;if PL and aM<=M and aM+self.h>M and ar then if self.parent~=nil then self.parent:setFocusedObject(self)end;at:sendEvent(a5,self,a5,aK,L,M)return true end;return false end,keyHandler=function(self,a5,aN)if self:isFocused()then at:sendEvent(a5,self,a5,aN)return true end;return false end,backgroundKeyHandler=function(self,a5,aN)at:sendEvent("background_"..a5,self,a5,aN)end,valueChangedHandler=function(self)at:sendEvent("value_changed",self)end,eventHandler=function(self,a5,aO,aP,aQ,aR)at:sendEvent("custom_event_handler",self,a5,aO,aP,aQ,aR)end,getFocusHandler=function(self)at:sendEvent("get_focus",self)end,loseFocusHandler=function(self)at:sendEvent("lose_focus",self)end}au.__index=au;return au end;local function aS(ak)local aT=aj(ak)local al="Button"aT:setValue("Button")aT:setZIndex(5)aT.w=8;aT.bgcolor=a.ButtonBG;aT.fgcolor=a.ButtonFG;local aU="center"local aV="center"local au={getType=function(self)return al end,setHorizontalAlign=function(self,aW)aU=aW end,setVerticalAlign=function(self,aW)aV=aW end,setText=function(self,i)aT:setValue(i)return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.h,aV)self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)self.parent:drawTextBox(aX,aY,self.w,self.h," ")for l=1,self.h do if l==aZ then self.parent:setText(aX,aY+l-1,h(self:getValue(),self.w,aU))end end end end end}return setmetatable(au,aT)end;local function a_(ak)local aT=aj(ak)local al="Program"aT:setZIndex(5)local au;local function b0(L,M,j,n)local b1,b2=1,1;local b3,b4=colors.black,colors.white;local b5=false;local b6=false;local v={}local w={}local x={}local b7={}local B;local C={}for r=0,15 do local b8=2^r;b7[b8]={f.getPaletteColour(b8)}end;local function D()B=(" "):rep(j)for l=0,15 do local E=2^l;local F=s[E]C[E]=F:rep(j)end end;local function G()D()local H=B;local I=C[colors.white]local J=C[colors.black]for l=1,n do v[l]=g(v[l]==nil and H or v[l]..H:sub(1,j-v[l]:len()),1,j)x[l]=g(x[l]==nil and I or x[l]..I:sub(1,j-x[l]:len()),1,j)w[l]=g(w[l]==nil and J or w[l]..J:sub(1,j-w[l]:len()),1,j)end end;G()local function b9()if b1>=1 and b2>=1 and b1<=j and b2<=n then else end end;local function ba(bb,bc,bd)local be=b1;local P=be+#bb-1;if b2>=1 and b2<=n then if be<=j and P>=1 then if be==1 and P==j then v[b2]=bb;x[b2]=bc;w[b2]=bd else local bf,bg,bh;if be<1 then local bi=1-be+1;local bj=j-be+1;bf=g(bb,bi,bj)bg=g(bc,bi,bj)bh=g(bd,bi,bj)elseif P>j then local bj=j-be+1;bf=g(bb,1,bj)bg=g(bc,1,bj)bh=g(bd,1,bj)else bf=bb;bg=bc;bh=bd end;local bk=v[b2]local bl=x[b2]local bm=w[b2]local bn,bo,bp;if be>1 then local bq=be-1;bn=g(bk,1,bq)..bf;bo=g(bl,1,bq)..bg;bp=g(bm,1,bq)..bh else bn=bf;bo=bg;bp=bh end;if P=1 and M<=n then v[bO]=v[M]w[bO]=w[M]x[bO]=x[M]else v[bO]=bL;x[bO]=bM;w[bO]=bN end end end;if b6 then b9()end end,isColor=function()return f.isColor()end,isColour=function()return f.isColor()end,write=function(i)i=tostring(i)if b6 then ba(i,s[b4]:rep(i:len()),s[b3]:rep(i:len()))end end,clearLine=function()if b6 then K(1,b2,(" "):rep(j))S(1,b2,s[b3]:rep(j))U(1,b2,s[b4]:rep(j))end;if b6 then b9()end end,clear=function()for l=1,n do K(1,l,(" "):rep(j))S(1,l,s[b3]:rep(j))U(1,l,s[b4]:rep(j))end;if b6 then b9()end end,blit=function(i,bP,bQ)if type(i)~="string"then error("bad argument #1 (expected string, got "..type(i)..")",2)end;if type(bP)~="string"then error("bad argument #2 (expected string, got "..type(bP)..")",2)end;if type(bQ)~="string"then error("bad argument #3 (expected string, got "..type(bQ)..")",2)end;if#bP~=#i or#bQ~=#i then error("Arguments must be the same length",2)end;if b6 then ba(i,bP,bQ)end end}return bG end;aT.w=30;aT.h=12;local bR=b0(1,1,aT.w,aT.h)local bS;local bT=false;local bU={}au={getType=function(self)return al end,show=function(self)aT.show(self)bR.setBackgroundColor(self.bgcolor)bR.setTextColor(self.fgcolor)bR.basalt_setVisible(true)return self end,hide=function(self)aT.hide(self)bR.basalt_setVisible(false)return self end,setPosition=function(self,L,M,aA)aT.setPosition(self,L,M,aA)bR.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return bR end,getBasaltProcess=function()return bS end,setSize=function(self,j,n)aT.setSize(self,j,n)bR.basalt_resize(self.w,self.h)return self end,getStatus=function(self)if bS~=nil then return bS:getStatus()end;return"inactive"end,execute=function(self,ad,...)bS=ab:new(ad,bR,...)bR.setBackgroundColor(colors.black)bR.setTextColor(colors.white)bR.clear()bR.setCursorPos(1,1)bS:resume()bT=false;return self end,stop=function(self)if bS~=nil then if not bS:isDead()then bS:resume("terminate")if bS:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,bV)bT=bV or not bT;if bS~=nil then if not bS:isDead()then if not bT then self:injectEvents(bU)bU={}end end end;return self end,isPaused=function(self)return bT end,injectEvent=function(self,a5,aO,aP,aQ,aR,bW)if bS~=nil then if not bS:isDead()then if bT==false or bW then bS:resume(a5,aO,aP,aQ,aR)else table.insert(bU,{event=a5,args={aO,aP,aQ,aR}})end end end;return self end,getQueuedEvents=function(self)return bU end,updateQueuedEvents=function(self,a3)bU=a3 or bU;return self end,injectEvents=function(self,a3)if bS~=nil then if not bS:isDead()then for aJ,a9 in pairs(a3)do bS:resume(a9.event,table.unpack(a9.args))end end end;return self end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then if bS==nil then return false end;if not bS:isDead()then if not bT then local bX,bY=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))bS:resume(a5,aK,L-bX+1,M-bY+1)end end;return true end end,keyHandler=function(self,a5,aN)aT.keyHandler(self,a5,aN)if self:isFocused()then if bS==nil then return false end;if not bS:isDead()then if not bT then if self.draw then bS:resume(a5,aN)end end end end end,getFocusHandler=function(self)aT.getFocusHandler(self)if bS~=nil then if not bS:isDead()then if not bT then if self.parent~=nil then local bZ,b_=bR.getCursorPos()local aX,aY=self:getAnchorPosition()if self.parent~=nil then if aX+bZ-1>=1 and aX+bZ-1<=aX+self.w-1 and b_+aY-1>=1 and b_+aY-1<=aY+self.h-1 then self.parent:setCursor(bR.getCursorBlink(),aX+bZ-1,b_+aY-1,bR.getTextColor())end end end end end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if bS~=nil then if not bS:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,a5,aO,aP,aQ,aR)if bS==nil then return end;if not bS:isDead()then if not bT then if a5~="mouse_click"and a5~="mouse_up"and a5~="mouse_scroll"and a5~="mouse_drag"and a5~="key_up"and a5~="key"and a5~="char"and a5~="terminate"then bS:resume(a5,aO,aP,aQ,aR)end;if self:isFocused()then local aX,aY=self:getAnchorPosition()local bZ,b_=bR.getCursorPos()if self.parent~=nil then if aX+bZ-1>=1 and aX+bZ-1<=aX+self.w-1 and b_+aY-1>=1 and b_+aY-1<=aY+self.h-1 then self.parent:setCursor(bR.getCursorBlink(),aX+bZ-1,b_+aY-1,bR.getTextColor())end end;if a5=="terminate"and self:isFocused()then self:stop()end end else if a5~="mouse_click"and a5~="mouse_up"and a5~="mouse_scroll"and a5~="mouse_drag"and a5~="key_up"and a5~="key"and a5~="char"and a5~="terminate"then table.insert(bU,{event=a5,args={aO,aP,aQ,aR}})end end end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()bR.basalt_reposition(aX,aY)self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)bR.basalt_update()end end end}return setmetatable(au,aT)end;local function c0(ak)local aT=aj(ak)local al="Label"aT:setZIndex(3)local c1=true;aT:setValue("")local au={getType=function(self)return al end,setText=function(self,i)i=tostring(i)aT:setValue(i)if c1 then self.w=i:len()end;return self end,setSize=function(self,j,n)self.w,self.h=j,n;c1=false;return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:writeText(aX,aY,self:getValue(),self.bgcolor,self.fgcolor)end end end}return setmetatable(au,aT)end;local function c2(ak)local aT=aj(ak)local al="Pane"local au={getType=function(self)return al end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)end end end}return setmetatable(au,aT)end;local function c3(ak)local aT=aj(ak)local al="Image"aT:setZIndex(2)local c4;local function c5()end;local au={getType=function(self)return al end,loadImage=function(self,ad)c4=paintutils.loadImage(ad)return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then if c4~=nil then local aX,aY=self:getAnchorPosition()for az=1,math.min(#c4,self.h)do local c6=c4[az]for ay=1,math.min(#c6,self.w)do if c6[ay]>0 then self.parent:drawBackgroundBox(aX+ay-1,aY+az-1,1,1,c6[ay])end end end end end end end}return setmetatable(au,aT)end;local function c7(ak)local aT=aj(ak)local al="Checkbox"aT:setZIndex(5)aT:setValue(false)aT.w=1;aT.h=1;aT.bgcolor=a.CheckboxBG;aT.fgcolor=a.CheckboxFG;local au={symbol="\42",getType=function(self)return al end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then if a5=="mouse_click"and aK==1 then if self:getValue()~=true and self:getValue()~=false then self:setValue(false)else self:setValue(not self:getValue())end end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.h,"center")self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)for l=1,self.h do if l==aZ then if self:getValue()==true then self.parent:writeText(aX,aY+l-1,h(self.symbol,self.w,"center"),self.bgcolor,self.fgcolor)else self.parent:writeText(aX,aY+l-1,h(" ",self.w,"center"),self.bgcolor,self.fgcolor)end end end end end end}return setmetatable(au,aT)end;local function c8(ak)local aT=aj(ak)local al="Input"local c9="text"local ca=0;aT:setZIndex(5)aT:setValue("")aT.w=10;aT.h=1;aT.bgcolor=a.InputBG;aT.fgcolor=a.InputFG;local cb=1;local cc=1;local cd=""local ce;local cf;local cg=cd;local ch=false;local au={getType=function(self)return al end,setInputType=function(self,ci)if ci=="password"or ci=="number"or ci=="text"then c9=ci end;return self end,setDefaultText=function(self,i,cj,ck)cd=i;ce=ck or ce;cf=cj or cf;if self:isFocused()then cg=""else cg=cd end;return self end,getInputType=function(self)return c9 end,setValue=function(self,cl)aT.setValue(self,tostring(cl))if not ch then cb=tostring(cl):len()+1 end;return self end,getValue=function(self)local cl=aT.getValue(self)return c9=="number"and tonumber(cl)or cl end,setInputLimit=function(self,cm)ca=tonumber(cm)or ca;return self end,getInputLimit=function(self)return ca end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then local aX,aY=self:getAnchorPosition()cg=""if self.parent~=nil then self.parent:setCursor(true,aX+cb-cc,aY,self.fgcolor)end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)cg=cd end end,keyHandler=function(self,a5,aN)if aT.keyHandler(self,a5,aN)then ch=true;if a5=="key"then if aN==keys.backspace then local i=tostring(aT.getValue())if cb>1 then self:setValue(i:sub(1,cb-2)..i:sub(cb,i:len()))if cb>1 then cb=cb-1 end;if cc>1 then if cbcn then cb=cn+1 end;if cb<1 then cb=1 end;if cb=self.w+cc then cc=cb-self.w+1 end;if cc<1 then cc=1 end end;if aN==keys.left then cb=cb-1;if cb>=1 then if cb=self.w+cc then cc=cb end end;if cb<1 then cb=1 end;if cc<1 then cc=1 end end end;if a5=="char"then local i=aT.getValue()if i:len()=self.w+cc then cc=cc+1 end end end;local aX,aY=self:getAnchorPosition()local cl=tostring(aT.getValue())local cp=(cb<=cl:len()and cb-1 or cl:len())-(cc-1)if cp>self.x+self.w-1 then cp=self.x+self.w-1 end;if self.parent~=nil then self.parent:setCursor(true,aX+cp,aY,self.fgcolor)end;ch=false end end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then if a5=="mouse_click"and aK==1 then end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.h,"center")self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)for l=1,self.h do if l==aZ then local cl=tostring(aT.getValue())local ck=self.bgcolor;local cj=self.fgcolor;local i;if cl:len()<=0 then i=cg;ck=ce or ck;cj=cf or cj end;i=cg;if cl~=""then i=cl end;i=i:sub(cc,self.w+cc-1)local cq=self.w-i:len()if cq<0 then cq=0 end;if c9=="password"and cl~=""then i=string.rep("*",i:len())end;i=i..string.rep(" ",cq)self.parent:writeText(aX,aY+l-1,i,ck,cj)end end end end end}return setmetatable(au,aT)end;local function cr(ak)local aT=aj(ak)local al="Textfield"local cs,cc,cb,ct=1,1,1,1;local cu={""}local cv={}local cw=colors.lightBlue;aT.w=20;aT.h=8;aT.bgcolor=a.textfieldBG;aT.fgcolor=a.textfieldFG;aT:setZIndex(5)local au={getType=function(self)return al end,getLines=function(self)return cu end,getLine=function(self,a4)return cu[a4]or""end,editLine=function(self,a4,i)cu[a4]=i or cu[a4]return self end,addLine=function(self,i,a4)if a4~=nil then table.insert(cu,a4,i)else table.insert(cu,i)end;return self end,removeLine=function(self,a4)table.remove(cu,a4 or#cu)if#cu<=0 then table.insert(cu,"")end;return self end,getTextCursor=function(self)return cb,ct end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then local aX,aY=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,aX+cb-cc,aY+ct-cs,self.fgcolor)end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,a5,aN)if aT.keyHandler(self,a5,aN)then local aX,aY=self:getAnchorPosition()if a5=="key"then if aN==keys.backspace then if cu[ct]==""then if ct>1 then table.remove(cu,ct)cb=cu[ct-1]:len()+1;cc=cb-self.w+1;if cc<1 then cc=1 end;ct=ct-1 end elseif cb<=1 then if ct>1 then cb=cu[ct-1]:len()+1;cc=cb-self.w+1;if cc<1 then cc=1 end;cu[ct-1]=cu[ct-1]..cu[ct]table.remove(cu,ct)ct=ct-1 end else cu[ct]=cu[ct]:sub(1,cb-2)..cu[ct]:sub(cb,cu[ct]:len())if cb>1 then cb=cb-1 end;if cc>1 then if cb=self.h then cs=cs+1 end;self:setValue("")end;if aN==keys.up then if ct>1 then ct=ct-1;if cb>cu[ct]:len()+1 then cb=cu[ct]:len()+1 end;if cc>1 then if cb1 then if ctcu[ct]:len()+1 then cb=cu[ct]:len()+1 end;if ct>=cs+self.h then cs=cs+1 end end end;if aN==keys.right then cb=cb+1;if ct<#cu then if cb>cu[ct]:len()+1 then cb=1;ct=ct+1 end elseif cb>cu[ct]:len()then cb=cu[ct]:len()+1 end;if cb<1 then cb=1 end;if cb=self.w+cc then cc=cb-self.w+1 end;if cc<1 then cc=1 end end;if aN==keys.left then cb=cb-1;if cb>=1 then if cb=self.w+cc then cc=cb end end;if ct>1 then if cb<1 then ct=ct-1;cb=cu[ct]:len()+1;cc=cb-self.w+1 end end;if cb<1 then cb=1 end;if cc<1 then cc=1 end end end;if a5=="char"then cu[ct]=cu[ct]:sub(1,cb-1)..aN..cu[ct]:sub(cb,cu[ct]:len())cb=cb+1;if cb>=self.w+cc then cc=cc+1 end;self:setValue("")end;local cp=(cb<=cu[ct]:len()and cb-1 or cu[ct]:len())-(cc-1)if cp>self.x+self.w-1 then cp=self.x+self.w-1 end;local cx=ct-cscu[ct]:len()then cb=cu[ct]:len()+1 end;if cb#cu-(self.h-1)then cs=#cu-(self.h-1)end;if cs<1 then cs=1 end;if self.parent~=nil then if aX+cb-cc>=aX and aX+cb-cc<=aX+self.w and(aY+ct-cs>=aY and aY+ct-cs<=aY+self.h)then self.parent:setCursor(true,cy+cb-cc,cz+ct-cs)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)for l=1,self.h do local i=""if cu[l+cs-1]~=nil then i=cu[l+cs-1]end;i=i:sub(cc,self.w+cc-1)local cq=self.w-i:len()if cq<0 then cq=0 end;i=i..string.rep(" ",cq)self.parent:setText(aX,aY+l-1,i)end end end end}return setmetatable(au,aT)end;local function cA(ak)local aT=aj(ak)local al="List"aT.w=16;aT.h=6;aT.bgcolor=a.listBG;aT.fgcolor=a.listFG;aT:setZIndex(5)local cB={}local cC=a.selectionBG;local cD=a.selectionFG;local cE=true;local cF="left"local cG=0;local cH=true;local au={getType=function(self)return al end,addItem=function(self,i,W,X,...)table.insert(cB,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})if#cB==1 then self:setValue(cB[1])end;return self end,setIndexOffset=function(self,cI)cG=cI;return self end,getIndexOffset=function(self)return cG end,removeItem=function(self,a4)table.remove(cB,a4)return self end,getItem=function(self,a4)return cB[a4]end,getItemIndex=function(self)local cJ=self:getValue()for a8,a9 in pairs(cB)do if a9==cJ then return a8 end end end,clear=function(self)cB={}self:setValue({})return self end,getItemCount=function(self)return#cB end,editItem=function(self,a4,i,W,X,...)table.remove(cB,a4)table.insert(cB,a4,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,selectItem=function(self,a4)self:setValue(cB[a4]or{})return self end,setSelectedItem=function(self,W,X,cK)cC=W or self.bgcolor;cD=X or self.fgcolor;cE=cK;return self end,setScrollable=function(self,cL)cH=cL;return self end,mouseClickHandler=function(self,a5,aK,L,M)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if aX<=L and aX+self.w>L and aY<=M and aY+self.h>M and self:isVisible()then if a5=="mouse_click"or a5=="mouse_drag"then if aK==1 then if#cB>0 then for l=1,self.h do if cB[l+cG]~=nil then if aX<=L and aX+self.w>L and aY+l-1==M then self:setValue(cB[l+cG])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,L,M,cB[l+cG])end end end end end end;if a5=="mouse_scroll"and cH then cG=cG+aK;if cG<0 then cG=0 end;if aK>=1 then if#cB>self.h then if cG>#cB-self.h then cG=#cB-self.h end;if cG>=#cB then cG=#cB-1 end else cG=cG-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)for l=1,self.h do if cB[l+cG]~=nil then if cB[l+cG]==self:getValue()then if cE then self.parent:writeText(aX,aY+l-1,h(cB[l+cG].text,self.w,cF),cC,cD)else self.parent:writeText(aX,aY+l-1,h(cB[l+cG].text,self.w,cF),cB[l+cG].bgCol,cB[l+cG].fgCol)end else self.parent:writeText(aX,aY+l-1,h(cB[l+cG].text,self.w,cF),cB[l+cG].bgCol,cB[l+cG].fgCol)end end end end end end}return setmetatable(au,aT)end;local function cM(ak)local aT=aj(ak)local al="Menubar"aT.w=30;aT.h=1;aT.bgcolor=colors.gray;aT.fgcolor=colors.lightGray;aT:setZIndex(5)local cB={}local cC=a.selectionBG;local cD=a.selectionFG;local cE=true;local cF="left"local cN=0;local cq=2;local cH=false;local function cO()local cP=0;local ay=1;for l=1,#cB do if ay+cB[l].text:len()+cq*2>aT.w then cP=cP+1 end;ay=ay+cB[l].text:len()+cq*2 end;return cP end;local au={getType=function(self)return al end,addItem=function(self,i,W,X,...)table.insert(cB,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})if#cB==1 then self:setValue(cB[1])end;return self end,getItemIndex=function(self)local cJ=self:getValue()for a8,a9 in pairs(cB)do if a9==cJ then return a8 end end end,clear=function(self)cB={}self:setValue({})return self end,setSpace=function(self,cQ)cq=cQ or cq;return self end,setButtonOffset=function(self,o)cN=o or 0;if cN<0 then cN=0 end;local cP=cO()if cN>cP then cN=cP end;return self end,setScrollable=function(self,cL)cH=cL;return self end,removeItem=function(self,a4)table.remove(cB,a4)return self end,getItem=function(self,a4)return cB[a4]end,getItemCount=function(self)return#cB end,editItem=function(self,a4,i,W,X,...)table.remove(cB,a4)table.insert(cB,a4,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,selectItem=function(self,a4)self:setValue(cB[a4]or{})return self end,setSelectedItem=function(self,W,X,cK)cC=W or self.bgcolor;cD=X or self.fgcolor;cE=cK;return self end,mouseClickHandler=function(self,a5,aK,L,M)local aL,aM=self:getAbsolutePosition(self:getAnchorPosition())if aL<=L and aL+self.w>L and aM<=M and aM+self.h>M and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if a5=="mouse_click"then local ay=1;for l=1+cN,#cB do if cB[l]~=nil then if ay+cB[l].text:len()+cq*2<=self.w then if aL+ay-1<=L and aL+ay-1+cB[l].text:len()+cq*2>L and aM==M then self:setValue(cB[l])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,L,M,cB[l])end;ay=ay+cB[l].text:len()+cq*2 else break end end end end;if a5=="mouse_scroll"and cH then cN=cN+aK;if cN<0 then cN=0 end;local cP=cO()if cN>cP then cN=cP end end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)local ay=1;for l=1+cN,#cB do if cB[l]~=nil then if ay+cB[l].text:len()+cq*2<=self.w then if cB[l]==self:getValue()then self.parent:writeText(aX+ay-1,aY,h((" "):rep(cq)..cB[l].text..(" "):rep(cq),cB[l].text:len()+cq*2,cF),cC or cB[l].bgCol,cD or cB[l].fgCol)else self.parent:writeText(aX+ay-1,aY,h((" "):rep(cq)..cB[l].text..(" "):rep(cq),cB[l].text:len()+cq*2,cF),cB[l].bgCol,cB[l].fgCol)end;ay=ay+cB[l].text:len()+cq*2 else break end end end end end end}return setmetatable(au,aT)end;local function cR(ak)local aT=aj(ak)local al="Dropdown"aT.w=12;aT.h=1;aT.bgcolor=a.dropdownBG;aT.fgcolor=a.dropdownFG;aT:setZIndex(6)local cB={}local cC=a.selectionBG;local cD=a.selectionFG;local cE=true;local cF="left"local cG=0;local cS=16;local cT=6;local cU="\16"local cV="\31"local cW=1;local au={getType=function(self)return al end,setIndexOffset=function(self,cI)cG=cI;return self end,getIndexOffset=function(self)return cG end,addItem=function(self,i,W,X,...)table.insert(cB,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,removeItem=function(self,a4)table.remove(cB,a4)return self end,getItem=function(self,a4)return cB[a4]end,getItemIndex=function(self)local cJ=self:getValue()for a8,a9 in pairs(cB)do if a9==cJ then return a8 end end end,clear=function(self)cB={}self:setValue({})return self end,getItemCount=function(self)return#cB end,editItem=function(self,a4,i,W,X,...)table.remove(cB,a4)table.insert(cB,a4,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,selectItem=function(self,a4)self:setValue(cB[a4]or{})return self end,setSelectedItem=function(self,W,X,cK)cC=W or self.bgcolor;cD=X or self.fgcolor;cE=cK;return self end,setDropdownSize=function(self,j,n)cS,cT=j,n;return self end,mouseClickHandler=function(self,a5,aK,L,M)if cW==2 then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if a5=="mouse_click"then if aK==1 then if#cB>0 then for l=1,cT do if cB[l+cG]~=nil then if aX<=L and aX+cS>L and aY+l==M then self:setValue(cB[l+cG])return true end end end end end end;if a5=="mouse_scroll"then cG=cG+aK;if cG<0 then cG=0 end;if aK==1 then if#cB>cT then if cG>#cB-cT then cG=#cB-cT end else cG=cB-1 end end;return true end;self:setVisualChanged()end;if aT.mouseClickHandler(self,a5,aK,L,M)then cW=2 else cW=1 end end,draw=function(self)if aT.draw(self)then local aX,aY=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)if#cB>=1 then if self:getValue()~=nil then if self:getValue().text~=nil then if cW==1 then self.parent:writeText(aX,aY,h(self:getValue().text,self.w,cF):sub(1,self.w-1)..cU,self.bgcolor,self.fgcolor)else self.parent:writeText(aX,aY,h(self:getValue().text,self.w,cF):sub(1,self.w-1)..cV,self.bgcolor,self.fgcolor)end end end;if cW==2 then for l=1,cT do if cB[l+cG]~=nil then if cB[l+cG]==self:getValue()then if cE then self.parent:writeText(aX,aY+l,h(cB[l+cG].text,cS,cF),cC,cD)else self.parent:writeText(aX,aY+l,h(cB[l+cG].text,cS,cF),cB[l+cG].bgCol,cB[l+cG].fgCol)end else self.parent:writeText(aX,aY+l,h(cB[l+cG].text,cS,cF),cB[l+cG].bgCol,cB[l+cG].fgCol)end end end end end end end end}return setmetatable(au,aT)end;local function cX(ak)local aT=aj(ak)local al="Radio"aT.w=8;aT.bgcolor=a.listBG;aT.fgcolor=a.listFG;aT:setZIndex(5)local cB={}local cC=a.selectionBG;local cD=a.selectionFG;local cY=aT.bgcolor;local cZ=aT.fgcolor;local cE=true;local Y="\7"local cF="left"local au={getType=function(self)return al end,addItem=function(self,i,L,M,W,X,...)table.insert(cB,{x=L or 1,y=M or 1,text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})if#cB==1 then self:setValue(cB[1])end;return self end,removeItem=function(self,a4)table.remove(cB,a4)return self end,getItem=function(self,a4)return cB[a4]end,getItemIndex=function(self)local cJ=self:getValue()for a8,a9 in pairs(cB)do if a9==cJ then return a8 end end end,clear=function(self)cB={}self:setValue({})return self end,getItemCount=function(self)return#cB end,editItem=function(self,a4,i,L,M,W,X,...)table.remove(cB,a4)table.insert(cB,a4,{x=L or 1,y=M or 1,text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,selectItem=function(self,a4)self:setValue(cB[a4]or{})return self end,setSelectedItem=function(self,W,X,c_,d0,cK)cC=W or cC;cD=X or cD;cY=c_ or cY;cZ=d0 or cZ;cE=cK;return self end,mouseClickHandler=function(self,a5,aK,L,M)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if a5=="mouse_click"then if aK==1 then if#cB>0 then for aJ,a9 in pairs(cB)do if aX+a9.x-1<=L and aX+a9.x-1+a9.text:len()+2>=L and aY+a9.y-1==M then self:setValue(a9)if self.parent~=nil then self.parent:setFocusedObject(self)end;self:setVisualChanged()return true end end end end end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()for aJ,a9 in pairs(cB)do if a9==self:getValue()then if cF=="left"then self.parent:writeText(a9.x+aX-1,a9.y+aY-1,Y,cY,cZ)self.parent:writeText(a9.x+2+aX-1,a9.y+aY-1,a9.text,cC,cD)end else self.parent:drawBackgroundBox(a9.x+aX-1,a9.y+aY-1,1,1,self.bgcolor)self.parent:writeText(a9.x+2+aX-1,a9.y+aY-1,a9.text,a9.bgCol,a9.fgCol)end end end end end}return setmetatable(au,aT)end;local function d1(ak)local al="Timer"local d2=0;local d3=0;local d4=0;local d5;local at=a2()local au={name=ak,getType=function(self)return al end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,d6,d7)d2=d6 or 0;d3=d7 or 1;return self end,start=function(self)d4=d3;d5=os.startTimer(d2)return self end,cancel=function(self)if d5~=nil then os.cancelTimer(d5)end;return self end,onCall=function(self,a7)at:registerEvent("timed_event",a7)return self end,eventHandler=function(self,a5,d8)if a5=="timer"and d8==d5 then at:sendEvent("timed_event",self)if d4>=1 then d4=d4-1;if d4>=1 then d5=os.startTimer(d2)end elseif d4==-1 then d5=os.startTimer(d2)end end end}au.__index=au;return au end;local function d9(ak)local au;local al="Thread"local a7;local da;local db=false;au={name=ak,getType=function(self)return al end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,dc)if dc==nil then error("function is nil")end;a7=dc;da=coroutine.create(a7)db=true;local ah,ai=coroutine.resume(da)if not ah then if ai~="Terminated"then error("Threaderror - "..ai)end end;return self end,getStatus=function(self,dc)if da~=nil then return coroutine.status(da)end;return nil end,stop=function(self,dc)db=false;return self end,eventHandler=function(self,a5,aO,aP,aQ)if db then if coroutine.status(da)~="dead"then local ah,ai=coroutine.resume(da,a5,aO,aP,aQ)if not ah then if ai~="Terminated"then error("Threaderror - "..ai)end end else db=false end end end}au.__index=au;return au end;local function dd(ak)local au={}local al="Animation"local d5;local de={}local a4=1;local df=0;local dg;local function dh()if de[a4]~=nil then de[a4].f(au,a4)end;a4=a4+1;if de[a4]~=nil then if de[a4].t>0 then d5=os.startTimer(de[a4].t)else dh()end end end;au={name=ak,getType=function(self)return al end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,a7,di)dg=a7;table.insert(de,{f=a7,t=di or df})return self end,wait=function(self,di)df=di;return self end,rep=function(self,dj)for L=1,dj do table.insert(de,{f=dg,t=df})end;return self end,clear=function(self)de={}dg=nil;df=0;a4=1;return self end,play=function(self)a4=1;if de[a4]~=nil then if de[a4].t>0 then d5=os.startTimer(de[a4].t)else dh()end end;return self end,cancel=function(self)os.cancelTimer(d5)return self end,eventHandler=function(self,a5,d8)if a5=="timer"and d8==d5 then if de[a4]~=nil then dh()end end end}au.__index=au;return au end;local function dk(ak)local aT=aj(ak)local al="Slider"aT.w=8;aT.bgcolor=colors.lightGray;aT.fgcolor=colors.gray;aT:setValue(1)local dl="horizontal"local Y=" "local dm=colors.black;local dn="\140"local dp=aT.w;local a4=1;local au={getType=function(self)return al end,setSymbol=function(self,dq)Y=dq:sub(1,1)self:setVisualChanged()return self end,setBackgroundSymbol=function(self,dr)dn=string.sub(dr,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,ds)dm=ds;self:setVisualChanged()return self end,setBarType=function(self,dt)dl=dt:lower()return self end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if dl=="horizontal"then for du=0,self.w-1 do if aX+du==L and aY<=M and aY+self.h>M then a4=du+1;self:setValue(dp/self.w*a4)self:setVisualChanged()end end end;if dl=="vertical"then for du=0,self.h-1 do if aY+du==M and aX<=L and aX+self.w>L then a4=du+1;self:setValue(dp/self.h*a4)self:setVisualChanged()end end end end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()if dl=="horizontal"then self.parent:writeText(aX,aY,dn:rep(a4-1),self.bgcolor,self.fgcolor)self.parent:writeText(aX+a4-1,aY,Y,dm,dm)self.parent:writeText(aX+a4,aY,dn:rep(self.w-a4),self.bgcolor,self.fgcolor)end;if dl=="vertical"then for l=0,self.h-1 do if l+1==a4 then self.parent:writeText(aX,aY+l,Y,dm,dm)else self.parent:writeText(aX,aY+l,dn,self.bgcolor,self.fgcolor)end end end end end end}return setmetatable(au,aT)end;local function dv(ak)local aT=aj(ak)local al="Scrollbar"aT.w=1;aT.h=8;aT.bgcolor=colors.lightGray;aT.fgcolor=colors.gray;aT:setValue(1)aT:setZIndex(2)local dl="vertical"local Y=" "local dm=colors.black;local dn="\127"local dp=aT.h;local a4=1;local dw=1;local au={getType=function(self)return al end,setSymbol=function(self,dq)Y=dq:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,dx)dw=tonumber(dx)or 1;if dl=="vertical"then self:setValue(a4-1*dp/(self.h-(dw-1))-dp/(self.h-(dw-1)))elseif dl=="horizontal"then self:setValue(a4-1*dp/(self.w-(dw-1))-dp/(self.w-(dw-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,cl)dp=cl;return self end,setBackgroundSymbol=function(self,dr)dn=string.sub(dr,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,ds)dm=ds;self:setVisualChanged()return self end,setBarType=function(self,dt)dl=dt:lower()return self end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if(a5=="mouse_click"or a5=="mouse_drag")and aK==1 then if dl=="horizontal"then for du=0,self.w do if aX+du==L and aY<=M and aY+self.h>M then a4=math.min(du+1,self.w-(dw-1))self:setValue(dp/self.w*a4)self:setVisualChanged()end end end;if dl=="vertical"then for du=0,self.h do if aY+du==M and aX<=L and aX+self.w>L then a4=math.min(du+1,self.h-(dw-1))self:setValue(dp/self.h*a4)self:setVisualChanged()end end end end;if a5=="mouse_scroll"then a4=a4+aK;if a4<1 then a4=1 end;a4=math.min(a4,(dl=="vertical"and self.h or self.w)-(dw-1))self:setValue(dp/(dl=="vertical"and self.h or self.w)*a4)end;return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()if dl=="horizontal"then self.parent:writeText(aX,aY,dn:rep(a4-1),self.bgcolor,self.fgcolor)self.parent:writeText(aX+a4-1,aY,Y:rep(dw),dm,dm)self.parent:writeText(aX+a4+dw-1,aY,dn:rep(self.w-(a4+dw-1)),self.bgcolor,self.fgcolor)end;if dl=="vertical"then for l=0,self.h-1 do if a4==l+1 then for dy=0,math.min(dw-1,self.h)do self.parent:writeText(aX,aY+l+dy,Y,dm,dm)end else if l+1a4-1+dw then self.parent:writeText(aX,aY+l,dn,self.bgcolor,self.fgcolor)end end end end end end end}return setmetatable(au,aT)end;local function dz(ak,dA)local aT=aj(ak)local al="Frame"local dB={}local dC={}local au={}local dD;aT:setZIndex(10)local b5=false;local b1=1;local b2=1;local dE=colors.white;local dF,cG=0,0;if dA~=nil then aT.parent=dA;aT.w,aT.h=dA.w,dA.h;aT.bgcolor=a.FrameBG;aT.fgcolor=a.FrameFG else local dG,dH=f.getSize()aT.w,aT.h=dG,dH;aT.bgcolor=a.basaltBG;aT.fgcolor=a.basaltFG end;local function dI(ak)for a8,a9 in pairs(dB)do for dJ,bD in pairs(a9)do if bD.name==ak then return a9 end end end end;local function dK(dL)local an=dL:getZIndex()if dI(dL.name)~=nil then return nil end;if dB[an]==nil then for L=1,#dC+1 do if dC[L]~=nil then if an==dC[L]then break end;if an>dC[L]then table.insert(dC,L,an)break end else table.insert(dC,an)end end;if#dC<=0 then table.insert(dC,an)end;dB[an]={}end;dL.parent=au;table.insert(dB[an],dL)return dL end;local function dM(dL)for dJ,bD in pairs(dB)do for a8,a9 in pairs(bD)do if a9==dL then table.remove(dB[dJ],a8)return true end end end;return false end;au={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return al end,setFocusedObject=function(self,dL)for aJ,a4 in pairs(dC)do for aJ,a9 in pairs(dB[a4])do if a9==dL then if dD~=nil then dD:loseFocusHandler()end;dD=dL;dD:getFocusHandler()end end end;return self end,setOffset=function(self,aG,aH)dF=aG~=nil and math.floor(aG<0 and math.abs(aG)or-aG)or dF;cG=aH~=nil and math.floor(aH<0 and math.abs(aH)or-aH)or cG;return self end,getFrameOffset=function(self)return dF,cG end,removeFocusedObject=function(self)if dD~=nil then dD:loseFocusHandler()end;dD=nil;return self end,getFocusedObject=function(self)return dD end,show=function(self)aT:show()if self.parent==nil then c=self end;return self end,setCursor=function(self,dN,dO,dP,aC)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())b5=dN or false;if dO~=nil then b1=aX+dO-1 end;if dP~=nil then b2=aY+dP-1 end;dE=aC or dE;self:setVisualChanged()return self end,setMoveable=function(self,dQ)self.isMoveable=dQ or not self.isMoveable;self:setVisualChanged()return self end,showBar=function(self,dR)self.barActive=dR or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,i,W,X)self.barText=i or""self.barBackground=W or self.barBackground;self.barTextcolor=X or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,cF)self.barTextAlign=cF or"left"self:setVisualChanged()return self end,getVisualChanged=function(self)local dS=aT.getVisualChanged(self)for aJ,a4 in pairs(dC)do if dB[a4]~=nil then for aJ,a9 in pairs(dB[a4])do if a9.getVisualChanged~=nil and a9:getVisualChanged()then dS=true end end end end;return dS end,loseFocusHandler=function(self)aT.loseFocusHandler(self)end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,a5,aN)if dD~=nil then if dD.keyHandler~=nil then if dD:keyHandler(a5,aN)then return true end end end;return false end,backgroundKeyHandler=function(self,a5,aN)aT.backgroundKeyHandler(self,a5,aN)for aJ,a4 in pairs(dC)do if dB[a4]~=nil then for aJ,a9 in pairs(dB[a4])do if a9.backgroundKeyHandler~=nil then a9:backgroundKeyHandler(a5,aN)end end end end end,eventHandler=function(self,a5,aO,aP,aQ,aR)aT.eventHandler(self,a5,aO,aP,aQ,aR)for aJ,a4 in pairs(dC)do if dB[a4]~=nil then for aJ,a9 in pairs(dB[a4])do if a9.eventHandler~=nil then a9:eventHandler(a5,aO,aP,aQ,aR)end end end end;if a5=="terminate"then f.clear()f.setCursorPos(1,1)b.stop()end end,mouseClickHandler=function(self,a5,aK,L,M)local aG,aH=self:getOffset()aG=aG<0 and math.abs(aG)or-aG;aH=aH<0 and math.abs(aH)or-aH;if self.drag then if a5=="mouse_drag"then local dT=1;local dU=1;if self.parent~=nil then dT,dU=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(L+self.xToRem-(dT-1)+aG,M-(dU-1)+aH)end;if a5=="mouse_up"then self.drag=false end;return true end;if aT.mouseClickHandler(self,a5,aK,L,M)then local aD,aE=self:getAbsolutePosition(self:getAnchorPosition())for aJ,a4 in pairs(dC)do if dB[a4]~=nil then for aJ,a9 in p(dB[a4])do if a9.mouseClickHandler~=nil then if a9:mouseClickHandler(a5,aK,L+aG,M+aH)then return true end end end end end;if self.isMoveable then if L>=aD and L<=aD+self.w-1 and M==aE and a5=="mouse_click"then self.drag=true;self.xToRem=aD-L end end;if dD~=nil then dD:loseFocusHandler()dD=nil end;return true end;return false end,setText=function(self,L,M,i)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:setText(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(i,math.max(1-L+1,1),self.w-L+1))else V.setText(math.max(L+aX-1,aX),aY+M-1,g(i,math.max(1-L+1,1),self.w-L+1))end end end,setBG=function(self,L,M,W)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:setBG(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(W,math.max(1-L+1,1),self.w-L+1))else V.setBG(math.max(L+aX-1,aX),aY+M-1,g(W,math.max(1-L+1,1),self.w-L+1))end end end,setFG=function(self,L,M,X)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:setFG(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(X,math.max(1-L+1,1),self.w-L+1))else V.setFG(math.max(L+aX-1,aX),aY+M-1,g(X,math.max(1-L+1,1),self.w-L+1))end end end,writeText=function(self,L,M,i,W,X)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:writeText(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(i,math.max(1-L+1,1),self.w-L+1),W,X)else V.writeText(math.max(L+aX-1,aX),aY+M-1,g(i,math.max(1-L+1,1),self.w-L+1),W,X)end end end,drawBackgroundBox=function(self,L,M,j,n,W)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())n=M<1 and(n+M>self.h and self.h or n+M-1)or(n+M>self.h and self.h-M+1 or n)j=L<1 and(j+L>self.w and self.w or j+L-1)or(j+L>self.w and self.w-L+1 or j)if self.parent~=nil then self.parent:drawBackgroundBox(math.max(L+aX-1,aX)-(self.parent.x-1),math.max(M+aY-1,aY)-(self.parent.y-1),j,n,W)else V.drawBackgroundBox(math.max(L+aX-1,aX),math.max(M+aY-1,aY),j,n,W)end end,drawTextBox=function(self,L,M,j,n,Y)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())n=M<1 and(n+M>self.h and self.h or n+M-1)or(n+M>self.h and self.h-M+1 or n)j=L<1 and(j+L>self.w and self.w or j+L-1)or(j+L>self.w and self.w-L+1 or j)if self.parent~=nil then self.parent:drawTextBox(math.max(L+aX-1,aX)-(self.parent.x-1),math.max(M+aY-1,aY)-(self.parent.y-1),j,n,Y:sub(1,1))else V.drawTextBox(math.max(L+aX-1,aX),math.max(M+aY-1,aY),j,n,Y:sub(1,1))end end,drawForegroundBox=function(self,L,M,j,n,X)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())n=M<1 and(n+M>self.h and self.h or n+M-1)or(n+M>self.h and self.h-M+1 or n)j=L<1 and(j+L>self.w and self.w or j+L-1)or(j+L>self.w and self.w-L+1 or j)if self.parent~=nil then self.parent:drawForegroundBox(math.max(L+aX-1,aX)-(self.parent.x-1),math.max(M+aY-1,aY)-(self.parent.y-1),j,n,X)else V.drawForegroundBox(math.max(L+aX-1,aX),math.max(M+aY-1,aY),j,n,X)end end,draw=function(self)if self:getVisualChanged()then if aT.draw(self)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())local cy,cz=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(cy,cz,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(cy,cz,self.w,self.h,self.fgcolor)self.parent:drawTextBox(cy,cz,self.w,self.h," ")else V.drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)V.drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)V.drawTextBox(aX,aY,self.w,self.h," ")end;f.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(cy,cz,h(self.barText,self.w,self.barTextAlign),self.barBackground,self.barTextcolor)else V.writeText(aX,aY,h(self.barText,self.w,self.barTextAlign),self.barBackground,self.barTextcolor)end end;for aJ,a4 in p(dC)do if dB[a4]~=nil then for aJ,a9 in pairs(dB[a4])do if a9.draw~=nil then a9:draw()end end end end;if b5 then f.setTextColor(dE)f.setCursorPos(b1,b2)if self.parent~=nil then f.setCursorBlink(self:isFocused())else f.setCursorBlink(b5)end end;self:setVisualChanged(false)end end end,addObject=function(self,dL)return dK(dL)end,removeObject=function(self,dL)return dM(dL)end,getObject=function(self,dL)return dI(dL)end,addButton=function(self,ak)local dL=aS(ak)dL.name=ak;return dK(dL)end,addLabel=function(self,ak)local dL=c0(ak)dL.name=ak;dL.bgcolor=self.bgcolor;dL.fgcolor=self.fgcolor;return dK(dL)end,addCheckbox=function(self,ak)local dL=c7(ak)dL.name=ak;return dK(dL)end,addInput=function(self,ak)local dL=c8(ak)dL.name=ak;return dK(dL)end,addProgram=function(self,ak)local dL=a_(ak)dL.name=ak;return dK(dL)end,addTextfield=function(self,ak)local dL=cr(ak)dL.name=ak;return dK(dL)end,addList=function(self,ak)local dL=cA(ak)dL.name=ak;return dK(dL)end,addDropdown=function(self,ak)local dL=cR(ak)dL.name=ak;return dK(dL)end,addRadio=function(self,ak)local dL=cX(ak)dL.name=ak;return dK(dL)end,addTimer=function(self,ak)local dL=d1(ak)dL.name=ak;return dK(dL)end,addAnimation=function(self,ak)local dL=dd(ak)dL.name=ak;return dK(dL)end,addSlider=function(self,ak)local dL=dk(ak)dL.name=ak;return dK(dL)end,addScrollbar=function(self,ak)local dL=dv(ak)dL.name=ak;return dK(dL)end,addMenubar=function(self,ak)local dL=cM(ak)dL.name=ak;return dK(dL)end,addThread=function(self,ak)local dL=d9(ak)dL.name=ak;return dK(dL)end,addPane=function(self,ak)local dL=c2(ak)dL.name=ak;return dK(dL)end,addImage=function(self,ak)local dL=c3(ak)dL.name=ak;return dK(dL)end,addFrame=function(self,ak)local dL=dz(ak,self)dL.name=ak;return dK(dL)end}setmetatable(au,aT)if dA==nil then table.insert(d,au)end;return au end;local dV=false;local function dW(a5,aO,aP,aQ,aR)if a5=="mouse_click"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="mouse_drag"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="mouse_up"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="mouse_scroll"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="key"or a5=="char"then c:keyHandler(a5,aO)c:backgroundKeyHandler(a5,aO)end;for aJ,a9 in pairs(d)do a9:eventHandler(a5,aO,aP,aQ,aR)end;if dV then c:draw()V.update()end end;function b.autoUpdate(db)f.clear()dV=db or true;c:draw()V.update()while dV do local a5,aO,aP,aQ,aR=os.pullEventRaw()dW(a5,aO,aP,aQ,aR)end end;function b.update(a5,aO,aP,aQ,aR)if a5~="nil"then dW(a5,aO,aP,aQ,aR)else c:draw()V.update()end end;function b.stop()dV=false end;function b.getFrame(ak)for a8,a9 in pairs(d)do if a9.name==ak then return a9 end end end;function b.getActiveFrame()return c end;function b.setActiveFrame(av)if av:getType()=="Frame"then c=av;return true end;return false end;function b.createFrame(ak)local av=dz(ak)return av end;function b.removeFrame(ak)for a8,a9 in pairs(d)do if a9.name==ak then d[a8]=nil;return true end end;return false end;if b.debugger then b.debugFrame=b.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug",colors.black,colors.gray)b.debugList=b.debugFrame:addList("debugList"):setSize(b.debugFrame.w-2,b.debugFrame.h-3):setPosition(2,3):setScrollable(true):show()b.debugFrame:addButton("back"):setAnchor("right"):setSize(1,1):setText("\22"):onClick(function()b.oldFrame:show()end):setBackground(colors.red):show()b.debugLabel=b.debugFrame:addLabel("debugLabel"):onClick(function()b.oldFrame=c;b.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):setZIndex(20):show()end;if b.debugger then function b.debug(...)local af={...}if c.name~="basaltDebuggingFrame"then if c~=b.debugLabel.frame then b.debugLabel:setParent(c)end end;local dX=""for a8,a9 in pairs(af)do dX=dX..tostring(a9)..(#af~=a8 and", "or"")end;b.debugLabel:setText("[Debug] "..dX)b.debugList:addItem(dX)if b.debugList:getItemCount()>50 then b.debugList:removeItem(1)end;b.debugList:setValue(b.debugList:getItem(b.debugList:getItemCount()))b.debugLabel:show()end end;return b \ No newline at end of file +local a={basaltBG=colors.lightGray,basaltFG=colors.black,FrameBG=colors.gray,FrameFG=colors.black,ButtonBG=colors.gray,ButtonFG=colors.black,CheckboxBG=colors.gray,CheckboxFG=colors.black,InputBG=colors.gray,InputFG=colors.black,textfieldBG=colors.gray,textfieldFG=colors.black,listBG=colors.gray,listFG=colors.black,dropdownBG=colors.gray,dropdownFG=colors.black,radioBG=colors.gray,radioFG=colors.black,selectionBG=colors.black,selectionFG=colors.lightGray}local b={debugger=true,version=1}local c;local d={}local e={}local f=term.current()local g=string.sub;local function h(i,j,k)local i=string.sub(i,1,j)local l=j-string.len(i)if k=="right"then i=string.rep(" ",l)..i elseif k=="center"then i=string.rep(" ",math.floor(l/2))..i..string.rep(" ",math.floor(l/2))i=i..(string.len(i)=1 and M<=n then if L+i:len()>0 and L<=j then local N=v[M]local O;local P=L+#i-1;if L<1 then local Q=1-L+1;local R=j-L+1;i=g(i,Q,R)elseif P>j then local R=j-L+1;i=g(i,1,R)end;if L>1 then local R=L-1;O=g(N,1,R)..i else O=i end;if P=1 and M<=n then if L+T:len()>0 and L<=j then local N=w[M]local O;local P=L+#T-1;if L<1 then T=g(T,1-L+1,j-L+1)elseif P>j then T=g(T,1,j-L+1)end;if L>1 then O=g(N,1,L-1)..T else O=T end;if P=1 and M<=n then if L+T:len()>0 and L<=j then local N=x[M]local O;local P=L+#T-1;if L<1 then local Q=1-L+1;local R=j-L+1;T=g(T,Q,R)elseif P>j then local R=j-L+1;T=g(T,1,R)end;if L>1 then local R=L-1;O=g(N,1,R)..T else O=T end;if PL and aM<=M and aM+self.h>M and ar then if self.parent~=nil then self.parent:setFocusedObject(self)end;at:sendEvent(a5,self,a5,aK,L,M)return true end;return false end,keyHandler=function(self,a5,aN)if self:isFocused()then at:sendEvent(a5,self,a5,aN)return true end;return false end,backgroundKeyHandler=function(self,a5,aN)at:sendEvent("background_"..a5,self,a5,aN)end,valueChangedHandler=function(self)at:sendEvent("value_changed",self)end,eventHandler=function(self,a5,aO,aP,aQ,aR)at:sendEvent("custom_event_handler",self,a5,aO,aP,aQ,aR)end,getFocusHandler=function(self)at:sendEvent("get_focus",self)end,loseFocusHandler=function(self)at:sendEvent("lose_focus",self)end}au.__index=au;return au end;local function aS(ak)local aT=aj(ak)local al="Button"aT:setValue("Button")aT:setZIndex(5)aT.w=8;aT.bgcolor=a.ButtonBG;aT.fgcolor=a.ButtonFG;local aU="center"local aV="center"local au={getType=function(self)return al end,setHorizontalAlign=function(self,aW)aU=aW end,setVerticalAlign=function(self,aW)aV=aW end,setText=function(self,i)aT:setValue(i)return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.h,aV)self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)self.parent:drawTextBox(aX,aY,self.w,self.h," ")for l=1,self.h do if l==aZ then self.parent:setText(aX,aY+l-1,h(self:getValue(),self.w,aU))end end end end end}return setmetatable(au,aT)end;local function a_(ak)local aT=aj(ak)local al="Program"aT:setZIndex(5)local au;local function b0(L,M,j,n)local b1,b2=1,1;local b3,b4=colors.black,colors.white;local b5=false;local b6=false;local v={}local w={}local x={}local b7={}local B;local C={}for r=0,15 do local b8=2^r;b7[b8]={f.getPaletteColour(b8)}end;local function D()B=(" "):rep(j)for l=0,15 do local E=2^l;local F=s[E]C[E]=F:rep(j)end end;local function G()D()local H=B;local I=C[colors.white]local J=C[colors.black]for l=1,n do v[l]=g(v[l]==nil and H or v[l]..H:sub(1,j-v[l]:len()),1,j)x[l]=g(x[l]==nil and I or x[l]..I:sub(1,j-x[l]:len()),1,j)w[l]=g(w[l]==nil and J or w[l]..J:sub(1,j-w[l]:len()),1,j)end end;G()local function b9()if b1>=1 and b2>=1 and b1<=j and b2<=n then else end end;local function ba(bb,bc,bd)local be=b1;local P=be+#bb-1;if b2>=1 and b2<=n then if be<=j and P>=1 then if be==1 and P==j then v[b2]=bb;x[b2]=bc;w[b2]=bd else local bf,bg,bh;if be<1 then local bi=1-be+1;local bj=j-be+1;bf=g(bb,bi,bj)bg=g(bc,bi,bj)bh=g(bd,bi,bj)elseif P>j then local bj=j-be+1;bf=g(bb,1,bj)bg=g(bc,1,bj)bh=g(bd,1,bj)else bf=bb;bg=bc;bh=bd end;local bk=v[b2]local bl=x[b2]local bm=w[b2]local bn,bo,bp;if be>1 then local bq=be-1;bn=g(bk,1,bq)..bf;bo=g(bl,1,bq)..bg;bp=g(bm,1,bq)..bh else bn=bf;bo=bg;bp=bh end;if P=1 and M<=n then v[bO]=v[M]w[bO]=w[M]x[bO]=x[M]else v[bO]=bL;x[bO]=bM;w[bO]=bN end end end;if b6 then b9()end end,isColor=function()return f.isColor()end,isColour=function()return f.isColor()end,write=function(i)i=tostring(i)if b6 then ba(i,s[b4]:rep(i:len()),s[b3]:rep(i:len()))end end,clearLine=function()if b6 then K(1,b2,(" "):rep(j))S(1,b2,s[b3]:rep(j))U(1,b2,s[b4]:rep(j))end;if b6 then b9()end end,clear=function()for l=1,n do K(1,l,(" "):rep(j))S(1,l,s[b3]:rep(j))U(1,l,s[b4]:rep(j))end;if b6 then b9()end end,blit=function(i,bP,bQ)if type(i)~="string"then error("bad argument #1 (expected string, got "..type(i)..")",2)end;if type(bP)~="string"then error("bad argument #2 (expected string, got "..type(bP)..")",2)end;if type(bQ)~="string"then error("bad argument #3 (expected string, got "..type(bQ)..")",2)end;if#bP~=#i or#bQ~=#i then error("Arguments must be the same length",2)end;if b6 then ba(i,bP,bQ)end end}return bG end;aT.w=30;aT.h=12;local bR=b0(1,1,aT.w,aT.h)local bS;local bT=false;local bU={}au={getType=function(self)return al end,show=function(self)aT.show(self)bR.setBackgroundColor(self.bgcolor)bR.setTextColor(self.fgcolor)bR.basalt_setVisible(true)return self end,hide=function(self)aT.hide(self)bR.basalt_setVisible(false)return self end,setPosition=function(self,L,M,aA)aT.setPosition(self,L,M,aA)bR.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return bR end,getBasaltProcess=function()return bS end,setSize=function(self,j,n)aT.setSize(self,j,n)bR.basalt_resize(self.w,self.h)return self end,getStatus=function(self)if bS~=nil then return bS:getStatus()end;return"inactive"end,execute=function(self,ad,...)bS=ab:new(ad,bR,...)bR.setBackgroundColor(colors.black)bR.setTextColor(colors.white)bR.clear()bR.setCursorPos(1,1)bS:resume()bT=false;return self end,stop=function(self)if bS~=nil then if not bS:isDead()then bS:resume("terminate")if bS:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,bV)bT=bV or not bT;if bS~=nil then if not bS:isDead()then if not bT then self:injectEvents(bU)bU={}end end end;return self end,isPaused=function(self)return bT end,injectEvent=function(self,a5,aO,aP,aQ,aR,bW)if bS~=nil then if not bS:isDead()then if bT==false or bW then bS:resume(a5,aO,aP,aQ,aR)else table.insert(bU,{event=a5,args={aO,aP,aQ,aR}})end end end;return self end,getQueuedEvents=function(self)return bU end,updateQueuedEvents=function(self,a3)bU=a3 or bU;return self end,injectEvents=function(self,a3)if bS~=nil then if not bS:isDead()then for aJ,a9 in pairs(a3)do bS:resume(a9.event,table.unpack(a9.args))end end end;return self end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then if bS==nil then return false end;if not bS:isDead()then if not bT then local bX,bY=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))bS:resume(a5,aK,L-bX+1,M-bY+1)end end;return true end end,keyHandler=function(self,a5,aN)aT.keyHandler(self,a5,aN)if self:isFocused()then if bS==nil then return false end;if not bS:isDead()then if not bT then if self.draw then bS:resume(a5,aN)end end end end end,getFocusHandler=function(self)aT.getFocusHandler(self)if bS~=nil then if not bS:isDead()then if not bT then if self.parent~=nil then local bZ,b_=bR.getCursorPos()local aX,aY=self:getAnchorPosition()if self.parent~=nil then if aX+bZ-1>=1 and aX+bZ-1<=aX+self.w-1 and b_+aY-1>=1 and b_+aY-1<=aY+self.h-1 then self.parent:setCursor(bR.getCursorBlink(),aX+bZ-1,b_+aY-1,bR.getTextColor())end end end end end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if bS~=nil then if not bS:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,a5,aO,aP,aQ,aR)if bS==nil then return end;if not bS:isDead()then if not bT then if a5~="mouse_click"and a5~="mouse_up"and a5~="mouse_scroll"and a5~="mouse_drag"and a5~="key_up"and a5~="key"and a5~="char"and a5~="terminate"then bS:resume(a5,aO,aP,aQ,aR)end;if self:isFocused()then local aX,aY=self:getAnchorPosition()local bZ,b_=bR.getCursorPos()if self.parent~=nil then if aX+bZ-1>=1 and aX+bZ-1<=aX+self.w-1 and b_+aY-1>=1 and b_+aY-1<=aY+self.h-1 then self.parent:setCursor(bR.getCursorBlink(),aX+bZ-1,b_+aY-1,bR.getTextColor())end end;if a5=="terminate"and self:isFocused()then self:stop()end end else if a5~="mouse_click"and a5~="mouse_up"and a5~="mouse_scroll"and a5~="mouse_drag"and a5~="key_up"and a5~="key"and a5~="char"and a5~="terminate"then table.insert(bU,{event=a5,args={aO,aP,aQ,aR}})end end end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()bR.basalt_reposition(aX,aY)self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)bR.basalt_update()end end end}return setmetatable(au,aT)end;local function c0(ak)local aT=aj(ak)local al="Label"aT:setZIndex(3)local c1=true;aT:setValue("")local au={getType=function(self)return al end,setText=function(self,i)i=tostring(i)aT:setValue(i)if c1 then self.w=i:len()end;return self end,setSize=function(self,j,n)self.w,self.h=j,n;c1=false;return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:writeText(aX,aY,self:getValue(),self.bgcolor,self.fgcolor)end end end}return setmetatable(au,aT)end;local function c2(ak)local aT=aj(ak)local al="Pane"local au={getType=function(self)return al end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(aX,aY,self.w,self.h,self.bgcolor)end end end}return setmetatable(au,aT)end;local function c3(ak)local aT=aj(ak)local al="Image"aT:setZIndex(2)local c4;local c5;local c6=false;local function c7()local c8={[0]={8,4,3,6,5},{4,14,8,7},{6,10,8,7},{9,11,8,0},{1,14,8,0},{13,12,8,0},{2,10,8,0},{15,8,10,11,12,14},{0,7,1,9,2,13},{3,11,8,7},{2,6,7,15},{9,3,7,15},{13,5,7,15},{5,12,8,7},{1,4,7,15},{7,10,11,12,14}}local c9,ca,cb={},{},{}for r=0,15 do ca[2^r]=r end;do local cc="0123456789abcdef"for r=1,16 do c9[cc:sub(r,r)]=r-1;c9[r-1]=cc:sub(r,r)cb[cc:sub(r,r)]=2^(r-1)cb[2^(r-1)]=cc:sub(r,r)local cd=c8[r-1]for r=1,#cd do cd[r]=2^cd[r]end end end;local function ce(cf)local cg=c8[ca[cf[#cf][1]]]for ch=1,#cg do local ci=cg[ch]for r=1,#cf-1 do if cf[r][1]==ci then return r end end end;return 1 end;local function cj(ck,cl)if not cl then local cm={}cl={}for r=1,6 do local cn=ck[r]local co=cl[cn]cl[cn],cm[r]=co and co+1 or 1,cn end;ck=cm end;local cf={}for aN,am in pairs(cl)do cf[#cf+1]={aN,am}end;if#cf>1 then while#cf>2 do table.sort(cf,function(cp,bD)return cp[2]>bD[2]end)local cq,cr=ce(cf),#cf;local cs,ct=cf[cr][1],cf[cq][1]for r=1,6 do if ck[r]==cs then ck[r]=ct;cf[cq][2]=cf[cq][2]+1 end end;cf[cr]=nil end;local cu=128;for r=1,#ck-1 do if ck[r]~=ck[6]then cu=cu+2^(r-1)end end;return string.char(cu),cb[cf[1][1]==ck[6]and cf[2][1]or cf[1][1]],cb[ck[6]]else return"\128",cb[ck[1]],cb[ck[1]]end end;local cv,cw,cx,W={{},{},{}},0,#c4+#c4%3,aT.bgcolor or colors.black;for r=1,#c4 do if#c4[r]>cw then cw=#c4[r]end end;for M=0,cx-1,3 do local cy,cz,cA,cB={},{},{},1;for L=0,cw-1,2 do local ck,cl={},{}for cC=1,3 do for cD=1,2 do ck[#ck+1]=c4[M+cC]and c4[M+cC][L+cD]and(c4[M+cC][L+cD]==0 and W or c4[M+cC][L+cD])or W;cl[ck[#ck]]=cl[ck[#ck]]and cl[ck[#ck]]+1 or 1 end end;cy[cB],cz[cB],cA[cB]=cj(ck,cl)cB=cB+1 end;cv[1][#cv[1]+1],cv[2][#cv[2]+1],cv[3][#cv[3]+1]=table.concat(cy),table.concat(cz),table.concat(cA)end;cv.width,cv.height=#cv[1][1],#cv[1]c5=cv end;local au={getType=function(self)return al end,loadImage=function(self,ad)c4=paintutils.loadImage(ad)c6=false;return self end,loadBlittleImage=function(self,ad)c6=true;return self end,shrinkImage=function(self)c7()c6=true;return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then if c4~=nil then local aX,aY=self:getAnchorPosition()if c6 then local q,cE,cF=c5[1],c5[2],c5[3]for r=1,c5.height do local cG=q[r]if type(cG)=="string"then self.parent:setText(aX,aY+r-1,cG)self.parent:setFG(aX,aY+r-1,cE[r])self.parent:setBG(aX,aY+r-1,cF[r])elseif type(cG)=="table"then self.parent:setText(aX,aY+r-1,cG[2])self.parent:setFG(aX,aY+r-1,cE[r])self.parent:setBG(aX,aY+r-1,cF[r])end end else for az=1,math.min(#c4,self.h)do local cH=c4[az]for ay=1,math.min(#cH,self.w)do if cH[ay]>0 then self.parent:drawBackgroundBox(aX+ay-1,aY+az-1,1,1,cH[ay])end end end end end end end end}return setmetatable(au,aT)end;local function cI(ak)local aT=aj(ak)local al="Checkbox"aT:setZIndex(5)aT:setValue(false)aT.w=1;aT.h=1;aT.bgcolor=a.CheckboxBG;aT.fgcolor=a.CheckboxFG;local au={symbol="\42",getType=function(self)return al end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then if a5=="mouse_click"and aK==1 then if self:getValue()~=true and self:getValue()~=false then self:setValue(false)else self:setValue(not self:getValue())end end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.h,"center")self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)for l=1,self.h do if l==aZ then if self:getValue()==true then self.parent:writeText(aX,aY+l-1,h(self.symbol,self.w,"center"),self.bgcolor,self.fgcolor)else self.parent:writeText(aX,aY+l-1,h(" ",self.w,"center"),self.bgcolor,self.fgcolor)end end end end end end}return setmetatable(au,aT)end;local function cJ(ak)local aT=aj(ak)local al="Progressbar"local cK=0;aT:setZIndex(5)aT:setValue(false)aT.w=25;aT.h=1;aT.bgcolor=a.CheckboxBG;aT.fgcolor=a.CheckboxFG;local cL=colors.black;local cM=""local cN=colors.white;local cO=""local cP=0;local au={getType=function(self)return al end,setDirection=function(self,cQ)cP=cQ;return self end,setProgressBar=function(self,aC,Y,cR)cL=aC or cL;cM=Y or cM;cN=cR or cN;return self end,setBackgroundSymbol=function(self,Y)cO=Y:sub(1,1)return self end,setProgress=function(self,am)if am>=0 and am<=100 and cK~=am then cK=am;self:setValue(cK)if cK==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return cK end,onProgressDone=function(self,cS)self:registerEvent("progress_done",cS)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done")end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)self.parent:drawTextBox(aX,aY,self.w,self.h,cO)if cP==1 then self.parent:drawBackgroundBox(aX,aY,self.w,self.h/100*cK,cL)self.parent:drawForegroundBox(aX,aY,self.w,self.h/100*cK,cN)self.parent:drawTextBox(aX,aY,self.w,self.h/100*cK,cM)elseif cP==2 then self.parent:drawBackgroundBox(aX,aY+math.ceil(self.h-self.h/100*cK),self.w,self.h/100*cK,cL)self.parent:drawForegroundBox(aX,aY+math.ceil(self.h-self.h/100*cK),self.w,self.h/100*cK,cN)self.parent:drawTextBox(aX,aY+math.ceil(self.h-self.h/100*cK),self.w,self.h/100*cK,cM)elseif cP==3 then self.parent:drawBackgroundBox(aX+math.ceil(self.w-self.w/100*cK),aY,self.w/100*cK,self.h,cL)self.parent:drawForegroundBox(aX+math.ceil(self.w-self.w/100*cK),aY,self.w/100*cK,self.h,cN)self.parent:drawTextBox(aX+math.ceil(self.w-self.w/100*cK),aY,self.w/100*cK,self.h,cM)else self.parent:drawBackgroundBox(aX,aY,self.w/100*cK,self.h,cL)self.parent:drawForegroundBox(aX,aY,self.w/100*cK,self.h,cN)self.parent:drawTextBox(aX,aY,self.w/100*cK,self.h,cM)end end end end}return setmetatable(au,aT)end;local function cT(ak)local aT=aj(ak)local al="Input"local cU="text"local cV=0;aT:setZIndex(5)aT:setValue("")aT.w=10;aT.h=1;aT.bgcolor=a.InputBG;aT.fgcolor=a.InputFG;local cW=1;local cX=1;local cY=""local cZ;local c_;local d0=cY;local d1=false;local au={getType=function(self)return al end,setInputType=function(self,d2)if d2=="password"or d2=="number"or d2=="text"then cU=d2 end;return self end,setDefaultText=function(self,i,d3,d4)cY=i;cZ=d4 or cZ;c_=d3 or c_;if self:isFocused()then d0=""else d0=cY end;return self end,getInputType=function(self)return cU end,setValue=function(self,d5)aT.setValue(self,tostring(d5))if not d1 then cW=tostring(d5):len()+1 end;return self end,getValue=function(self)local d5=aT.getValue(self)return cU=="number"and tonumber(d5)or d5 end,setInputLimit=function(self,d6)cV=tonumber(d6)or cV;return self end,getInputLimit=function(self)return cV end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then local aX,aY=self:getAnchorPosition()d0=""if self.parent~=nil then self.parent:setCursor(true,aX+cW-cX,aY,self.fgcolor)end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)d0=cY end end,keyHandler=function(self,a5,aN)if aT.keyHandler(self,a5,aN)then d1=true;if a5=="key"then if aN==keys.backspace then local i=tostring(aT.getValue())if cW>1 then self:setValue(i:sub(1,cW-2)..i:sub(cW,i:len()))if cW>1 then cW=cW-1 end;if cX>1 then if cWd7 then cW=d7+1 end;if cW<1 then cW=1 end;if cW=self.w+cX then cX=cW-self.w+1 end;if cX<1 then cX=1 end end;if aN==keys.left then cW=cW-1;if cW>=1 then if cW=self.w+cX then cX=cW end end;if cW<1 then cW=1 end;if cX<1 then cX=1 end end end;if a5=="char"then local i=aT.getValue()if i:len()=self.w+cX then cX=cX+1 end end end;local aX,aY=self:getAnchorPosition()local d5=tostring(aT.getValue())local d9=(cW<=d5:len()and cW-1 or d5:len())-(cX-1)if d9>self.x+self.w-1 then d9=self.x+self.w-1 end;if self.parent~=nil then self.parent:setCursor(true,aX+d9,aY,self.fgcolor)end;d1=false end end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then if a5=="mouse_click"and aK==1 then end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.h,"center")self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)for l=1,self.h do if l==aZ then local d5=tostring(aT.getValue())local d4=self.bgcolor;local d3=self.fgcolor;local i;if d5:len()<=0 then i=d0;d4=cZ or d4;d3=c_ or d3 end;i=d0;if d5~=""then i=d5 end;i=i:sub(cX,self.w+cX-1)local da=self.w-i:len()if da<0 then da=0 end;if cU=="password"and d5~=""then i=string.rep("*",i:len())end;i=i..string.rep(" ",da)self.parent:writeText(aX,aY+l-1,i,d4,d3)end end end end end}return setmetatable(au,aT)end;local function db(ak)local aT=aj(ak)local al="Textfield"local dc,cX,cW,dd=1,1,1,1;local de={""}local df={[colors.purple]={"break"}}aT.w=20;aT.h=8;aT.bgcolor=a.textfieldBG;aT.fgcolor=a.textfieldFG;aT:setZIndex(5)local au={getType=function(self)return al end,getLines=function(self)return de end,getLine=function(self,a4)return de[a4]or""end,editLine=function(self,a4,i)de[a4]=i or de[a4]return self end,addLine=function(self,i,a4)if a4~=nil then table.insert(de,a4,i)else table.insert(de,i)end;return self end,addKeyword=function(self,dg,aC)end,removeLine=function(self,a4)table.remove(de,a4 or#de)if#de<=0 then table.insert(de,"")end;return self end,getTextCursor=function(self)return cW,dd end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then local aX,aY=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,aX+cW-cX,aY+dd-dc,self.fgcolor)end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,a5,aN)if aT.keyHandler(self,a5,aN)then local aX,aY=self:getAnchorPosition()if a5=="key"then if aN==keys.backspace then if de[dd]==""then if dd>1 then table.remove(de,dd)cW=de[dd-1]:len()+1;cX=cW-self.w+1;if cX<1 then cX=1 end;dd=dd-1 end elseif cW<=1 then if dd>1 then cW=de[dd-1]:len()+1;cX=cW-self.w+1;if cX<1 then cX=1 end;de[dd-1]=de[dd-1]..de[dd]table.remove(de,dd)dd=dd-1 end else de[dd]=de[dd]:sub(1,cW-2)..de[dd]:sub(cW,de[dd]:len())if cW>1 then cW=cW-1 end;if cX>1 then if cWde[dd]:len()then if de[dd+1]~=nil then de[dd]=de[dd]..de[dd+1]table.remove(de,dd+1)end else de[dd]=de[dd]:sub(1,cW-1)..de[dd]:sub(cW+1,de[dd]:len())end end;if aN==keys.enter then table.insert(de,dd+1,de[dd]:sub(cW,de[dd]:len()))de[dd]=de[dd]:sub(1,cW-1)dd=dd+1;cW=1;cX=1;if dd-dc>=self.h then dc=dc+1 end;self:setValue("")end;if aN==keys.up then if dd>1 then dd=dd-1;if cW>de[dd]:len()+1 then cW=de[dd]:len()+1 end;if cX>1 then if cW1 then if ddde[dd]:len()+1 then cW=de[dd]:len()+1 end;if dd>=dc+self.h then dc=dc+1 end end end;if aN==keys.right then cW=cW+1;if dd<#de then if cW>de[dd]:len()+1 then cW=1;dd=dd+1 end elseif cW>de[dd]:len()then cW=de[dd]:len()+1 end;if cW<1 then cW=1 end;if cW=self.w+cX then cX=cW-self.w+1 end;if cX<1 then cX=1 end end;if aN==keys.left then cW=cW-1;if cW>=1 then if cW=self.w+cX then cX=cW end end;if dd>1 then if cW<1 then dd=dd-1;cW=de[dd]:len()+1;cX=cW-self.w+1 end end;if cW<1 then cW=1 end;if cX<1 then cX=1 end end end;if a5=="char"then de[dd]=de[dd]:sub(1,cW-1)..aN..de[dd]:sub(cW,de[dd]:len())cW=cW+1;if cW>=self.w+cX then cX=cX+1 end;self:setValue("")end;local d9=(cW<=de[dd]:len()and cW-1 or de[dd]:len())-(cX-1)if d9>self.x+self.w-1 then d9=self.x+self.w-1 end;local dh=dd-dcde[dd]:len()then cW=de[dd]:len()+1 end;if cWde[dd]:len()then cW=de[dd]:len()+1 end;if cW#de-(self.h-1)then dc=#de-(self.h-1)end;if dc<1 then dc=1 end;if self.parent~=nil then if aX+cW-cX>=aX and aX+cW-cX<=aX+self.w and(aY+dd-dc>=aY and aY+dd-dc<=aY+self.h)then self.parent:setCursor(true,di+cW-cX,dj+dd-dc)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)for l=1,self.h do local i=""if de[l+dc-1]~=nil then i=de[l+dc-1]end;i=i:sub(cX,self.w+cX-1)local da=self.w-i:len()if da<0 then da=0 end;i=i..string.rep(" ",da)self.parent:setText(aX,aY+l-1,i)end end end end}return setmetatable(au,aT)end;local function dk(ak)local aT=aj(ak)local al="List"aT.w=16;aT.h=6;aT.bgcolor=a.listBG;aT.fgcolor=a.listFG;aT:setZIndex(5)local dl={}local dm=a.selectionBG;local dn=a.selectionFG;local dp=true;local dq="left"local dr=0;local ds=true;local au={getType=function(self)return al end,addItem=function(self,i,W,X,...)table.insert(dl,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})if#dl==1 then self:setValue(dl[1])end;return self end,setIndexOffset=function(self,dt)dr=dt;return self end,getIndexOffset=function(self)return dr end,removeItem=function(self,a4)table.remove(dl,a4)return self end,getItem=function(self,a4)return dl[a4]end,getItemIndex=function(self)local du=self:getValue()for a8,a9 in pairs(dl)do if a9==du then return a8 end end end,clear=function(self)dl={}self:setValue({})return self end,getItemCount=function(self)return#dl end,editItem=function(self,a4,i,W,X,...)table.remove(dl,a4)table.insert(dl,a4,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,selectItem=function(self,a4)self:setValue(dl[a4]or{})return self end,setSelectedItem=function(self,W,X,dv)dm=W or self.bgcolor;dn=X or self.fgcolor;dp=dv;return self end,setScrollable=function(self,dw)ds=dw;return self end,mouseClickHandler=function(self,a5,aK,L,M)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if aX<=L and aX+self.w>L and aY<=M and aY+self.h>M and self:isVisible()then if a5=="mouse_click"or a5=="mouse_drag"then if aK==1 then if#dl>0 then for l=1,self.h do if dl[l+dr]~=nil then if aX<=L and aX+self.w>L and aY+l-1==M then self:setValue(dl[l+dr])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,L,M,dl[l+dr])end end end end end end;if a5=="mouse_scroll"and ds then dr=dr+aK;if dr<0 then dr=0 end;if aK>=1 then if#dl>self.h then if dr>#dl-self.h then dr=#dl-self.h end;if dr>=#dl then dr=#dl-1 end else dr=dr-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)for l=1,self.h do if dl[l+dr]~=nil then if dl[l+dr]==self:getValue()then if dp then self.parent:writeText(aX,aY+l-1,h(dl[l+dr].text,self.w,dq),dm,dn)else self.parent:writeText(aX,aY+l-1,h(dl[l+dr].text,self.w,dq),dl[l+dr].bgCol,dl[l+dr].fgCol)end else self.parent:writeText(aX,aY+l-1,h(dl[l+dr].text,self.w,dq),dl[l+dr].bgCol,dl[l+dr].fgCol)end end end end end end}return setmetatable(au,aT)end;local function dx(ak)local aT=aj(ak)local al="Menubar"local au={}aT.w=30;aT.h=1;aT.bgcolor=colors.gray;aT.fgcolor=colors.lightGray;aT:setZIndex(5)local dl={}local dm=a.selectionBG;local dn=a.selectionFG;local dp=true;local dq="left"local dy=0;local da=2;local ds=false;local function dz()local dA=0;local ay=1;for l=1,#dl do if ay+dl[l].text:len()+da*2>au.w then dA=dA+dl[l].text:len()+da*2 end;ay=ay+dl[l].text:len()+da*2 end;return dA end;au={getType=function(self)return al end,addItem=function(self,i,W,X,...)table.insert(dl,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})if#dl==1 then self:setValue(dl[1])end;return self end,getItemIndex=function(self)local du=self:getValue()for a8,a9 in pairs(dl)do if a9==du then return a8 end end end,clear=function(self)dl={}self:setValue({})return self end,setSpace=function(self,dB)da=dB or da;return self end,setButtonOffset=function(self,o)dy=o or 0;if dy<0 then dy=0 end;local dA=dz()if dy>dA then dy=dA end;return self end,setScrollable=function(self,dw)ds=dw;return self end,removeItem=function(self,a4)table.remove(dl,a4)return self end,getItem=function(self,a4)return dl[a4]end,getItemCount=function(self)return#dl end,editItem=function(self,a4,i,W,X,...)table.remove(dl,a4)table.insert(dl,a4,{text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,selectItem=function(self,a4)self:setValue(dl[a4]or{})return self end,setSelectedItem=function(self,W,X,dv)dm=W or self.bgcolor;dn=X or self.fgcolor;dp=dv;return self end,mouseClickHandler=function(self,a5,aK,L,M)local aL,aM=self:getAbsolutePosition(self:getAnchorPosition())if aL<=L and aL+self.w>L and aM<=M and aM+self.h>M and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if a5=="mouse_click"then local ay=1;for l=1+dy,#dl do if dl[l]~=nil then if ay+dl[l].text:len()+da*2<=self.w then if aL+ay-1<=L and aL+ay-1+dl[l].text:len()+da*2>L and aM==M then self:setValue(dl[l])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,L,M,dl[l])end;ay=ay+dl[l].text:len()+da*2 else break end end end end;if a5=="mouse_scroll"and ds then dy=dy+aK;if dy<0 then dy=0 end;local dA=dz()if dy>dA then dy=dA end end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)local ay=0;for a8,a9 in pairs(dl)do if ay+a9.text:len()+da*2<=self.w then if a9==self:getValue()then self.parent:writeText(aX+ay-1+-dy,aY,h((" "):rep(da)..a9.text..(" "):rep(da),a9.text:len()+da*2,dq),dm or a9.bgCol,dn or a9.fgCol)else self.parent:writeText(aX+ay-1+-dy,aY,h((" "):rep(da)..a9.text..(" "):rep(da),a9.text:len()+da*2,dq),a9.bgCol,a9.fgCol)end;ay=ay+a9.text:len()+da*2 else if ay0 then for l=1,dE do if dl[l+dr]~=nil then if aX<=L and aX+dD>L and aY+l==M then self:setValue(dl[l+dr])return true end end end end end end;if a5=="mouse_scroll"then dr=dr+aK;if dr<0 then dr=0 end;if aK==1 then if#dl>dE then if dr>#dl-dE then dr=#dl-dE end else dr=dl-1 end end;return true end;self:setVisualChanged()end;if aT.mouseClickHandler(self,a5,aK,L,M)then dH=2 else dH=1 end end,draw=function(self)if aT.draw(self)then local aX,aY=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)if#dl>=1 then if self:getValue()~=nil then if self:getValue().text~=nil then if dH==1 then self.parent:writeText(aX,aY,h(self:getValue().text,self.w,dq):sub(1,self.w-1)..dF,self.bgcolor,self.fgcolor)else self.parent:writeText(aX,aY,h(self:getValue().text,self.w,dq):sub(1,self.w-1)..dG,self.bgcolor,self.fgcolor)end end end;if dH==2 then for l=1,dE do if dl[l+dr]~=nil then if dl[l+dr]==self:getValue()then if dp then self.parent:writeText(aX,aY+l,h(dl[l+dr].text,dD,dq),dm,dn)else self.parent:writeText(aX,aY+l,h(dl[l+dr].text,dD,dq),dl[l+dr].bgCol,dl[l+dr].fgCol)end else self.parent:writeText(aX,aY+l,h(dl[l+dr].text,dD,dq),dl[l+dr].bgCol,dl[l+dr].fgCol)end end end end end end end end}return setmetatable(au,aT)end;local function dI(ak)local aT=aj(ak)local al="Radio"aT.w=8;aT.bgcolor=a.listBG;aT.fgcolor=a.listFG;aT:setZIndex(5)local dl={}local dm=a.selectionBG;local dn=a.selectionFG;local dJ=aT.bgcolor;local dK=aT.fgcolor;local dp=true;local Y="\7"local dq="left"local au={getType=function(self)return al end,addItem=function(self,i,L,M,W,X,...)table.insert(dl,{x=L or 1,y=M or 1,text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})if#dl==1 then self:setValue(dl[1])end;return self end,removeItem=function(self,a4)table.remove(dl,a4)return self end,getItem=function(self,a4)return dl[a4]end,getItemIndex=function(self)local du=self:getValue()for a8,a9 in pairs(dl)do if a9==du then return a8 end end end,clear=function(self)dl={}self:setValue({})return self end,getItemCount=function(self)return#dl end,editItem=function(self,a4,i,L,M,W,X,...)table.remove(dl,a4)table.insert(dl,a4,{x=L or 1,y=M or 1,text=i,bgCol=W or self.bgcolor,fgCol=X or self.fgcolor,args={...}})return self end,selectItem=function(self,a4)self:setValue(dl[a4]or{})return self end,setSelectedItem=function(self,W,X,dL,dM,dv)dm=W or dm;dn=X or dn;dJ=dL or dJ;dK=dM or dK;dp=dv;return self end,mouseClickHandler=function(self,a5,aK,L,M)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if a5=="mouse_click"then if aK==1 then if#dl>0 then for aJ,a9 in pairs(dl)do if aX+a9.x-1<=L and aX+a9.x-1+a9.text:len()+2>=L and aY+a9.y-1==M then self:setValue(a9)if self.parent~=nil then self.parent:setFocusedObject(self)end;self:setVisualChanged()return true end end end end end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()for aJ,a9 in pairs(dl)do if a9==self:getValue()then if dq=="left"then self.parent:writeText(a9.x+aX-1,a9.y+aY-1,Y,dJ,dK)self.parent:writeText(a9.x+2+aX-1,a9.y+aY-1,a9.text,dm,dn)end else self.parent:drawBackgroundBox(a9.x+aX-1,a9.y+aY-1,1,1,self.bgcolor)self.parent:writeText(a9.x+2+aX-1,a9.y+aY-1,a9.text,a9.bgCol,a9.fgCol)end end end end end}return setmetatable(au,aT)end;local function dN(ak)local al="Timer"local dO=0;local dP=0;local dQ=0;local dR;local at=a2()local au={name=ak,getType=function(self)return al end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,dS,dT)dO=dS or 0;dP=dT or 1;return self end,start=function(self)dQ=dP;dR=os.startTimer(dO)return self end,cancel=function(self)if dR~=nil then os.cancelTimer(dR)end;return self end,onCall=function(self,a7)at:registerEvent("timed_event",a7)return self end,eventHandler=function(self,a5,dU)if a5=="timer"and dU==dR then at:sendEvent("timed_event",self)if dQ>=1 then dQ=dQ-1;if dQ>=1 then dR=os.startTimer(dO)end elseif dQ==-1 then dR=os.startTimer(dO)end end end}au.__index=au;return au end;local function dV(ak)local au;local al="Thread"local a7;local dW;local dX=false;au={name=ak,getType=function(self)return al end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,cS)if cS==nil then error("function is nil")end;a7=cS;dW=coroutine.create(a7)dX=true;local ah,ai=coroutine.resume(dW)if not ah then if ai~="Terminated"then error("Threaderror - "..ai)end end;return self end,getStatus=function(self,cS)if dW~=nil then return coroutine.status(dW)end;return nil end,stop=function(self,cS)dX=false;return self end,eventHandler=function(self,a5,aO,aP,aQ)if dX then if coroutine.status(dW)~="dead"then local ah,ai=coroutine.resume(dW,a5,aO,aP,aQ)if not ah then if ai~="Terminated"then error("Threaderror - "..ai)end end else dX=false end end end}au.__index=au;return au end;local function dY(ak)local au={}local al="Animation"local dR;local dZ={}local a4=1;local d_=0;local e0;local function e1()if dZ[a4]~=nil then dZ[a4].f(au,a4)end;a4=a4+1;if dZ[a4]~=nil then if dZ[a4].t>0 then dR=os.startTimer(dZ[a4].t)else e1()end end end;au={name=ak,getType=function(self)return al end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,a7,e2)e0=a7;table.insert(dZ,{f=a7,t=e2 or d_})return self end,wait=function(self,e2)d_=e2;return self end,rep=function(self,e3)for L=1,e3 do table.insert(dZ,{f=e0,t=d_})end;return self end,clear=function(self)dZ={}e0=nil;d_=0;a4=1;return self end,play=function(self)a4=1;if dZ[a4]~=nil then if dZ[a4].t>0 then dR=os.startTimer(dZ[a4].t)else e1()end end;return self end,cancel=function(self)os.cancelTimer(dR)return self end,eventHandler=function(self,a5,dU)if a5=="timer"and dU==dR then if dZ[a4]~=nil then e1()end end end}au.__index=au;return au end;local function e4(ak)local aT=aj(ak)local al="Slider"aT.w=8;aT.bgcolor=colors.lightGray;aT.fgcolor=colors.gray;aT:setValue(1)local e5="horizontal"local Y=" "local e6=colors.black;local e7="\140"local e8=aT.w;local a4=1;local au={getType=function(self)return al end,setSymbol=function(self,e9)Y=e9:sub(1,1)self:setVisualChanged()return self end,setBackgroundSymbol=function(self,ea)e7=string.sub(ea,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eb)e6=eb;self:setVisualChanged()return self end,setBarType=function(self,ec)e5=ec:lower()return self end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if e5=="horizontal"then for ed=0,self.w-1 do if aX+ed==L and aY<=M and aY+self.h>M then a4=ed+1;self:setValue(e8/self.w*a4)self:setVisualChanged()end end end;if e5=="vertical"then for ed=0,self.h-1 do if aY+ed==M and aX<=L and aX+self.w>L then a4=ed+1;self:setValue(e8/self.h*a4)self:setVisualChanged()end end end end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()if e5=="horizontal"then self.parent:writeText(aX,aY,e7:rep(a4-1),self.bgcolor,self.fgcolor)self.parent:writeText(aX+a4-1,aY,Y,e6,e6)self.parent:writeText(aX+a4,aY,e7:rep(self.w-a4),self.bgcolor,self.fgcolor)end;if e5=="vertical"then for l=0,self.h-1 do if l+1==a4 then self.parent:writeText(aX,aY+l,Y,e6,e6)else self.parent:writeText(aX,aY+l,e7,self.bgcolor,self.fgcolor)end end end end end end}return setmetatable(au,aT)end;local function ee(ak)local aT=aj(ak)local al="Scrollbar"aT.w=1;aT.h=8;aT.bgcolor=colors.lightGray;aT.fgcolor=colors.gray;aT:setValue(1)aT:setZIndex(2)local e5="vertical"local Y=" "local e6=colors.black;local e7="\127"local e8=aT.h;local a4=1;local ef=1;local au={getType=function(self)return al end,setSymbol=function(self,e9)Y=e9:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,eg)ef=tonumber(eg)or 1;if e5=="vertical"then self:setValue(a4-1*e8/(self.h-(ef-1))-e8/(self.h-(ef-1)))elseif e5=="horizontal"then self:setValue(a4-1*e8/(self.w-(ef-1))-e8/(self.w-(ef-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,d5)e8=d5;return self end,setBackgroundSymbol=function(self,ea)e7=string.sub(ea,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eb)e6=eb;self:setVisualChanged()return self end,setBarType=function(self,ec)e5=ec:lower()return self end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if(a5=="mouse_click"or a5=="mouse_drag")and aK==1 then if e5=="horizontal"then for ed=0,self.w do if aX+ed==L and aY<=M and aY+self.h>M then a4=math.min(ed+1,self.w-(ef-1))self:setValue(e8/self.w*a4)self:setVisualChanged()end end end;if e5=="vertical"then for ed=0,self.h do if aY+ed==M and aX<=L and aX+self.w>L then a4=math.min(ed+1,self.h-(ef-1))self:setValue(e8/self.h*a4)self:setVisualChanged()end end end end;if a5=="mouse_scroll"then a4=a4+aK;if a4<1 then a4=1 end;a4=math.min(a4,(e5=="vertical"and self.h or self.w)-(ef-1))self:setValue(e8/(e5=="vertical"and self.h or self.w)*a4)end;return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()if e5=="horizontal"then self.parent:writeText(aX,aY,e7:rep(a4-1),self.bgcolor,self.fgcolor)self.parent:writeText(aX+a4-1,aY,Y:rep(ef),e6,e6)self.parent:writeText(aX+a4+ef-1,aY,e7:rep(self.w-(a4+ef-1)),self.bgcolor,self.fgcolor)end;if e5=="vertical"then for l=0,self.h-1 do if a4==l+1 then for eh=0,math.min(ef-1,self.h)do self.parent:writeText(aX,aY+l+eh,Y,e6,e6)end else if l+1a4-1+ef then self.parent:writeText(aX,aY+l,e7,self.bgcolor,self.fgcolor)end end end end end end end}return setmetatable(au,aT)end;local function ei(ak)local aT=aj(ak)local al="Switch"aT.w=3;aT.h=1;aT.bgcolor=colors.lightGray;aT.fgcolor=colors.gray;aT:setValue(false)aT:setZIndex(5)local au={getType=function(self)return al end,mouseClickHandler=function(self,a5,aK,L,M)if aT.mouseClickHandler(self,a5,aK,L,M)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if(a5=="mouse_click"or a5=="mouse_drag")and aK==1 then end;return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()end end end}return setmetatable(au,aT)end;local function ej(ak,ek)local aT=aj(ak)local al="Frame"local el={}local em={}local au={}local en;aT:setZIndex(10)local b5=false;local b1=1;local b2=1;local eo=colors.white;local ep,dr=0,0;if ek~=nil then aT.parent=ek;aT.w,aT.h=ek.w,ek.h;aT.bgcolor=a.FrameBG;aT.fgcolor=a.FrameFG else local eq,er=f.getSize()aT.w,aT.h=eq,er;aT.bgcolor=a.basaltBG;aT.fgcolor=a.basaltFG end;local function es(ak)for a8,a9 in pairs(el)do for cp,bD in pairs(a9)do if bD.name==ak then return a9 end end end end;local function et(eu)local an=eu:getZIndex()if es(eu.name)~=nil then return nil end;if el[an]==nil then for L=1,#em+1 do if em[L]~=nil then if an==em[L]then break end;if an>em[L]then table.insert(em,L,an)break end else table.insert(em,an)end end;if#em<=0 then table.insert(em,an)end;el[an]={}end;eu.parent=au;table.insert(el[an],eu)return eu end;local function ev(eu)for cp,bD in pairs(el)do for a8,a9 in pairs(bD)do if a9==eu then table.remove(el[cp],a8)return true end end end;return false end;au={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return al end,setFocusedObject=function(self,eu)for aJ,a4 in pairs(em)do for aJ,a9 in pairs(el[a4])do if a9==eu then if en~=nil then en:loseFocusHandler()end;en=eu;en:getFocusHandler()end end end;return self end,setOffset=function(self,aG,aH)ep=aG~=nil and math.floor(aG<0 and math.abs(aG)or-aG)or ep;dr=aH~=nil and math.floor(aH<0 and math.abs(aH)or-aH)or dr;return self end,getFrameOffset=function(self)return ep,dr end,removeFocusedObject=function(self)if en~=nil then en:loseFocusHandler()end;en=nil;return self end,getFocusedObject=function(self)return en end,show=function(self)aT:show()if self.parent==nil then c=self end;return self end,setCursor=function(self,ew,ex,ey,aC)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())b5=ew or false;if ex~=nil then b1=aX+ex-1 end;if ey~=nil then b2=aY+ey-1 end;eo=aC or eo;self:setVisualChanged()return self end,setMoveable=function(self,ez)self.isMoveable=ez or not self.isMoveable;self:setVisualChanged()return self end,showBar=function(self,eA)self.barActive=eA or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,i,W,X)self.barText=i or""self.barBackground=W or self.barBackground;self.barTextcolor=X or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,dq)self.barTextAlign=dq or"left"self:setVisualChanged()return self end,getVisualChanged=function(self)local eB=aT.getVisualChanged(self)for aJ,a4 in pairs(em)do if el[a4]~=nil then for aJ,a9 in pairs(el[a4])do if a9.getVisualChanged~=nil and a9:getVisualChanged()then eB=true end end end end;return eB end,loseFocusHandler=function(self)aT.loseFocusHandler(self)end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,a5,aN)if en~=nil then if en.keyHandler~=nil then if en:keyHandler(a5,aN)then return true end end end;return false end,backgroundKeyHandler=function(self,a5,aN)aT.backgroundKeyHandler(self,a5,aN)for aJ,a4 in pairs(em)do if el[a4]~=nil then for aJ,a9 in pairs(el[a4])do if a9.backgroundKeyHandler~=nil then a9:backgroundKeyHandler(a5,aN)end end end end end,eventHandler=function(self,a5,aO,aP,aQ,aR)aT.eventHandler(self,a5,aO,aP,aQ,aR)for aJ,a4 in pairs(em)do if el[a4]~=nil then for aJ,a9 in pairs(el[a4])do if a9.eventHandler~=nil then a9:eventHandler(a5,aO,aP,aQ,aR)end end end end;if a5=="terminate"then f.clear()f.setCursorPos(1,1)b.stop()end end,mouseClickHandler=function(self,a5,aK,L,M)local aG,aH=self:getOffset()aG=aG<0 and math.abs(aG)or-aG;aH=aH<0 and math.abs(aH)or-aH;if self.drag then if a5=="mouse_drag"then local eC=1;local eD=1;if self.parent~=nil then eC,eD=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(L+self.xToRem-(eC-1)+aG,M-(eD-1)+aH)end;if a5=="mouse_up"then self.drag=false end;return true end;if aT.mouseClickHandler(self,a5,aK,L,M)then local aD,aE=self:getAbsolutePosition(self:getAnchorPosition())for aJ,a4 in pairs(em)do if el[a4]~=nil then for aJ,a9 in p(el[a4])do if a9.mouseClickHandler~=nil then if a9:mouseClickHandler(a5,aK,L+aG,M+aH)then return true end end end end end;if self.isMoveable then if L>=aD and L<=aD+self.w-1 and M==aE and a5=="mouse_click"then self.drag=true;self.xToRem=aD-L end end;if en~=nil then en:loseFocusHandler()en=nil end;return true end;return false end,setText=function(self,L,M,i)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:setText(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(i,math.max(1-L+1,1),self.w-L+1))else V.setText(math.max(L+aX-1,aX),aY+M-1,g(i,math.max(1-L+1,1),self.w-L+1))end end end,setBG=function(self,L,M,W)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:setBG(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(W,math.max(1-L+1,1),self.w-L+1))else V.setBG(math.max(L+aX-1,aX),aY+M-1,g(W,math.max(1-L+1,1),self.w-L+1))end end end,setFG=function(self,L,M,X)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:setFG(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(X,math.max(1-L+1,1),self.w-L+1))else V.setFG(math.max(L+aX-1,aX),aY+M-1,g(X,math.max(1-L+1,1),self.w-L+1))end end end,writeText=function(self,L,M,i,W,X)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if M>=1 and M<=self.h then if self.parent~=nil then self.parent:writeText(math.max(L+aX-1,aX)-(self.parent.x-1),aY+M-1-(self.parent.y-1),g(i,math.max(1-L+1,1),self.w-L+1),W,X)else V.writeText(math.max(L+aX-1,aX),aY+M-1,g(i,math.max(1-L+1,1),self.w-L+1),W,X)end end end,drawBackgroundBox=function(self,L,M,j,n,W)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())n=M<1 and(n+M>self.h and self.h or n+M-1)or(n+M>self.h and self.h-M+1 or n)j=L<1 and(j+L>self.w and self.w or j+L-1)or(j+L>self.w and self.w-L+1 or j)if self.parent~=nil then self.parent:drawBackgroundBox(math.max(L+aX-1,aX)-(self.parent.x-1),math.max(M+aY-1,aY)-(self.parent.y-1),j,n,W)else V.drawBackgroundBox(math.max(L+aX-1,aX),math.max(M+aY-1,aY),j,n,W)end end,drawTextBox=function(self,L,M,j,n,Y)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())n=M<1 and(n+M>self.h and self.h or n+M-1)or(n+M>self.h and self.h-M+1 or n)j=L<1 and(j+L>self.w and self.w or j+L-1)or(j+L>self.w and self.w-L+1 or j)if self.parent~=nil then self.parent:drawTextBox(math.max(L+aX-1,aX)-(self.parent.x-1),math.max(M+aY-1,aY)-(self.parent.y-1),j,n,Y:sub(1,1))else V.drawTextBox(math.max(L+aX-1,aX),math.max(M+aY-1,aY),j,n,Y:sub(1,1))end end,drawForegroundBox=function(self,L,M,j,n,X)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())n=M<1 and(n+M>self.h and self.h or n+M-1)or(n+M>self.h and self.h-M+1 or n)j=L<1 and(j+L>self.w and self.w or j+L-1)or(j+L>self.w and self.w-L+1 or j)if self.parent~=nil then self.parent:drawForegroundBox(math.max(L+aX-1,aX)-(self.parent.x-1),math.max(M+aY-1,aY)-(self.parent.y-1),j,n,X)else V.drawForegroundBox(math.max(L+aX-1,aX),math.max(M+aY-1,aY),j,n,X)end end,draw=function(self)if self:getVisualChanged()then if aT.draw(self)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())local di,dj=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(di,dj,self.w,self.h,self.bgcolor)self.parent:drawForegroundBox(di,dj,self.w,self.h,self.fgcolor)self.parent:drawTextBox(di,dj,self.w,self.h," ")else V.drawBackgroundBox(aX,aY,self.w,self.h,self.bgcolor)V.drawForegroundBox(aX,aY,self.w,self.h,self.fgcolor)V.drawTextBox(aX,aY,self.w,self.h," ")end;f.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(di,dj,h(self.barText,self.w,self.barTextAlign),self.barBackground,self.barTextcolor)else V.writeText(aX,aY,h(self.barText,self.w,self.barTextAlign),self.barBackground,self.barTextcolor)end end;for aJ,a4 in p(em)do if el[a4]~=nil then for aJ,a9 in pairs(el[a4])do if a9.draw~=nil then a9:draw()end end end end;if b5 then f.setTextColor(eo)f.setCursorPos(b1,b2)if self.parent~=nil then f.setCursorBlink(self:isFocused())else f.setCursorBlink(b5)end end;self:setVisualChanged(false)end end end,addObject=function(self,eu)return et(eu)end,removeObject=function(self,eu)return ev(eu)end,getObject=function(self,eu)return es(eu)end,addButton=function(self,ak)local eu=aS(ak)eu.name=ak;return et(eu)end,addLabel=function(self,ak)local eu=c0(ak)eu.name=ak;eu.bgcolor=self.bgcolor;eu.fgcolor=self.fgcolor;return et(eu)end,addCheckbox=function(self,ak)local eu=cI(ak)eu.name=ak;return et(eu)end,addInput=function(self,ak)local eu=cT(ak)eu.name=ak;return et(eu)end,addProgram=function(self,ak)local eu=a_(ak)eu.name=ak;return et(eu)end,addTextfield=function(self,ak)local eu=db(ak)eu.name=ak;return et(eu)end,addList=function(self,ak)local eu=dk(ak)eu.name=ak;return et(eu)end,addDropdown=function(self,ak)local eu=dC(ak)eu.name=ak;return et(eu)end,addRadio=function(self,ak)local eu=dI(ak)eu.name=ak;return et(eu)end,addTimer=function(self,ak)local eu=dN(ak)eu.name=ak;return et(eu)end,addAnimation=function(self,ak)local eu=dY(ak)eu.name=ak;return et(eu)end,addSlider=function(self,ak)local eu=e4(ak)eu.name=ak;return et(eu)end,addScrollbar=function(self,ak)local eu=ee(ak)eu.name=ak;return et(eu)end,addMenubar=function(self,ak)local eu=dx(ak)eu.name=ak;return et(eu)end,addThread=function(self,ak)local eu=dV(ak)eu.name=ak;return et(eu)end,addPane=function(self,ak)local eu=c2(ak)eu.name=ak;return et(eu)end,addImage=function(self,ak)local eu=c3(ak)eu.name=ak;return et(eu)end,addProgressbar=function(self,ak)local eu=cJ(ak)eu.name=ak;return et(eu)end,addFrame=function(self,ak)local eu=ej(ak,self)eu.name=ak;return et(eu)end}setmetatable(au,aT)if ek==nil then table.insert(d,au)end;return au end;local eE=false;local function eF(a5,aO,aP,aQ,aR)if a5=="mouse_click"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="mouse_drag"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="mouse_up"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="mouse_scroll"then c:mouseClickHandler(a5,aO,aP,aQ,aR)end;if a5=="key"or a5=="char"then c:keyHandler(a5,aO)c:backgroundKeyHandler(a5,aO)end;for aJ,a9 in pairs(d)do a9:eventHandler(a5,aO,aP,aQ,aR)end;if eE then c:draw()V.update()end end;function b.autoUpdate(dX)f.clear()eE=dX or true;c:draw()V.update()while eE do local a5,aO,aP,aQ,aR=os.pullEventRaw()eF(a5,aO,aP,aQ,aR)end end;function b.update(a5,aO,aP,aQ,aR)if a5~="nil"then eF(a5,aO,aP,aQ,aR)else c:draw()V.update()end end;function b.stop()eE=false end;function b.getFrame(ak)for a8,a9 in pairs(d)do if a9.name==ak then return a9 end end end;function b.getActiveFrame()return c end;function b.setActiveFrame(av)if av:getType()=="Frame"then c=av;return true end;return false end;function b.createFrame(ak)local av=ej(ak)return av end;function b.removeFrame(ak)for a8,a9 in pairs(d)do if a9.name==ak then d[a8]=nil;return true end end;return false end;if b.debugger then b.debugFrame=b.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug",colors.black,colors.gray)b.debugList=b.debugFrame:addList("debugList"):setSize(b.debugFrame.w-2,b.debugFrame.h-3):setPosition(2,3):setScrollable(true):show()b.debugFrame:addButton("back"):setAnchor("right"):setSize(1,1):setText("\22"):onClick(function()b.oldFrame:show()end):setBackground(colors.red):show()b.debugLabel=b.debugFrame:addLabel("debugLabel"):onClick(function()b.oldFrame=c;b.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):setZIndex(20):show()end;if b.debugger then function b.debug(...)local af={...}if c.name~="basaltDebuggingFrame"then if c~=b.debugLabel.frame then b.debugLabel:setParent(c)end end;local eG=""for a8,a9 in pairs(af)do eG=eG..tostring(a9)..(#af~=a8 and", "or"")end;b.debugLabel:setText("[Debug] "..eG)b.debugList:addItem(eG)if b.debugList:getItemCount()>50 then b.debugList:removeItem(1)end;b.debugList:setValue(b.debugList:getItem(b.debugList:getItemCount()))b.debugLabel:show()end end;return b \ No newline at end of file diff --git a/source/basalt.lua b/source/basalt.lua index 8826f32..8f32c3c 100644 --- a/source/basalt.lua +++ b/source/basalt.lua @@ -650,14 +650,18 @@ local function Object(name) -- Base object return self end; - registerEvent = function(self,event, func) + registerEvent = function(self, event, func) return eventSystem:registerEvent(event, func) end; - removeEvent = function(self,event, index) + removeEvent = function(self, event, index) return eventSystem:removeEvent(event, index) end; + sendEvent = function(self, event, ...) + return eventSystem:sendEvent(event, self, ...) + end; + mouseClickHandler = function(self, event, button, x, y) local objX,objY = self:getAbsolutePosition(self:getAnchorPosition()) if(objX<=x)and(objX+self.w>x)and(objY<=y)and(objY+self.h>y)and(isVisible)then @@ -1423,7 +1427,7 @@ local function Pane(name) -- Pane if(self.parent~=nil)then local obx, oby = self:getAnchorPosition() self.parent:drawBackgroundBox(obx, oby, self.w, self.h, self.bgcolor) - self.parent:drawForegroundBox(obx, oby, self.w, self.h, self.fgcolor) + self.parent:drawForegroundBox(obx, oby, self.w, self.h, self.bgcolor) end end end; @@ -1438,9 +1442,105 @@ local function Image(name) -- Pane local typ = "Image" base:setZIndex(2) local image + local shrinkedImage + local imageGotShrinked = false local function shrink() + -- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ + local relations = {[0] = {8, 4, 3, 6, 5}, {4, 14, 8, 7}, {6, 10, 8, 7}, {9, 11, 8, 0}, {1, 14, 8, 0}, {13, 12, 8, 0}, {2, 10, 8, 0}, {15, 8, 10, 11, 12, 14}, + {0, 7, 1, 9, 2, 13}, {3, 11, 8, 7}, {2, 6, 7, 15}, {9, 3, 7, 15}, {13, 5, 7, 15}, {5, 12, 8, 7}, {1, 4, 7, 15}, {7, 10, 11, 12, 14}} + +local colourNum, exponents, colourChar = {}, {}, {} +for i = 0, 15 do exponents[2^i] = i end +do + local hex = "0123456789abcdef" + for i = 1, 16 do + colourNum[hex:sub(i, i)] = i - 1 + colourNum[i - 1] = hex:sub(i, i) + colourChar[hex:sub(i, i)] = 2 ^ (i - 1) + colourChar[2 ^ (i - 1)] = hex:sub(i, i) + + local thisRel = relations[i - 1] + for i = 1, #thisRel do thisRel[i] = 2 ^ thisRel[i] end + end +end + +local function getBestColourMatch(usage) + local lastCol = relations[exponents[usage[#usage][1]]] + + for j = 1, #lastCol do + local thisRelation = lastCol[j] + for i = 1, #usage - 1 do if usage[i][1] == thisRelation then return i end end + end + + return 1 +end + +local function colsToChar(pattern, totals) + if not totals then + local newPattern = {} + totals = {} + for i = 1, 6 do + local thisVal = pattern[i] + local thisTot = totals[thisVal] + totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal + end + pattern = newPattern + end + + local usage = {} + for key, value in pairs(totals) do usage[#usage + 1] = {key, value} end + + if #usage > 1 then + -- Reduce the chunk to two colours: + while #usage > 2 do + table.sort(usage, function (a, b) return a[2] > b[2] end) + local matchToInd, usageLen = getBestColourMatch(usage), #usage + local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1] + for i = 1, 6 do if pattern[i] == matchFrom then + pattern[i] = matchTo + usage[matchToInd][2] = usage[matchToInd][2] + 1 + end end + usage[usageLen] = nil + end + + -- Convert to character. Adapted from oli414's function: + -- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/ + local data = 128 + for i = 1, #pattern - 1 do if pattern[i] ~= pattern[6] then data = data + 2^(i-1) end end + return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]] + else + -- Solid colour character: + return "\128", colourChar[pattern[1]], colourChar[pattern[1]] + end +end + + local results, width, height, bgCol = {{}, {}, {}}, 0, #image + #image % 3, base.bgcolor or colors.black + for i = 1, #image do if #image[i] > width then width = #image[i] end end + + for y = 0, height - 1, 3 do + local cRow, tRow, bRow, counter = {}, {}, {}, 1 + + for x = 0, width - 1, 2 do + -- Grab a 2x3 chunk: + local pattern, totals = {}, {} + + for yy = 1, 3 do for xx = 1, 2 do + pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol + totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1 + end end + + cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals) + counter = counter + 1 + end + + results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow) + end + + results.width, results.height = #results[1][1], #results[1] + + shrinkedImage = results end local object = { @@ -1450,6 +1550,19 @@ local function Image(name) -- Pane loadImage = function(self, path) image = paintutils.loadImage(path) + imageGotShrinked = false + return self + end; + + loadBlittleImage = function(self, path) + --image = paintutils.loadImage(path) + imageGotShrinked = true + return self + end; + + shrinkImage = function(self) + shrink() + imageGotShrinked = true return self end; @@ -1458,12 +1571,27 @@ local function Image(name) -- Pane if(self.parent~=nil)then if(image~=nil)then local obx, oby = self:getAnchorPosition() - - for yPos=1,math.min(#image, self.h) do - local line = image[yPos] - for xPos=1,math.min(#line, self.w) do - if line[xPos] > 0 then - self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos]) + if(imageGotShrinked)then -- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ + local t, tC, bC = shrinkedImage[1], shrinkedImage[2], shrinkedImage[3] + for i = 1, shrinkedImage.height do + local tI = t[i] + if type(tI) == "string" then + self.parent:setText(obx, oby + i - 1, tI) + self.parent:setFG(obx, oby + i - 1, tC[i]) + self.parent:setBG(obx, oby + i - 1, bC[i]) + elseif type(tI) == "table" then + self.parent:setText(obx, oby + i - 1, tI[2]) + self.parent:setFG(obx, oby + i - 1, tC[i]) + self.parent:setBG(obx, oby + i - 1, bC[i]) + end + end + else + for yPos=1,math.min(#image, self.h) do + local line = image[yPos] + for xPos=1,math.min(#line, self.w) do + if line[xPos] > 0 then + self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos]) + end end end end @@ -1533,6 +1661,105 @@ local function Checkbox(name) -- Checkbox return setmetatable(object, base) end +local function Progressbar(name) -- Checkbox + local base = Object(name) + local typ = "Progressbar" + + local progress = 0 + + base:setZIndex(5) + base:setValue(false) + base.w = 25 + base.h = 1 + base.bgcolor = theme.CheckboxBG + base.fgcolor = theme.CheckboxFG + + local activeBarColor = colors.black + local activeBarSymbol = "" + local activeBarSymbolCol = colors.white + local bgBarSymbol = "" + local direction = 0 + + local object = { + + getType = function(self) + return typ + end; + + setDirection = function(self, dir) + direction = dir + return self + end; + + setProgressBar = function(self, color, symbol, symbolcolor) + activeBarColor = color or activeBarColor + activeBarSymbol = symbol or activeBarSymbol + activeBarSymbolCol = symbolcolor or activeBarSymbolCol + return self + end; + + setBackgroundSymbol = function(self, symbol) + bgBarSymbol = symbol:sub(1,1) + return self + end; + + setProgress = function(self, value) + if(value>=0)and(value<=100)and(progress~=value)then + progress = value + self:setValue(progress) + if(progress==100)then + self:progressDoneHandler() + end + end + return self + end; + + getProgress = function(self) + return progress + end; + + onProgressDone = function(self, f) + self:registerEvent("progress_done", f) + return self + end; + + progressDoneHandler = function(self) + self:sendEvent("progress_done") + end; + + draw = function(self) + if(base.draw(self))then + if(self.parent~=nil)then + local obx, oby = self:getAnchorPosition() + self.parent:drawBackgroundBox(obx, oby, self.w, self.h, self.bgcolor) + self.parent:drawForegroundBox(obx, oby, self.w, self.h, self.fgcolor) + self.parent:drawTextBox(obx, oby, self.w, self.h, bgBarSymbol) + if(direction==1)then + self.parent:drawBackgroundBox(obx, oby, self.w, self.h/100*progress, activeBarColor) + self.parent:drawForegroundBox(obx, oby, self.w, self.h/100*progress, activeBarSymbolCol) + self.parent:drawTextBox(obx, oby, self.w, self.h/100*progress, activeBarSymbol) + elseif(direction==2)then + self.parent:drawBackgroundBox(obx, oby+math.ceil(self.h-self.h/100*progress), self.w, self.h/100*progress, activeBarColor) + self.parent:drawForegroundBox(obx, oby+math.ceil(self.h-self.h/100*progress), self.w, self.h/100*progress, activeBarSymbolCol) + self.parent:drawTextBox(obx, oby+math.ceil(self.h-self.h/100*progress), self.w, self.h/100*progress, activeBarSymbol) + elseif(direction==3)then + self.parent:drawBackgroundBox(obx+math.ceil(self.w-self.w/100*progress), oby, self.w/100*progress, self.h, activeBarColor) + self.parent:drawForegroundBox(obx+math.ceil(self.w-self.w/100*progress), oby, self.w/100*progress, self.h, activeBarSymbolCol) + self.parent:drawTextBox(obx+math.ceil(self.w-self.w/100*progress), oby, self.w/100*progress, self.h, activeBarSymbol) + else + self.parent:drawBackgroundBox(obx, oby, self.w/100*progress, self.h, activeBarColor) + self.parent:drawForegroundBox(obx, oby, self.w/100*progress, self.h, activeBarSymbolCol) + self.parent:drawTextBox(obx, oby, self.w/100*progress, self.h, activeBarSymbol) + end + end + end + end; + + } + + return setmetatable(object, base) +end + local function Input(name) -- Input local base = Object(name) local typ = "Input" @@ -1756,8 +1983,7 @@ local function Textfield(name) local hIndex, wIndex, textX, textY = 1, 1, 1, 1 local lines = {""} - local selection = {} - local selectionColor = colors.lightBlue + local keyWords = {[colors.purple] = {"break"}} base.w = 20 base.h = 8 @@ -1792,6 +2018,10 @@ local function Textfield(name) return self end; + addKeyword = function(self, keyword, color) + + end; + removeLine = function(self, index) table.remove(lines, index or #lines) if(#lines <= 0)then @@ -1858,6 +2088,17 @@ local function Textfield(name) self:setValue("") end + if(key==keys.delete)then -- on delete + if(textX>lines[textY]:len())then + if(lines[textY+1]~=nil)then + lines[textY] = lines[textY]..lines[textY+1] + table.remove(lines, textY+1) + end + else + lines[textY] = lines[textY]:sub(1,textX-1)..lines[textY]:sub(textX+1,lines[textY]:len()) + end + end + if(key==keys.enter)then -- on enter table.insert(lines,textY+1,lines[textY]:sub(textX,lines[textY]:len())) lines[textY] = lines[textY]:sub(1,textX-1) @@ -1969,6 +2210,22 @@ local function Textfield(name) end end end + if(event=="mouse_drag")then + if(lines[y-oby+hIndex]~=nil)then + textX = x-obx+wIndex + textY = y-oby+hIndex + if(textX>lines[textY]:len())then + textX = lines[textY]:len()+1 + end + if(textX base.w)then - mScroll = mScroll + 1 + if(xPos + list[n].text:len() + space*2 > object.w)then + mScroll = mScroll + list[n].text:len() + space*2 end xPos = xPos+list[n].text:len()+space*2 @@ -2199,7 +2457,7 @@ local function Menubar(name) return mScroll end - local object = { + object = { getType = function(self) return typ end; @@ -2324,18 +2582,23 @@ local function Menubar(name) if(self.parent~=nil)then local obx, oby = self:getAnchorPosition() self.parent:drawBackgroundBox(obx, oby, self.w, self.h, self.bgcolor) - local xPos = 1 - for n=1+itemOffset,#list do - if(list[n]~=nil)then - if(xPos + list[n].text:len() + space*2 <= self.w)then - if(list[n]==self:getValue())then - self.parent:writeText(obx + (xPos-1), oby, getTextHorizontalAlign((" "):rep(space)..list[n].text..(" "):rep(space), list[n].text:len()+space*2, align), itemSelectedBG or list[n].bgCol, itemSelectedFG or list[n].fgCol) - else - self.parent:writeText(obx + (xPos-1), oby, getTextHorizontalAlign((" "):rep(space)..list[n].text..(" "):rep(space), list[n].text:len()+space*2, align), list[n].bgCol, list[n].fgCol) - end - xPos = xPos+list[n].text:len()+space*2 + local xPos = 0 + for k,v in pairs(list)do + if(xPos + v.text:len() + space*2 <= self.w)then + if(v==self:getValue())then + self.parent:writeText(obx + (xPos-1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space)..v.text..(" "):rep(space), v.text:len()+space*2, align), itemSelectedBG or v.bgCol, itemSelectedFG or v.fgCol) else - break + self.parent:writeText(obx + (xPos-1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space)..v.text..(" "):rep(space), v.text:len()+space*2, align), v.bgCol, v.fgCol) + end + xPos = xPos+v.text:len()+space*2 + else + if(xPos