diff --git a/basalt-source.lua b/basalt-source.lua index 700d1cc..6907e65 100644 --- a/basalt-source.lua +++ b/basalt-source.lua @@ -1,7 +1,7 @@ local basalt = { debugger = true, version = 1 } local activeFrame -local frames = {} -local keyModifier = {} +local frames = {} +local keyActive = {} local parentTerminal = term.current() local sub = string.sub @@ -140,12 +140,11 @@ local function generateFontSize(size,yeld) return true end -generateFontSize(3,false) - local function makeText(nSize, sString, nFC, nBC, bBlit) if not type(sString) == "string" then error("Not a String",3) end --this should never happend with expects in place. local cFC = type(nFC) == "string" and nFC:sub(1, 1) or tHex[nFC] or error("Wrong Front Color",3) local cBC = type(nBC) == "string" and nBC:sub(1, 1) or tHex[nBC] or error("Wrong Back Color",3) + if(fonts[nSize]==nil)then generateFontSize(3,false) end local font = fonts[nSize] or error("Wrong font size selected",3) if sString == "" then return {{""}, {""}, {""}} end @@ -649,10 +648,6 @@ local function Object(name) return isVisible end; - getZIndex = function(self) - return zIndex; - end; - setFocus = function(self) if (self.parent ~= nil) then self.parent:setFocusedObject(self) @@ -669,6 +664,10 @@ local function Object(name) return self end; + getZIndex = function(self) + return zIndex; + end; + getType = function(self) return objectType end; @@ -714,6 +713,7 @@ local function Object(name) setVisualChanged = function(self, change) visualsChanged = change or true + if(change == nil)then visualsChanged = true end return self end; @@ -1122,6 +1122,7 @@ local function Button(name) end end end + self:setVisualChanged(false) end end; @@ -1178,6 +1179,7 @@ local function Checkbox(name) end end end + self:setVisualChanged(false) end end; @@ -1205,7 +1207,7 @@ local function Dropdown(name) local dropdownH = 6 local closedSymbol = "\16" local openedSymbol = "\31" - local state = 1 + local isOpened = false local object = { getType = function(self) @@ -1282,7 +1284,7 @@ local function Dropdown(name) end; mouseClickHandler = function(self, event, button, x, y) - if (state == 2) then + if (isOpened) then local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then @@ -1317,9 +1319,9 @@ local function Dropdown(name) self:setVisualChanged() end if (base.mouseClickHandler(self, event, button, x, y)) then - state = 2 + isOpened = true else - state = 1 + isOpened = false end end; @@ -1328,33 +1330,27 @@ local function Dropdown(name) local obx, oby = self:getAnchorPosition() if (self.parent ~= nil) then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - if (#list >= 1) then - if (self:getValue() ~= nil) then - if (self:getValue().text ~= nil) then - if (state == 1) then - self.parent:writeText(obx, oby, getTextHorizontalAlign(self:getValue().text, self.width, align):sub(1, self.width - 1) .. closedSymbol, self.bgColor, self.fgColor) - else - self.parent:writeText(obx, oby, getTextHorizontalAlign(self:getValue().text, self.width, align):sub(1, self.width - 1) .. openedSymbol, self.bgColor, self.fgColor) - end - end - end - if (state == 2) then - for n = 1, dropdownH do - if (list[n + yOffset] ~= nil) then - if (list[n + yOffset] == self:getValue()) then - if (selectionColorActive) then - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG) - else - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end + local val = self:getValue() + local text = getTextHorizontalAlign((val~=nil and val.text or ""), self.width, align):sub(1, self.width - 1) .. (isOpened and openedSymbol or closedSymbol) + self.parent:writeText(obx, oby, text, self.bgColor, self.fgColor) + + if (isOpened) then + for n = 1, dropdownH do + if (list[n + yOffset] ~= nil) then + if (list[n + yOffset] == val) then + if (selectionColorActive) then + self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG) else self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) end + else + self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) end end end end end + self:setVisualChanged(false) end end; } @@ -1547,6 +1543,7 @@ local function Image(name) end end end + self:setVisualChanged(false) end end; } @@ -1788,6 +1785,7 @@ local function Input(name) end end end + self:setVisualChanged(false) end end; } @@ -1884,6 +1882,7 @@ local function Label(name) end end end + self:setVisualChanged(false) end end; @@ -2043,6 +2042,7 @@ local function List(name) end end end + self:setVisualChanged(false) end end; } @@ -2066,15 +2066,19 @@ local function Menubar(name) local selectionColorActive = true local align = "left" local itemOffset = 0 - local space = 2 + local space = 1 local scrollable = false local function maxScroll() local mScroll = 0 - local xPos = 1 + local xPos = 0 for n = 1, #list do - if (xPos + list[n].text:len() + space * 2 > object.w) then - mScroll = mScroll + list[n].text:len() + space * 2 + if (xPos + list[n].text:len() + space * 2 > object.width) then + if(xPos < object.width)then + mScroll = mScroll + (list[n].text:len() + space * 2-(object.width - xPos)) + else + mScroll = mScroll + list[n].text:len() + space * 2 + end end xPos = xPos + list[n].text:len() + space * 2 @@ -2119,7 +2123,7 @@ local function Menubar(name) return self end; - setButtonOffset = function(self, offset) + setPositionOffset = function(self, offset) itemOffset = offset or 0 if (itemOffset < 0) then itemOffset = 0 @@ -2132,8 +2136,13 @@ local function Menubar(name) return self end; + getPositionOffset = function(self) + return itemOffset + end; + setScrollable = function(self, scroll) scrollable = scroll + if(scroll==nil)then scrollable = true end return self end; @@ -2169,41 +2178,41 @@ local function Menubar(name) end; mouseClickHandler = function(self, event, button, x, y) - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (self:isVisible()) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - if (event == "mouse_click") or (event == "monitor_touch") then - local xPos = 1 - for n = 1 + itemOffset, #list do - if (list[n] ~= nil) then - if (xPos + list[n].text:len() + space * 2 <= self.width) then - if (objX + (xPos - 1) <= x) and (objX + (xPos - 1) + list[n].text:len() + space * 2 > x) and (objY == y) then + if(base.mouseClickHandler(self, event, button, x, y))then + local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (self:isVisible()) then + if (self.parent ~= nil) then + self.parent:setFocusedObject(self) + end + if (event == "mouse_click") or (event == "monitor_touch") then + local xPos = 0 + for n = 1, #list do + if (list[n] ~= nil) then + --if (xPos-1 + list[n].text:len() + space * 2 <= self.width) then + if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then self:setValue(list[n]) - self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", 0, x, y, list[n]) + self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n]) end xPos = xPos + list[n].text:len() + space * 2 - else - break end end - end + end + if (event == "mouse_scroll") and (scrollable) then + itemOffset = itemOffset + button + if (itemOffset < 0) then + itemOffset = 0 + end + + local mScroll = maxScroll() + + if (itemOffset > mScroll) then + itemOffset = mScroll + end + end + self:setVisualChanged(true) + return true end - if (event == "mouse_scroll") and (scrollable) then - itemOffset = itemOffset + button - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - - if (itemOffset > mScroll) then - itemOffset = mScroll - end - end - return true end return false end; @@ -2213,27 +2222,26 @@ local function Menubar(name) if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - local xPos = 0 - for _, value in pairs(list) do - if (xPos + value.text:len() + space * 2 <= self.width) then - if (value == self:getValue()) then - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align), itemSelectedBG or value.bgCol, itemSelectedFG or value.fgCol) - else - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align), value.bgCol, value.fgCol) - end - xPos = xPos + value.text:len() + space * 2 + local text = "" + local textBGCol = "" + local textFGCol = "" + for _, v in pairs(list) do + local newItem = (" "):rep(space) .. v.text .. (" "):rep(space) + text = text .. newItem + if(v == self:getValue())then + textBGCol = textBGCol .. tHex[itemSelectedBG or v.bgCol or self.bgColor]:rep(newItem:len()) + textFGCol = textFGCol .. tHex[itemSelectedFG or v.FgCol or self.fgColor]:rep(newItem:len()) else - if (xPos < self.width + itemOffset) then - if (value == self:getValue()) then - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align):sub(1, self.width + itemOffset - xPos), itemSelectedBG or value.bgCol, itemSelectedFG or value.fgCol) - else - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align):sub(1, self.width + itemOffset - xPos), value.bgCol, value.fgCol) - end - xPos = xPos + value.text:len() + space * 2 - end + textBGCol = textBGCol .. tHex[v.bgCol or self.bgColor]:rep(newItem:len()) + textFGCol = textFGCol .. tHex[v.FgCol or self.fgColor]:rep(newItem:len()) end end + + self.parent:setText(obx, oby, text:sub(itemOffset+1, self.width+itemOffset)) + self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, self.width+itemOffset)) + self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, self.width+itemOffset)) end + self:setVisualChanged(false) end end; } @@ -2257,6 +2265,7 @@ local function Pane(name) self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.bgColor) end + self:setVisualChanged(false) end end; @@ -2899,6 +2908,7 @@ local function Program(name) self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) pWindow.basalt_update() end + self:setVisualChanged(false) end end; @@ -2998,6 +3008,7 @@ local function Progressbar(name) self.parent:drawTextBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbol) end end + self:setVisualChanged(false) end end; @@ -3123,6 +3134,7 @@ local function Radio(name) end end end + self:setVisualChanged(false) end end; } @@ -3252,6 +3264,7 @@ local function Scrollbar(name) end end end + self:setVisualChanged(false) end end; } @@ -3263,6 +3276,7 @@ local function Slider(name) local objectType = "Slider" base.width = 8 + base.height = 1 base.bgColor = colors.lightGray base.fgColor = colors.gray base:setValue(1) @@ -3273,6 +3287,7 @@ local function Slider(name) local bgSymbol = "\140" local maxValue = base.width local index = 1 + local symbolSize = 1 local object = { getType = function(self) @@ -3285,6 +3300,22 @@ local function Slider(name) return self end; + setSymbolSize = function(self, size) + symbolSize = tonumber(size) or 1 + if (barType == "vertical") then + self:setValue(index - 1 * (maxValue / (self.height - (symbolSize - 1))) - (maxValue / (self.height - (symbolSize - 1)))) + elseif (barType == "horizontal") then + self:setValue(index - 1 * (maxValue / (self.width - (symbolSize - 1))) - (maxValue / (self.width - (symbolSize - 1)))) + end + self:setVisualChanged() + return self + end; + + setMaxValue = function(self, val) + maxValue = val + return self + end; + setBackgroundSymbol = function(self, _bgSymbol) bgSymbol = string.sub(_bgSymbol, 1, 1) self:setVisualChanged() @@ -3305,84 +3336,33 @@ local function Slider(name) mouseClickHandler = function(self, event, button, x, y) if (base.mouseClickHandler(self, event, button, x, y)) then local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (barType == "horizontal") then - for _index = 0, self.width - 1 do - if (obx + _index == x) and (oby <= y) and (oby + self.height > y) then - index = _index + 1 - self:setValue(maxValue / self.width * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, self.height - 1 do - if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then - index = _index + 1 - self:setValue(maxValue / self.height * (index)) - self:setVisualChanged() - end - end - end - --[[if(event=="mouse_scroll")then - self:setValue(self:getValue() + (maxValue/(barType=="vertical" and self.height or self.width))*typ) - self:setVisualChanged() - end - if(self:getValue()>maxValue)then self:setValue(maxValue) end - if(self:getValue() y) then + index = math.min(_index + 1, self.width - (symbolSize - 1)) + self:setValue(maxValue / self.width * (index)) + self:setVisualChanged() + end + end end - if (barType == "vertical") then - for n = 0, self.height - 1 do - if (n + 1 == index) then - self.parent:writeText(obx, oby + n, symbol, symbolColor, symbolColor) - else - self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor) + for _index = 0, self.height do + if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then + index = math.min(_index + 1, self.height - (symbolSize - 1)) + self:setValue(maxValue / self.height * (index)) + self:setVisualChanged() end end end end - end - end; - - } - - return setmetatable(object, base) -end -local function Switch(name) - local base = Object(name) - local objectType = "Switch" - - base.width = 3 - base.height = 1 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(false) - base:setZIndex(5) - - local object = { - getType = function(self) - return objectType - end; - - - mouseClickHandler = function(self, event, button, x, y) - if (base.mouseClickHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then - - + if (event == "mouse_scroll") then + index = index + button + if (index < 1) then + index = 1 + end + index = math.min(index, (barType == "vertical" and self.height or self.width) - (symbolSize - 1)) + self:setValue(maxValue / (barType == "vertical" and self.height or self.width) * index) end return true end @@ -3392,8 +3372,96 @@ local function Switch(name) if (base.draw(self)) then if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() + if (barType == "horizontal") then + self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor) + self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor) + self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(self.width - (index + symbolSize - 1)), self.bgColor, self.fgColor) + end + if (barType == "vertical") then + for n = 0, self.height - 1 do + + if (index == n + 1) then + for curIndexOffset = 0, math.min(symbolSize - 1, self.height) do + self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor) + end + else + if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then + self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor) + end + end + end + end end + self:setVisualChanged(false) + end + end; + } + + return setmetatable(object, base) +end +local function Switch(name) + local base = Object(name) + local objectType = "Switch" + + base.width = 2 + base.height = 1 + base.bgColor = colors.lightGray + base.fgColor = colors.gray + base:setValue(false) + base:setZIndex(5) + + local bgSymbol = colors.black + local inactiveBG = colors.red + local activeBG = colors.green + + local object = { + getType = function(self) + return objectType + end; + + setSymbolColor = function(self, symbolColor) + bgSymbol = symbolColor + self:setVisualChanged() + return self + end; + + setActiveBackground = function(self, bgcol) + activeBG = bgcol + self:setVisualChanged() + return self + end; + + setInactiveBackground = function(self, bgcol) + inactiveBG = bgcol + self:setVisualChanged() + return self + end; + + mouseClickHandler = function(self, event, button, x, y) + if (base.mouseClickHandler(self, event, button, x, y)) then + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + if ((event == "mouse_click") and (button == 1))or(event=="monitor_touch") then + self:setValue(not self:getValue()) + end + return true + end + 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.width, self.height, self.bgColor) + if(self:getValue())then + self.parent:drawBackgroundBox(obx, oby, 1, self.height, activeBG) + self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, bgSymbol) + else + self.parent:drawBackgroundBox(obx, oby, 1, self.height, bgSymbol) + self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, inactiveBG) + end + end + self:setVisualChanged(false) end end; } @@ -3730,6 +3798,7 @@ local function Textfield(name) self.parent:setText(obx, oby + n - 1, text) end end + self:setVisualChanged(false) end end; } @@ -3813,6 +3882,7 @@ local function Timer(name) local repeats = 0 local timerObj local eventSystem = BasaltEvents() + local timerIsActive = false local object = { name = name, @@ -3835,15 +3905,24 @@ local function Timer(name) end; start = function(self) + if(timerIsActive)then + os.cancelTimer(timerObj) + end repeats = savedRepeats timerObj = os.startTimer(timer) + timerIsActive = true return self end; + isActive = function(self) + return timerIsActive + end; + cancel = function(self) if (timerObj ~= nil) then os.cancelTimer(timerObj) end + timerIsActive = false return self end; @@ -3853,7 +3932,7 @@ local function Timer(name) end; eventHandler = function(self, event, tObj) - if (event == "timer") and (tObj == timerObj) then + if event == "timer" and tObj == timerObj and timerIsActive then eventSystem:sendEvent("timed_event", self) if (repeats >= 1) then repeats = repeats - 1 @@ -3896,7 +3975,7 @@ local function Frame(name, parent) if (parent ~= nil) then base.parent = parent - base.width, base.height = parent.w, parent.h + base.width, base.height = parent:getSize() base.bgColor = theme.FrameBG base.fgColor = theme.FrameFG else @@ -4053,7 +4132,8 @@ local function Frame(name, parent) end; setFrameAsMonitor = function(self, isMon) - isMonitor = isMon or true + isMonitor = isMon + if(isMon==nil)then isMonitor = true end return self end; @@ -4289,6 +4369,9 @@ local function Frame(name, parent) end; draw = function(self) + for _,v in pairs(monitors)do + v.frame:draw() + end if (self:getVisualChanged()) then if (base.draw(self)) then local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) @@ -4302,7 +4385,7 @@ local function Frame(name, parent) drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") end - parentTerminal.setCursorBlink(false) + termObject.setCursorBlink(false) if (self.barActive) then if (self.parent ~= nil) then self.parent:writeText(anchx, anchy, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) @@ -4332,10 +4415,13 @@ local function Frame(name, parent) end self:setVisualChanged(false) end - for _,v in pairs(monitors)do - v.frame:draw() - end - drawHelper.update() + end + end; + + drawUpdate = function (self) + drawHelper.update() + for k,v in pairs(monitors)do + v.frame:drawUpdate() end end; @@ -4359,7 +4445,6 @@ local function Frame(name, parent) addLabel = function(self, name) local obj = Label(name) - obj.name = name obj.bgColor = self.bgColor obj.fgColor = self.fgColor return addObject(obj) @@ -4367,103 +4452,92 @@ local function Frame(name, parent) addCheckbox = function(self, name) local obj = Checkbox(name) - obj.name = name return addObject(obj) end; addInput = function(self, name) local obj = Input(name) - obj.name = name return addObject(obj) end; addProgram = function(self, name) local obj = Program(name) - obj.name = name return addObject(obj) end; addTextfield = function(self, name) local obj = Textfield(name) - obj.name = name return addObject(obj) end; addList = function(self, name) local obj = List(name) - obj.name = name + obj.name = nam return addObject(obj) end; addDropdown = function(self, name) local obj = Dropdown(name) - obj.name = name return addObject(obj) end; addRadio = function(self, name) local obj = Radio(name) - obj.name = name return addObject(obj) end; addTimer = function(self, name) local obj = Timer(name) - obj.name = name return addObject(obj) end; addAnimation = function(self, name) local obj = Animation(name) - obj.name = name return addObject(obj) end; addSlider = function(self, name) local obj = Slider(name) - obj.name = name return addObject(obj) end; addScrollbar = function(self, name) local obj = Scrollbar(name) - obj.name = name return addObject(obj) end; addMenubar = function(self, name) local obj = Menubar(name) - obj.name = name return addObject(obj) end; addThread = function(self, name) local obj = Thread(name) - obj.name = name return addObject(obj) end; addPane = function(self, name) local obj = Pane(name) - obj.name = name return addObject(obj) end; addImage = function(self, name) local obj = Image(name) - obj.name = name return addObject(obj) end; addProgressbar = function(self, name) local obj = Progressbar(name) - obj.name = name + return addObject(obj) + end; + + addSwitch = function(self, name) + local obj = Switch(name) return addObject(obj) end; addFrame = function(self, name) local obj = Frame(name, self) - obj.name = name return addObject(obj) end; } @@ -4489,12 +4563,21 @@ local function basaltUpdateEvent(event, p1, p2, p3, p4) activeFrame:keyHandler(event, p1) activeFrame:backgroundKeyHandler(event, p1) end - + + if(event == "key")then + keyActive[p1] = true + end + + if(event == "key_up")then + keyActive[p1] = false + end + for _, value in pairs(frames) do value:eventHandler(event, p1, p2, p3, p4) end if (updaterActive) then activeFrame:draw() + activeFrame:drawUpdate() end end @@ -4502,6 +4585,7 @@ function basalt.autoUpdate(isActive) parentTerminal.clear() updaterActive = isActive or true activeFrame:draw() + activeFrame:drawUpdate() while updaterActive do local event, p1, p2, p3, p4 = os.pullEventRaw() -- change to raw later basaltUpdateEvent(event, p1, p2, p3, p4) @@ -4509,10 +4593,11 @@ function basalt.autoUpdate(isActive) end function basalt.update(event, p1, p2, p3, p4) - if (event ~= "nil") then + if (event ~= nil) then basaltUpdateEvent(event, p1, p2, p3, p4) else activeFrame:draw() + activeFrame:drawUpdate() end end @@ -4520,6 +4605,11 @@ function basalt.stop() updaterActive = false end +function basalt.isKeyDown(key) + if(keyActive[key]==nil)then return false end + return keyActive[key]; +end + function basalt.getFrame(name) for _, value in pairs(frames) do if (value.name == name) then @@ -4579,6 +4669,9 @@ if (basalt.debugger) then basalt.debugList:removeItem(1) end basalt.debugList:setValue(basalt.debugList:getItem(basalt.debugList:getItemCount())) + if(basalt.debugList.getItemCount() > basalt.debugList:getHeight())then + basalt.debugList:setIndexOffset(basalt.debugList:getItemCount() - basalt.debugList:getHeight()) + end basalt.debugLabel:show() end end diff --git a/basalt.lua b/basalt.lua index da768be..4be3003 100644 --- a/basalt.lua +++ b/basalt.lua @@ -1 +1 @@ -local a={debugger=true,version=1}local b;local c={}local d={}local e=term.current()local f=string.sub;local g={[colors.white]="0",[colors.orange]="1",[colors.magenta]="2",[colors.lightBlue]="3",[colors.yellow]="4",[colors.lime]="5",[colors.pink]="6",[colors.gray]="7",[colors.lightGray]="8",[colors.cyan]="9",[colors.purple]="a",[colors.blue]="b",[colors.brown]="c",[colors.green]="d",[colors.red]="e",[colors.black]="f"}local h={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 i={{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147","\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132","\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131","\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132","\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32","\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129","\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32","\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32","\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148","\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32","\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32","\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148","\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149","\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32","\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32","\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32","\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132","\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32","\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149","\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32","\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148","\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32","\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32","\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129","\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32","\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32","\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32","\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148","\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32","\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32","\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32","\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132","\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149","\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32","\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32","\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32","\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144","\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149","\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129"},{[[000110000110110000110010101000000010000000100101]],[[000000110110000000000010101000000010000000100101]],[[000000000000000000000000000000000000000000000000]],[[100010110100000010000110110000010100000100000110]],[[000000110000000010110110000110000000000000110000]],[[000000000000000000000000000000000000000000000000]],[[000000110110000010000000100000100000000000000010]],[[000000000110110100010000000010000000000000000100]],[[000000000000000000000000000000000000000000000000]],[[010000000000100110000000000000000000000110010000]],[[000000000000000000000000000010000000010110000000]],[[000000000000000000000000000000000000000000000000]],[[011110110000000100100010110000000100000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110000110110000000000000000000010100100010000000]],[[000010000000000000110110000000000100010010000000]],[[000000000000000000000000000000000000000000000000]],[[010110010110100110110110010000000100000110110110]],[[000000000000000000000110000000000110000000000000]],[[000000000000000000000000000000000000000000000000]],[[010100010110110000000000000000110000000010000000]],[[110110000000000000110000110110100000000010000000]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[100100100100100100100100100100100100100100100100]],[[000000110100110110000010000011110000000000011000]],[[000000000100000000000010000011000110000000001000]],[[000000000000000000000000000000000000000000000000]],[[010000100100000000000000000100000000010010110000]],[[000000000000000000000000000000110110110110110000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110000000110110110110110110110110]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000110110000110010000000000000000010010]],[[000010000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110110110110000000000000]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110000000000000000010000]],[[000000000000000000000000100000000000000110000110]],[[000000000000000000000000000000000000000000000000]]}}local j={}local k={}do local l=0;local m=#i[1]local n=#i[1][1]for o=1,m,3 do for p=1,n,3 do local q=string.char(l)local r={}r[1]=i[1][o]:sub(p,p+2)r[2]=i[1][o+1]:sub(p,p+2)r[3]=i[1][o+2]:sub(p,p+2)local s={}s[1]=i[2][o]:sub(p,p+2)s[2]=i[2][o+1]:sub(p,p+2)s[3]=i[2][o+2]:sub(p,p+2)k[q]={r,s}l=l+1 end end;j[1]=k end;local function t(u,v)local w={["0"]="1",["1"]="0"}if u<=#j then return true end;for x=#j+1,u do local y={}local z=j[x-1]for l=0,255 do local q=string.char(l)local r={}local s={}local A=z[q][1]local B=z[q][2]for o=1,#A do local C,D,E,F,G,H={},{},{},{},{},{}for p=1,#A[1]do local I=k[A[o]:sub(p,p)][1]table.insert(C,I[1])table.insert(D,I[2])table.insert(E,I[3])local J=k[A[o]:sub(p,p)][2]if B[o]:sub(p,p)=="1"then table.insert(F,J[1]:gsub("[01]",w))table.insert(G,J[2]:gsub("[01]",w))table.insert(H,J[3]:gsub("[01]",w))else table.insert(F,J[1])table.insert(G,J[2])table.insert(H,J[3])end end;table.insert(r,table.concat(C))table.insert(r,table.concat(D))table.insert(r,table.concat(E))table.insert(s,table.concat(F))table.insert(s,table.concat(G))table.insert(s,table.concat(H))end;y[q]={r,s}if v then v="Font"..x.."Yeld"..l;os.queueEvent(v)os.pullEvent(v)end end;j[x]=y end;return true end;t(3,false)local function K(L,M,N,O,P)if not type(M)=="string"then error("Not a String",3)end;local Q=type(N)=="string"and N:sub(1,1)or g[N]or error("Wrong Front Color",3)local R=type(O)=="string"and O:sub(1,1)or g[O]or error("Wrong Back Color",3)local S=j[L]or error("Wrong font size selected",3)if M==""then return{{""},{""},{""}}end;local T={}for o in M:gmatch('.')do table.insert(T,o)end;local U={}local m=#S[T[1]][1]for V=1,m do local W={}for o=1,#T do W[o]=S[T[o]]and S[T[o]][1][V]or""end;U[V]=table.concat(W)end;local X={}local Y={}local Z={["0"]=Q,["1"]=R}local _={["0"]=R,["1"]=Q}for V=1,m do local a0={}local a1={}for o=1,#T do local a2=S[T[o]]and S[T[o]][2][V]or""a0[o]=a2:gsub("[01]",P and{["0"]=N:sub(o,o),["1"]=O:sub(o,o)}or Z)a1[o]=a2:gsub("[01]",P and{["0"]=O:sub(o,o),["1"]=N:sub(o,o)}or _)end;X[V]=table.concat(a0)Y[V]=table.concat(a1)end;return{U,X,Y}end;local function a3(a4)local a5=a4;local a6,m=a5.getSize()local a7={}local a8={}local a9={}local aa={}local ab={}local ac={}local ad;local ae={}local function af()ad=(" "):rep(a6)for ag=0,15 do local ah=2^ag;local ai=g[ah]ae[ah]=ai:rep(a6)end end;af()local function aj()local ak=ad;local al=ae[colors.white]local am=ae[colors.black]for an=1,m do a7[an]=f(a7[an]==nil and ak or a7[an]..ak:sub(1,a6-a7[an]:len()),1,a6)a9[an]=f(a9[an]==nil and al or a9[an]..al:sub(1,a6-a9[an]:len()),1,a6)a8[an]=f(a8[an]==nil and am or a8[an]..am:sub(1,a6-a8[an]:len()),1,a6)end end;aj()local function ao(ap,aq,ar)if aq>=1 and aq<=m then if ap+ar:len()>0 and ap<=a6 then local as=a7[aq]local at;local au=ap+#ar-1;if ap<1 then local av=1-ap+1;local aw=a6-ap+1;ar=f(ar,av,aw)elseif au>a6 then local aw=a6-ap+1;ar=f(ar,1,aw)end;if ap>1 then local aw=ap-1;at=f(as,1,aw)..ar else at=ar end;if au=1 and aq<=m then if ap+ay:len()>0 and ap<=a6 then local as=a8[aq]local at;local au=ap+#ay-1;if ap<1 then ay=f(ay,1-ap+1,a6-ap+1)elseif au>a6 then ay=f(ay,1,a6-ap+1)end;if ap>1 then at=f(as,1,ap-1)..ay else at=ay end;if au=1 and aq<=m then if ap+ay:len()>0 and ap<=a6 then local as=a9[aq]local at;local au=ap+#ay-1;if ap<1 then local av=1-ap+1;local aw=a6-ap+1;ay=f(ay,av,aw)elseif au>a6 then local aw=a6-ap+1;ay=f(ay,1,aw)end;if ap>1 then local aw=ap-1;at=f(as,1,aw)..ay else at=ay end;if au1 then while#bg>2 do table.sort(bg,function(bq,br)return bq[2]>br[2]end)local bs,bt=bf(bg),#bg;local bu,bv=bg[bt][1],bg[bs][1]for o=1,6 do if bk[o]==bu then bk[o]=bv;bg[bs][2]=bg[bs][2]+1 end end;bg[bt]=nil end;local bw=128;for o=1,#bk-1 do if bk[o]~=bk[6]then bw=bw+2^(o-1)end end;return string.char(bw),bc[bg[1][1]==bk[6]and bg[2][1]or bg[1][1]],bc[bk[6]]else return"\128",bc[bk[1]],bc[bk[1]]end end;local bx,a6,m,aB={{},{},{}},0,#b7+#b7%3,b8 or colors.black;for o=1,#b7 do if#b7[o]>a6 then a6=#b7[o]end end;for aq=0,m-1,3 do local by,bz,bA,bB={},{},{},1;for ap=0,a6-1,2 do local bk,bl={},{}for bC=1,3 do for bD=1,2 do bk[#bk+1]=b7[aq+bC]and b7[aq+bC][ap+bD]and(b7[aq+bC][ap+bD]==0 and aB or b7[aq+bC][ap+bD])or aB;bl[bk[#bk]]=bl[bk[#bk]]and bl[bk[#bk]]+1 or 1 end end;by[bB],bz[bB],bA[bB]=bj(bk,bl)bB=bB+1 end;bx[1][#bx[1]+1],bx[2][#bx[2]+1],bx[3][#bx[3]+1]=table.concat(by),table.concat(bz),table.concat(bA)end;bx.width,bx.height=#bx[1][1],#bx[1]return bx end;local function bE(bF)local bG="Object"local aP;local bH=1;local bI="left"local bJ="top"local bK=false;local bL=false;local bM=true;local bN=aI()local bO={x=1,y=1,width=1,height=1,bgColor=colors.black,fgColor=colors.white,name=bF or"Object",parent=nil,show=function(self)bL=true;bM=true;return self end,hide=function(self)bL=false;bM=true;return self end,isVisible=function(self)return bL end,getZIndex=function(self)return bH end,setFocus=function(self)if self.parent~=nil then self.parent:setFocusedObject(self)end;return self end,setZIndex=function(self,aK)bH=aK;if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end;return self end,getType=function(self)return bG end,getName=function(self)return self.name end,remove=function(self)if self.parent~=nil then self.parent:removeObject(self)end;return self end,setParent=function(self,bP)if bP.getType~=nil and bP:getType()=="Frame"then self:remove()bP:addObject(self)if self.draw then self:show()end end;return self end,setValue=function(self,bQ)if aP~=bQ then aP=bQ;bM=true;self:valueChangedHandler()end;return self end,getValue=function(self)return aP end,getVisualChanged=function(self)return bM end,setVisualChanged=function(self,bR)bM=bR or true;return self end,getEventSystem=function(self)return bN end,getParent=function(self)return self.parent end,setPosition=function(self,bS,bT,bU)if bU then self.x,self.y=math.floor(self.x+bS),math.floor(self.y+bT)else self.x,self.y=math.floor(bS),math.floor(bT)end;bM=true;return self end,getPosition=function(self)return self.x,self.y end,getVisibility=function(self)return bL end,setVisibility=function(self,bV)bL=bV or not bL;bM=true;return self end,setSize=function(self,a6,m)self.width,self.height=a6,m;bM=true;return self end,getHeight=function(self)return self.height end,getWidth=function(self)return self.width end,getSize=function(self)return self.width,self.height end,setBackground=function(self,bW)self.bgColor=bW;bM=true;return self end,getBackground=function(self)return self.bgColor end,setForeground=function(self,bW)self.fgColor=bW;bM=true;return self end,getForeground=function(self)return self.fgColor end,draw=function(self)if bL then return true end;return false end,getAbsolutePosition=function(self,ap,aq)if ap==nil then ap=self.x end;if aq==nil then aq=self.y end;if self.parent~=nil then local bX,bY=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())ap=bX+ap-1;aq=bY+aq-1 end;return ap,aq end,getAnchorPosition=function(self,ap,aq,bZ)if ap==nil then ap=self.x end;if aq==nil then aq=self.y end;if bI=="right"then ap=self.parent.width-ap-self.width+2 end;if bJ=="bottom"then aq=self.parent.height-aq-self.height+2 end;local b_,c0=self:getOffset()if bK or bZ then return ap,aq end;return ap+b_,aq+c0 end,getOffset=function(self)if self.parent~=nil and bK==false then return self.parent:getFrameOffset()end;return 0,0 end,ignoreOffset=function(self,c1)bK=c1 or true;return self end,setAnchor=function(self,...)for aO,aP in pairs(table.pack(...))do if aP=="right"or aP=="left"then bI=aP end;if aP=="top"or aP=="bottom"then bJ=aP end end;bM=true;return self end,getAnchor=function(self)return bI,bJ end,onChange=function(self,aN)self:registerEvent("value_changed",aN)return self end,onClick=function(self,aN)self:registerEvent("mouse_click",aN)self:registerEvent("monitor_touch",aN)return self end,onEvent=function(self,aN)self:registerEvent("custom_event_handler",aN)return self end,onClickUp=function(self,aN)self:registerEvent("mouse_up",aN)return self end,onKey=function(self,aN)self:registerEvent("key",aN)self:registerEvent("char",aN)return self end,onKeyUp=function(self,aN)self:registerEvent("key_up",aN)return self end,onBackgroundKey=function(self,aN)self:registerEvent("background_key",aN)self:registerEvent("background_char",aN)return self end,onBackgroundKeyUp=function(self,aN)self:registerEvent("background_key_up",aN)return self end,isFocused=function(self)if self.parent~=nil then return self.parent:getFocusedObject()==self end;return false end,onGetFocus=function(self,aN)self:registerEvent("get_focus",aN)return self end,onLoseFocus=function(self,aN)self:registerEvent("lose_focus",aN)return self end,registerEvent=function(self,aL,aN)return bN:registerEvent(aL,aN)end,removeEvent=function(self,aL,aK)return bN:removeEvent(aL,aK)end,sendEvent=function(self,aL,...)return bN:sendEvent(aL,self,...)end,mouseClickHandler=function(self,aL,c2,ap,aq)local c3,c4=self:getAbsolutePosition(self:getAnchorPosition())if c3<=ap and c3+self.width>ap and c4<=aq and c4+self.height>aq and bL then if self.parent~=nil then self.parent:setFocusedObject(self)end;bN:sendEvent(aL,self,aL,c2,ap,aq)return true end;return false end,keyHandler=function(self,aL,bp)if self:isFocused()then bN:sendEvent(aL,self,aL,bp)return true end;return false end,backgroundKeyHandler=function(self,aL,bp)bN:sendEvent("background_"..aL,self,aL,bp)end,valueChangedHandler=function(self)bN:sendEvent("value_changed",self)end,eventHandler=function(self,aL,c5,c6,c7,c8)bN:sendEvent("custom_event_handler",self,aL,c5,c6,c7,c8)end,getFocusHandler=function(self)bN:sendEvent("get_focus",self)end,loseFocusHandler=function(self)bN:sendEvent("lose_focus",self)end}bO.__index=bO;return bO end;local function c9(bF)local bO={}local bG="Animation"local ca;local cb={}local aK=1;local cc=0;local cd;local function ce()if cb[aK]~=nil then cb[aK].f(bO,aK)end;aK=aK+1;if cb[aK]~=nil then if cb[aK].t>0 then ca=os.startTimer(cb[aK].t)else ce()end end end;bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,aN,cf)cd=aN;table.insert(cb,{f=aN,t=cf or cc})return self end,wait=function(self,cf)cc=cf;return self end,rep=function(self,cg)for ap=1,cg do table.insert(cb,{f=cd,t=cc})end;return self end,clear=function(self)cb={}cd=nil;cc=0;aK=1;return self end,play=function(self)aK=1;if cb[aK]~=nil then if cb[aK].t>0 then ca=os.startTimer(cb[aK].t)else ce()end end;return self end,cancel=function(self)os.cancelTimer(ca)return self end,eventHandler=function(self,aL,ch)if aL=="timer"and ch==ca then if cb[aK]~=nil then ce()end end end}bO.__index=bO;return bO end;local function ci(bF)local cj=bE(bF)local bG="Button"cj:setValue("Button")cj:setZIndex(5)cj.width=8;cj.bgColor=h.ButtonBG;cj.fgColor=h.ButtonFG;local ck="center"local cl="center"local bO={getType=function(self)return bG end,setHorizontalAlign=function(self,cm)ck=cm end,setVerticalAlign=function(self,cm)cl=cm end,setText=function(self,ar)cj:setValue(ar)return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,cl)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height," ")for ag=1,self.height do if ag==cp then self.parent:setText(cn,co+ag-1,aZ(self:getValue(),self.width,ck))end end end end end}return setmetatable(bO,cj)end;local function cq(bF)local cj=bE(bF)local bG="Checkbox"cj:setZIndex(5)cj:setValue(false)cj.width=1;cj.height=1;cj.bgColor=h.CheckboxBG;cj.fgColor=h.CheckboxFG;local bO={symbol="\42",getType=function(self)return bG end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if aL=="mouse_click"and c2==1 or aL=="monitor_touch"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 cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,"center")self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if ag==cp then if self:getValue()==true then self.parent:writeText(cn,co+ag-1,aZ(self.symbol,self.width,"center"),self.bgColor,self.fgColor)else self.parent:writeText(cn,co+ag-1,aZ(" ",self.width,"center"),self.bgColor,self.fgColor)end end end end end end}return setmetatable(bO,cj)end;local function cr(bF)local cj=bE(bF)local bG="Dropdown"cj.width=12;cj.height=1;cj.bgColor=h.dropdownBG;cj.fgColor=h.dropdownFG;cj:setZIndex(6)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local cx=0;local cy=16;local cz=6;local cA="\16"local cB="\31"local cC=1;local bO={getType=function(self)return bG end,setIndexOffset=function(self,cD)cx=cD;return self end,getIndexOffset=function(self)return cx end,addItem=function(self,ar,aB,aC,...)table.insert(cs,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,getAll=function(self)return cs end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,setDropdownSize=function(self,a6,m)cy,cz=a6,m;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cC==2 then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then if#cs>0 then for ag=1,cz do if cs[ag+cx]~=nil then if cn<=ap and cn+cy>ap and co+ag==aq then self:setValue(cs[ag+cx])return true end end end end end;if aL=="mouse_scroll"then cx=cx+c2;if cx<0 then cx=0 end;if c2==1 then if#cs>cz then if cx>#cs-cz then cx=#cs-cz end else cx=cs-1 end end;return true end;self:setVisualChanged()end;if cj.mouseClickHandler(self,aL,c2,ap,aq)then cC=2 else cC=1 end end,draw=function(self)if cj.draw(self)then local cn,co=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)if#cs>=1 then if self:getValue()~=nil then if self:getValue().text~=nil then if cC==1 then self.parent:writeText(cn,co,aZ(self:getValue().text,self.width,cw):sub(1,self.width-1)..cA,self.bgColor,self.fgColor)else self.parent:writeText(cn,co,aZ(self:getValue().text,self.width,cw):sub(1,self.width-1)..cB,self.bgColor,self.fgColor)end end end;if cC==2 then for ag=1,cz do if cs[ag+cx]~=nil then if cs[ag+cx]==self:getValue()then if cv then self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),ct,cu)else self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end else self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end end end end end end end end}return setmetatable(bO,cj)end;local function cG(bF)local cj=bE(bF)local bG="Image"cj:setZIndex(2)local cH;local cI;local cJ=false;local function b6()local b9={[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 ba,bb,bc={},{},{}for o=0,15 do bb[2^o]=o end;do local bd="0123456789abcdef"for o=1,16 do ba[bd:sub(o,o)]=o-1;ba[o-1]=bd:sub(o,o)bc[bd:sub(o,o)]=2^(o-1)bc[2^(o-1)]=bd:sub(o,o)local be=b9[o-1]for o=1,#be do be[o]=2^be[o]end end end;local function bf(bg)local bh=b9[bb[bg[#bg][1]]]for p=1,#bh do local bi=bh[p]for o=1,#bg-1 do if bg[o][1]==bi then return o end end end;return 1 end;local function bj(bk,bl)if not bl then local bm={}bl={}for o=1,6 do local bn=bk[o]local bo=bl[bn]bl[bn],bm[o]=bo and bo+1 or 1,bn end;bk=bm end;local bg={}for bp,aP in pairs(bl)do bg[#bg+1]={bp,aP}end;if#bg>1 then while#bg>2 do table.sort(bg,function(bq,br)return bq[2]>br[2]end)local bs,bt=bf(bg),#bg;local bu,bv=bg[bt][1],bg[bs][1]for o=1,6 do if bk[o]==bu then bk[o]=bv;bg[bs][2]=bg[bs][2]+1 end end;bg[bt]=nil end;local bw=128;for o=1,#bk-1 do if bk[o]~=bk[6]then bw=bw+2^(o-1)end end;return string.char(bw),bc[bg[1][1]==bk[6]and bg[2][1]or bg[1][1]],bc[bk[6]]else return"\128",bc[bk[1]],bc[bk[1]]end end;local bx,a6,m,aB={{},{},{}},0,#cH+#cH%3,cj.bgColor or colors.black;for o=1,#cH do if#cH[o]>a6 then a6=#cH[o]end end;for aq=0,m-1,3 do local by,bz,bA,bB={},{},{},1;for ap=0,a6-1,2 do local bk,bl={},{}for bC=1,3 do for bD=1,2 do bk[#bk+1]=cH[aq+bC]and cH[aq+bC][ap+bD]and(cH[aq+bC][ap+bD]==0 and aB or cH[aq+bC][ap+bD])or aB;bl[bk[#bk]]=bl[bk[#bk]]and bl[bk[#bk]]+1 or 1 end end;by[bB],bz[bB],bA[bB]=bj(bk,bl)bB=bB+1 end;bx[1][#bx[1]+1],bx[2][#bx[2]+1],bx[3][#bx[3]+1]=table.concat(by),table.concat(bz),table.concat(bA)end;bx.width,bx.height=#bx[1][1],#bx[1]cI=bx end;local bO={getType=function(self)return bG end,loadImage=function(self,aT)cH=paintutils.loadImage(aT)cJ=false;return self end,loadBlittleImage=function(self,aT)cJ=true;return self end,shrink=function(self)b6()cJ=true;return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then if cH~=nil then local cn,co=self:getAnchorPosition()if cJ then local b5,cK,cL=cI[1],cI[2],cI[3]for o=1,cI.height do local cM=b5[o]if type(cM)=="string"then self.parent:setText(cn,co+o-1,cM)self.parent:setFG(cn,co+o-1,cK[o])self.parent:setBG(cn,co+o-1,cL[o])elseif type(cM)=="table"then self.parent:setText(cn,co+o-1,cM[2])self.parent:setFG(cn,co+o-1,cK[o])self.parent:setBG(cn,co+o-1,cL[o])end end else for bT=1,math.min(#cH,self.height)do local cN=cH[bT]for bS=1,math.min(#cN,self.width)do if cN[bS]>0 then self.parent:drawBackgroundBox(cn+bS-1,co+bT-1,1,1,cN[bS])end end end end end end end end}return setmetatable(bO,cj)end;local function cO(bF)local cj=bE(bF)local bG="Input"local cP="text"local cQ=0;cj:setZIndex(5)cj:setValue("")cj.width=10;cj.height=1;cj.bgColor=h.InputBG;cj.fgColor=h.InputFG;local cR=1;local cS=1;local cT=""local cU;local cV;local cW=cT;local cX=false;local bO={getType=function(self)return bG end,setInputType=function(self,cY)if cY=="password"or cY=="number"or cY=="text"then cP=cY end;return self end,setDefaultText=function(self,ar,cZ,c_)cT=ar;cU=c_ or cU;cV=cZ or cV;if self:isFocused()then cW=""else cW=cT end;return self end,getInputType=function(self)return cP end,setValue=function(self,d0)cj.setValue(self,tostring(d0))if not cX then cR=tostring(d0):len()+1 end;return self end,getValue=function(self)local d0=cj.getValue(self)return cP=="number"and tonumber(d0)or d0 end,setInputLimit=function(self,d1)cQ=tonumber(d1)or cQ;return self end,getInputLimit=function(self)return cQ end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then local cn,co=self:getAnchorPosition()cW=""if self.parent~=nil then self.parent:setCursor(true,cn+cR-cS,co,self.fgColor)end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)cW=cT end end,keyHandler=function(self,aL,bp)if cj.keyHandler(self,aL,bp)then cX=true;if aL=="key"then if bp==keys.backspace then local ar=tostring(cj.getValue())if cR>1 then self:setValue(ar:sub(1,cR-2)..ar:sub(cR,ar:len()))if cR>1 then cR=cR-1 end;if cS>1 then if cRd2 then cR=d2+1 end;if cR<1 then cR=1 end;if cR=self.width+cS then cS=cR-self.width+1 end;if cS<1 then cS=1 end end;if bp==keys.left then cR=cR-1;if cR>=1 then if cR=self.width+cS then cS=cR end end;if cR<1 then cR=1 end;if cS<1 then cS=1 end end end;if aL=="char"then local ar=cj.getValue()if ar:len()=self.width+cS then cS=cS+1 end end end;local cn,co=self:getAnchorPosition()local d0=tostring(cj.getValue())local d4=(cR<=d0:len()and cR-1 or d0:len())-(cS-1)if d4>self.x+self.width-1 then d4=self.x+self.width-1 end;if self.parent~=nil then self.parent:setCursor(true,cn+d4,co,self.fgColor)end;cX=false end end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if aL=="mouse_click"and c2==1 then end;return true end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,"center")self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if ag==cp then local d0=tostring(cj.getValue())local c_=self.bgColor;local cZ=self.fgColor;local ar;if d0:len()<=0 then ar=cW;c_=cU or c_;cZ=cV or cZ end;ar=cW;if d0~=""then ar=d0 end;ar=ar:sub(cS,self.width+cS-1)local d5=self.width-ar:len()if d5<0 then d5=0 end;if cP=="password"and d0~=""then ar=string.rep("*",ar:len())end;ar=ar..string.rep(" ",d5)self.parent:writeText(cn,co+ag-1,ar,c_,cZ)end end end end end}return setmetatable(bO,cj)end;local function d6(bF)local cj=bE(bF)local bG="Label"cj:setZIndex(3)cj.fgColor=colors.white;cj.bgcolor=colors.black;local d7=true;cj:setValue("")local ck="left"local cl="top"local d8=0;local bO={getType=function(self)return bG end,setText=function(self,ar)ar=tostring(ar)cj:setValue(ar)if d7 then self.width=ar:len()end;return self end,setTextAlign=function(self,d9,da)ck=d9 or ck;cl=da or cl;self:setVisualChanged()return self end,setFontSize=function(self,u)if u>0 and u<=4 then d8=u-1 or 0 end;return self end,getFontSize=function(self)return d8+1 end,setSize=function(self,a6,m)cj.setSize(self,a6,m)d7=false;self:setVisualChanged()return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,cl)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height," ")if d8==0 then for ag=1,self.height do if ag==cp then self.parent:writeText(cn,co+ag-1,aZ(self:getValue(),self.width,ck),self.bgColor,self.fgColor)end end else local db=K(d8,self:getValue(),self.fgColor,self.bgColor)if d7 then self.height=#db[1]-1;self.width=#db[1][1]end;for ag=1,self.height do if ag==cp then local dc,dd=self.parent:getSize()local de,df=#db[1][1],#db[1]cn=cn or math.floor((dc-de)/2)+1;co=co or math.floor((dd-df)/2)+1;for o=1,df do self.parent:setFG(cn,co+o+ag-2,aZ(db[2][o],self.width,ck))self.parent:setBG(cn,co+o+ag-2,aZ(db[3][o],self.width,ck,g[self.bgColor]))self.parent:setText(cn,co+o+ag-2,aZ(db[1][o],self.width,ck))end end end end end end end}return setmetatable(bO,cj)end;local function dg(bF)local cj=bE(bF)local bG="List"cj.width=16;cj.height=6;cj.bgColor=h.listBG;cj.fgColor=h.listFG;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local cx=0;local dh=true;local bO={getType=function(self)return bG end,addItem=function(self,ar,aB,aC,...)table.insert(cs,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})if#cs==1 then self:setValue(cs[1])end;return self end,setIndexOffset=function(self,cD)cx=cD;return self end,getIndexOffset=function(self)return cx end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getAll=function(self)return cs end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,setScrollable=function(self,di)dh=di;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if cn<=ap and cn+self.width>ap and co<=aq and co+self.height>aq and self:isVisible()then if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if#cs>0 then for ag=1,self.height do if cs[ag+cx]~=nil then if cn<=ap and cn+self.width>ap and co+ag-1==aq then self:setValue(cs[ag+cx])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,ap,aq,cs[ag+cx])end end end end end;if aL=="mouse_scroll"and dh then cx=cx+c2;if cx<0 then cx=0 end;if c2>=1 then if#cs>self.height then if cx>#cs-self.height then cx=#cs-self.height end;if cx>=#cs then cx=#cs-1 end else cx=cx-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if cs[ag+cx]~=nil then if cs[ag+cx]==self:getValue()then if cv then self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),ct,cu)else self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end else self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end end end end end end}return setmetatable(bO,cj)end;local function dj(bF)local cj=bE(bF)local bG="Menubar"local bO={}cj.width=30;cj.height=1;cj.bgColor=colors.gray;cj.fgColor=colors.lightGray;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local dk=0;local d5=2;local dh=false;local function dl()local dm=0;local bS=1;for ag=1,#cs do if bS+cs[ag].text:len()+d5*2>bO.w then dm=dm+cs[ag].text:len()+d5*2 end;bS=bS+cs[ag].text:len()+d5*2 end;return dm end;bO={getType=function(self)return bG end,addItem=function(self,ar,aB,aC,...)table.insert(cs,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})if#cs==1 then self:setValue(cs[1])end;return self end,getAll=function(self)return cs end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,setSpace=function(self,dn)d5=dn or d5;return self end,setButtonOffset=function(self,b1)dk=b1 or 0;if dk<0 then dk=0 end;local dm=dl()if dk>dm then dk=dm end;return self end,setScrollable=function(self,di)dh=di;return self end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)local c3,c4=self:getAbsolutePosition(self:getAnchorPosition())if c3<=ap and c3+self.width>ap and c4<=aq and c4+self.height>aq and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if aL=="mouse_click"or aL=="monitor_touch"then local bS=1;for ag=1+dk,#cs do if cs[ag]~=nil then if bS+cs[ag].text:len()+d5*2<=self.width then if c3+bS-1<=ap and c3+bS-1+cs[ag].text:len()+d5*2>ap and c4==aq then self:setValue(cs[ag])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,ap,aq,cs[ag])end;bS=bS+cs[ag].text:len()+d5*2 else break end end end end;if aL=="mouse_scroll"and dh then dk=dk+c2;if dk<0 then dk=0 end;local dm=dl()if dk>dm then dk=dm end end;return true end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)local bS=0;for aO,aP in pairs(cs)do if bS+aP.text:len()+d5*2<=self.width then if aP==self:getValue()then self.parent:writeText(cn+bS-1+-dk,co,aZ((" "):rep(d5)..aP.text..(" "):rep(d5),aP.text:len()+d5*2,cw),ct or aP.bgCol,cu or aP.fgCol)else self.parent:writeText(cn+bS-1+-dk,co,aZ((" "):rep(d5)..aP.text..(" "):rep(d5),aP.text:len()+d5*2,cw),aP.bgCol,aP.fgCol)end;bS=bS+aP.text:len()+d5*2 else if bS=1 and dt>=1 and ds<=a6 and dt<=m then else end end;local function dA(dB,dC,dD)local dE=ds;local au=dE+#dB-1;if dt>=1 and dt<=m then if dE<=a6 and au>=1 then if dE==1 and au==a6 then a7[dt]=dB;a9[dt]=dC;a8[dt]=dD else local dF,dG,dH;if dE<1 then local dI=1-dE+1;local dJ=a6-dE+1;dF=f(dB,dI,dJ)dG=f(dC,dI,dJ)dH=f(dD,dI,dJ)elseif au>a6 then local dJ=a6-dE+1;dF=f(dB,1,dJ)dG=f(dC,1,dJ)dH=f(dD,1,dJ)else dF=dB;dG=dC;dH=dD end;local dK=a7[dt]local dL=a9[dt]local dM=a8[dt]local dN,dO,dP;if dE>1 then local dQ=dE-1;dN=f(dK,1,dQ)..dF;dO=f(dL,1,dQ)..dG;dP=f(dM,1,dQ)..dH else dN=dF;dO=dG;dP=dH end;if au=1 and aq<=m then a7[ec]=a7[aq]a8[ec]=a8[aq]a9[ec]=a9[aq]else a7[ec]=e9;a9[ec]=ea;a8[ec]=eb end end end;if dw then dz()end end,isColor=function()return e.isColor()end,isColour=function()return e.isColor()end,write=function(ar)ar=tostring(ar)if dw then dA(ar,g[du]:rep(ar:len()),g[b8]:rep(ar:len()))end end,clearLine=function()if dw then ao(1,dt,(" "):rep(a6))ax(1,dt,g[b8]:rep(a6))az(1,dt,g[du]:rep(a6))end;if dw then dz()end end,clear=function()for ag=1,m do ao(1,ag,(" "):rep(a6))ax(1,ag,g[b8]:rep(a6))az(1,ag,g[du]:rep(a6))end;if dw then dz()end end,blit=function(ar,ed,ee)if type(ar)~="string"then error("bad argument #1 (expected string, got "..type(ar)..")",2)end;if type(ed)~="string"then error("bad argument #2 (expected string, got "..type(ed)..")",2)end;if type(ee)~="string"then error("bad argument #3 (expected string, got "..type(ee)..")",2)end;if#ed~=#ar or#ee~=#ar then error("Arguments must be the same length",2)end;if dw then dA(ar,ed,ee)end end}return e4 end;cj.width=30;cj.height=12;local ef=dr(1,1,cj.width,cj.height)local eg;local eh=false;local ei={}bO={getType=function(self)return bG end,show=function(self)cj.show(self)ef.setBackgroundColor(self.bgColor)ef.setTextColor(self.fgColor)ef.basalt_setVisible(true)return self end,hide=function(self)cj.hide(self)ef.basalt_setVisible(false)return self end,setPosition=function(self,ap,aq,bU)cj.setPosition(self,ap,aq,bU)ef.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return ef end,getBasaltProcess=function()return eg end,setSize=function(self,a6,m)cj.setSize(self,a6,m)ef.basalt_resize(self.width,self.height)return self end,getStatus=function(self)if eg~=nil then return eg:getStatus()end;return"inactive"end,execute=function(self,aT,...)eg=aR:new(aT,ef,...)ef.setBackgroundColor(colors.black)ef.setTextColor(colors.white)ef.clear()ef.setCursorPos(1,1)eg:resume()eh=false;return self end,stop=function(self)if eg~=nil then if not eg:isDead()then eg:resume("terminate")if eg:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,ej)eh=ej or not eh;if eg~=nil then if not eg:isDead()then if not eh then self:injectEvents(ei)ei={}end end end;return self end,isPaused=function(self)return eh end,injectEvent=function(self,aL,c5,c6,c7,c8,ek)if eg~=nil then if not eg:isDead()then if eh==false or ek then eg:resume(aL,c5,c6,c7,c8)else table.insert(ei,{event=aL,args={c5,c6,c7,c8}})end end end;return self end,getQueuedEvents=function(self)return ei end,updateQueuedEvents=function(self,aJ)ei=aJ or ei;return self end,injectEvents=function(self,aJ)if eg~=nil then if not eg:isDead()then for aO,aP in pairs(aJ)do eg:resume(aP.event,table.unpack(aP.args))end end end;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if eg==nil then return false end;if not eg:isDead()then if not eh then local el,em=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))eg:resume(aL,c2,ap-el+1,aq-em+1)end end;return true end end,keyHandler=function(self,aL,bp)cj.keyHandler(self,aL,bp)if self:isFocused()then if eg==nil then return false end;if not eg:isDead()then if not eh then if self.draw then eg:resume(aL,bp)end end end end end,getFocusHandler=function(self)cj.getFocusHandler(self)if eg~=nil then if not eg:isDead()then if not eh then if self.parent~=nil then local en,eo=ef.getCursorPos()local cn,co=self:getAnchorPosition()if self.parent~=nil then if cn+en-1>=1 and cn+en-1<=cn+self.width-1 and eo+co-1>=1 and eo+co-1<=co+self.height-1 then self.parent:setCursor(ef.getCursorBlink(),cn+en-1,eo+co-1,ef.getTextColor())end end end end end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if eg~=nil then if not eg:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,aL,c5,c6,c7,c8)if eg==nil then return end;if not eg:isDead()then if not eh then if aL~="mouse_click"and aL~="monitor_touch"and aL~="mouse_up"and aL~="mouse_scroll"and aL~="mouse_drag"and aL~="key_up"and aL~="key"and aL~="char"and aL~="terminate"then eg:resume(aL,c5,c6,c7,c8)end;if self:isFocused()then local cn,co=self:getAnchorPosition()local en,eo=ef.getCursorPos()if self.parent~=nil then if cn+en-1>=1 and cn+en-1<=cn+self.width-1 and eo+co-1>=1 and eo+co-1<=co+self.height-1 then self.parent:setCursor(ef.getCursorBlink(),cn+en-1,eo+co-1,ef.getTextColor())end end;if aL=="terminate"and self:isFocused()then self:stop()end end else if aL~="mouse_click"and aL~="monitor_touch"and aL~="mouse_up"and aL~="mouse_scroll"and aL~="mouse_drag"and aL~="key_up"and aL~="key"and aL~="char"and aL~="terminate"then table.insert(ei,{event=aL,args={c5,c6,c7,c8}})end end end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()ef.basalt_reposition(cn,co)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)ef.basalt_update()end end end}return setmetatable(bO,cj)end;local function ep(bF)local cj=bE(bF)local bG="Progressbar"local eq=0;cj:setZIndex(5)cj:setValue(false)cj.width=25;cj.height=1;cj.bgColor=h.CheckboxBG;cj.fgColor=h.CheckboxFG;local er=colors.black;local es=""local et=colors.white;local eu=""local ev=0;local bO={getType=function(self)return bG end,setDirection=function(self,ew)ev=ew;return self end,setProgressBar=function(self,bW,aD,ex)er=bW or er;es=aD or es;et=ex or et;return self end,setBackgroundSymbol=function(self,aD)eu=aD:sub(1,1)return self end,setProgress=function(self,aP)if aP>=0 and aP<=100 and eq~=aP then eq=aP;self:setValue(eq)if eq==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return eq end,onProgressDone=function(self,x)self:registerEvent("progress_done",x)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done")end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height,eu)if ev==1 then self.parent:drawBackgroundBox(cn,co,self.width,self.height/100*eq,er)self.parent:drawForegroundBox(cn,co,self.width,self.height/100*eq,et)self.parent:drawTextBox(cn,co,self.width,self.height/100*eq,es)elseif ev==2 then self.parent:drawBackgroundBox(cn,co+math.ceil(self.height-self.height/100*eq),self.width,self.height/100*eq,er)self.parent:drawForegroundBox(cn,co+math.ceil(self.height-self.height/100*eq),self.width,self.height/100*eq,et)self.parent:drawTextBox(cn,co+math.ceil(self.height-self.height/100*eq),self.width,self.height/100*eq,es)elseif ev==3 then self.parent:drawBackgroundBox(cn+math.ceil(self.width-self.width/100*eq),co,self.width/100*eq,self.height,er)self.parent:drawForegroundBox(cn+math.ceil(self.width-self.width/100*eq),co,self.width/100*eq,self.height,et)self.parent:drawTextBox(cn+math.ceil(self.width-self.width/100*eq),co,self.width/100*eq,self.height,es)else self.parent:drawBackgroundBox(cn,co,self.width/100*eq,self.height,er)self.parent:drawForegroundBox(cn,co,self.width/100*eq,self.height,et)self.parent:drawTextBox(cn,co,self.width/100*eq,self.height,es)end end end end}return setmetatable(bO,cj)end;local function ey(bF)local cj=bE(bF)local bG="Radio"cj.width=8;cj.bgColor=h.listBG;cj.fgColor=h.listFG;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local ez=cj.bgColor;local eA=cj.fgColor;local cv=true;local aD="\7"local cw="left"local bO={getType=function(self)return bG end,addItem=function(self,ar,ap,aq,aB,aC,...)table.insert(cs,{x=ap or 1,y=aq or 1,text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})if#cs==1 then self:setValue(cs[1])end;return self end,getAll=function(self)return cs end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,ap,aq,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{x=ap or 1,y=aq or 1,text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,eB,eC,cF)ct=aB or ct;cu=aC or cu;ez=eB or ez;eA=eC or eA;cv=cF;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then if#cs>0 then for aO,aP in pairs(cs)do if cn+aP.x-1<=ap and cn+aP.x-1+aP.text:len()+2>=ap and co+aP.y-1==aq then self:setValue(aP)if self.parent~=nil then self.parent:setFocusedObject(self)end;self:setVisualChanged()return true end end end end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()for aO,aP in pairs(cs)do if aP==self:getValue()then if cw=="left"then self.parent:writeText(aP.x+cn-1,aP.y+co-1,aD,ez,eA)self.parent:writeText(aP.x+2+cn-1,aP.y+co-1,aP.text,ct,cu)end else self.parent:drawBackgroundBox(aP.x+cn-1,aP.y+co-1,1,1,self.bgColor)self.parent:writeText(aP.x+2+cn-1,aP.y+co-1,aP.text,aP.bgCol,aP.fgCol)end end end end end}return setmetatable(bO,cj)end;local function eD(bF)local cj=bE(bF)local bG="Scrollbar"cj.width=1;cj.height=8;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(1)cj:setZIndex(2)local eE="vertical"local aD=" "local eF=colors.black;local eG="\127"local eH=cj.height;local aK=1;local eI=1;local bO={getType=function(self)return bG end,setSymbol=function(self,eJ)aD=eJ:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,u)eI=tonumber(u)or 1;if eE=="vertical"then self:setValue(aK-1*eH/(self.height-(eI-1))-eH/(self.height-(eI-1)))elseif eE=="horizontal"then self:setValue(aK-1*eH/(self.width-(eI-1))-eH/(self.width-(eI-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,d0)eH=d0;return self end,setBackgroundSymbol=function(self,eK)eG=string.sub(eK,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eL)eF=eL;self:setVisualChanged()return self end,setBarType=function(self,eM)eE=eM:lower()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if eE=="horizontal"then for eN=0,self.width do if cn+eN==ap and co<=aq and co+self.height>aq then aK=math.min(eN+1,self.width-(eI-1))self:setValue(eH/self.width*aK)self:setVisualChanged()end end end;if eE=="vertical"then for eN=0,self.height do if co+eN==aq and cn<=ap and cn+self.width>ap then aK=math.min(eN+1,self.height-(eI-1))self:setValue(eH/self.height*aK)self:setVisualChanged()end end end end;if aL=="mouse_scroll"then aK=aK+c2;if aK<1 then aK=1 end;aK=math.min(aK,(eE=="vertical"and self.height or self.width)-(eI-1))self:setValue(eH/(eE=="vertical"and self.height or self.width)*aK)end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()if eE=="horizontal"then self.parent:writeText(cn,co,eG:rep(aK-1),self.bgColor,self.fgColor)self.parent:writeText(cn+aK-1,co,aD:rep(eI),eF,eF)self.parent:writeText(cn+aK+eI-1,co,eG:rep(self.width-(aK+eI-1)),self.bgColor,self.fgColor)end;if eE=="vertical"then for ag=0,self.height-1 do if aK==ag+1 then for eO=0,math.min(eI-1,self.height)do self.parent:writeText(cn,co+ag+eO,aD,eF,eF)end else if ag+1aK-1+eI then self.parent:writeText(cn,co+ag,eG,self.bgColor,self.fgColor)end end end end end end end}return setmetatable(bO,cj)end;local function eP(bF)local cj=bE(bF)local bG="Slider"cj.width=8;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(1)local eE="horizontal"local aD=" "local eF=colors.black;local eG="\140"local eH=cj.width;local aK=1;local bO={getType=function(self)return bG end,setSymbol=function(self,eJ)aD=eJ:sub(1,1)self:setVisualChanged()return self end,setBackgroundSymbol=function(self,eK)eG=string.sub(eK,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eL)eF=eL;self:setVisualChanged()return self end,setBarType=function(self,eM)eE=eM:lower()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if eE=="horizontal"then for eN=0,self.width-1 do if cn+eN==ap and co<=aq and co+self.height>aq then aK=eN+1;self:setValue(eH/self.width*aK)self:setVisualChanged()end end end;if eE=="vertical"then for eN=0,self.height-1 do if co+eN==aq and cn<=ap and cn+self.width>ap then aK=eN+1;self:setValue(eH/self.height*aK)self:setVisualChanged()end end end end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()if eE=="horizontal"then self.parent:writeText(cn,co,eG:rep(aK-1),self.bgColor,self.fgColor)self.parent:writeText(cn+aK-1,co,aD,eF,eF)self.parent:writeText(cn+aK,co,eG:rep(self.width-aK),self.bgColor,self.fgColor)end;if eE=="vertical"then for ag=0,self.height-1 do if ag+1==aK then self.parent:writeText(cn,co+ag,aD,eF,eF)else self.parent:writeText(cn,co+ag,eG,self.bgColor,self.fgColor)end end end end end end}return setmetatable(bO,cj)end;local function eQ(bF)local cj=bE(bF)local bG="Switch"cj.width=3;cj.height=1;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(false)cj:setZIndex(5)local bO={getType=function(self)return bG end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()end end end}return setmetatable(bO,cj)end;local function eR(bF)local cj=bE(bF)local bG="Textfield"local eS,cS,cR,eT=1,1,1,1;local eU={""}local eV={[colors.purple]={"break"}}cj.width=20;cj.height=8;cj.bgColor=h.textfieldBG;cj.fgColor=h.textfieldFG;cj:setZIndex(5)local bO={getType=function(self)return bG end,getLines=function(self)return eU end,getLine=function(self,aK)return eU[aK]or""end,editLine=function(self,aK,ar)eU[aK]=ar or eU[aK]return self end,addLine=function(self,ar,aK)if aK~=nil then table.insert(eU,aK,ar)else table.insert(eU,ar)end;return self end,addKeyword=function(self,eW,bW)end,removeLine=function(self,aK)table.remove(eU,aK or#eU)if#eU<=0 then table.insert(eU,"")end;return self end,getTextCursor=function(self)return cR,eT end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then local cn,co=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,cn+cR-cS,co+eT-eS,self.fgColor)end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,aL,bp)if cj.keyHandler(self,aL,bp)then local cn,co=self:getAnchorPosition()if aL=="key"then if bp==keys.backspace then if eU[eT]==""then if eT>1 then table.remove(eU,eT)cR=eU[eT-1]:len()+1;cS=cR-self.width+1;if cS<1 then cS=1 end;eT=eT-1 end elseif cR<=1 then if eT>1 then cR=eU[eT-1]:len()+1;cS=cR-self.width+1;if cS<1 then cS=1 end;eU[eT-1]=eU[eT-1]..eU[eT]table.remove(eU,eT)eT=eT-1 end else eU[eT]=eU[eT]:sub(1,cR-2)..eU[eT]:sub(cR,eU[eT]:len())if cR>1 then cR=cR-1 end;if cS>1 then if cReU[eT]:len()then if eU[eT+1]~=nil then eU[eT]=eU[eT]..eU[eT+1]table.remove(eU,eT+1)end else eU[eT]=eU[eT]:sub(1,cR-1)..eU[eT]:sub(cR+1,eU[eT]:len())end end;if bp==keys.enter then table.insert(eU,eT+1,eU[eT]:sub(cR,eU[eT]:len()))eU[eT]=eU[eT]:sub(1,cR-1)eT=eT+1;cR=1;cS=1;if eT-eS>=self.height then eS=eS+1 end;self:setValue("")end;if bp==keys.up then if eT>1 then eT=eT-1;if cR>eU[eT]:len()+1 then cR=eU[eT]:len()+1 end;if cS>1 then if cR1 then if eTeU[eT]:len()+1 then cR=eU[eT]:len()+1 end;if eT>=eS+self.height then eS=eS+1 end end end;if bp==keys.right then cR=cR+1;if eT<#eU then if cR>eU[eT]:len()+1 then cR=1;eT=eT+1 end elseif cR>eU[eT]:len()then cR=eU[eT]:len()+1 end;if cR<1 then cR=1 end;if cR=self.width+cS then cS=cR-self.width+1 end;if cS<1 then cS=1 end end;if bp==keys.left then cR=cR-1;if cR>=1 then if cR=self.width+cS then cS=cR end end;if eT>1 then if cR<1 then eT=eT-1;cR=eU[eT]:len()+1;cS=cR-self.width+1 end end;if cR<1 then cR=1 end;if cS<1 then cS=1 end end end;if aL=="char"then eU[eT]=eU[eT]:sub(1,cR-1)..bp..eU[eT]:sub(cR,eU[eT]:len())cR=cR+1;if cR>=self.width+cS then cS=cS+1 end;self:setValue("")end;local d4=(cR<=eU[eT]:len()and cR-1 or eU[eT]:len())-(cS-1)if d4>self.x+self.width-1 then d4=self.x+self.width-1 end;local eX=eT-eSeU[eT]:len()then cR=eU[eT]:len()+1 end;if cReU[eT]:len()then cR=eU[eT]:len()+1 end;if cR#eU-(self.height-1)then eS=#eU-(self.height-1)end;if eS<1 then eS=1 end;if self.parent~=nil then if cn+cR-cS>=cn and cn+cR-cS<=cn+self.width and(co+eT-eS>=co and co+eT-eS<=co+self.height)then self.parent:setCursor(true,eY+cR-cS,eZ+eT-eS)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)for ag=1,self.height do local ar=""if eU[ag+eS-1]~=nil then ar=eU[ag+eS-1]end;ar=ar:sub(cS,self.width+cS-1)local d5=self.width-ar:len()if d5<0 then d5=0 end;ar=ar..string.rep(" ",d5)self.parent:setText(cn,co+ag-1,ar)end end end end}return setmetatable(bO,cj)end;local function e_(bF)local bO;local bG="Thread"local aN;local f0;local f1=false;bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,x)if x==nil then error("Function provided to thread is nil")end;aN=x;f0=coroutine.create(aN)f1=true;local aX,aY=coroutine.resume(f0)if not aX then if aY~="Terminated"then error("Thread Error Occurred - "..aY)end end;return self end,getStatus=function(self,x)if f0~=nil then return coroutine.status(f0)end;return nil end,stop=function(self,x)f1=false;return self end,eventHandler=function(self,aL,c5,c6,c7)if f1 then if coroutine.status(f0)~="dead"then local aX,aY=coroutine.resume(f0,aL,c5,c6,c7)if not aX then if aY~="Terminated"then error("Thread Error Occurred - "..aY)end end else f1=false end end end}bO.__index=bO;return bO end;local function f2(bF)local bG="Timer"local f3=0;local f4=0;local f5=0;local ca;local bN=aI()local bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,f6,f7)f3=f6 or 0;f4=f7 or 1;return self end,start=function(self)f5=f4;ca=os.startTimer(f3)return self end,cancel=function(self)if ca~=nil then os.cancelTimer(ca)end;return self end,onCall=function(self,aN)bN:registerEvent("timed_event",aN)return self end,eventHandler=function(self,aL,ch)if aL=="timer"and ch==ca then bN:sendEvent("timed_event",self)if f5>=1 then f5=f5-1;if f5>=1 then ca=os.startTimer(f3)end elseif f5==-1 then ca=os.startTimer(f3)end end end}bO.__index=bO;return bO end;local function f8(bF,f9)local cj=bE(bF)local bG="Frame"local fa={}local fb={}local bO={}local fc;local fd=e;local fe={}local ff=false;cj:setZIndex(10)local aA=a3(fd)local dv=false;local ds=1;local dt=1;local fg=colors.white;local fh,cx=0,0;if f9~=nil then cj.parent=f9;cj.width,cj.height=f9.w,f9.h;cj.bgColor=h.FrameBG;cj.fgColor=h.FrameFG else cj.width,cj.height=fd.getSize()cj.bgColor=h.basaltBG;cj.fgColor=h.basaltFG end;local function fi(bF)for aO,aP in pairs(fa)do for aO,br in pairs(aP)do if br.name==bF then return aP end end end end;local function fj(fk)local bH=fk:getZIndex()if fi(fk.name)~=nil then return nil end;if fa[bH]==nil then for ap=1,#fb+1 do if fb[ap]~=nil then if bH==fb[ap]then break end;if bH>fb[ap]then table.insert(fb,ap,bH)break end else table.insert(fb,bH)end end;if#fb<=0 then table.insert(fb,bH)end;fa[bH]={}end;fk.parent=bO;table.insert(fa[bH],fk)return fk end;local function fl(fk)for bq,br in pairs(fa)do for bp,aP in pairs(br)do if aP==fk then table.remove(fa[bq],bp)return true end end end;return false end;bO={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return bG end,setFocusedObject=function(self,fk)for aO,aK in pairs(fb)do for aO,aP in pairs(fa[aK])do if aP==fk then if fc~=nil then fc:loseFocusHandler()end;fc=fk;fc:getFocusHandler()end end end;return self end,setOffset=function(self,b_,c0)fh=b_~=nil and math.floor(b_<0 and math.abs(b_)or-b_)or fh;cx=c0~=nil and math.floor(c0<0 and math.abs(c0)or-c0)or cx;return self end,getFrameOffset=function(self)return fh,cx end,removeFocusedObject=function(self)if fc~=nil then fc:loseFocusHandler()end;fc=nil;return self end,getFocusedObject=function(self)return fc end,show=function(self)cj:show()if self.parent==nil and not ff then b=self end;return self end,setCursor=function(self,fm,fn,fo,bW)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())dv=fm or false;if fn~=nil then ds=cn+fn-1 end;if fo~=nil then dt=co+fo-1 end;fg=bW or fg;self:setVisualChanged()return self end,setMoveable=function(self,fp)self.isMoveable=fp or not self.isMoveable;self:setVisualChanged()return self end,addMonitor=function(self,fq)local fr=peripheral.wrap(fq)fe[fq]={monitor=fq,frame=a.createFrame(self:getName().."_monitor_"..fq)}fe[fq].frame:setDisplay(fr):setFrameAsMonitor()fe[fq].frame:setSize(fr:getSize())return fe[fq].frame end,setMonitorScale=function(self,fs,ft)if ff then fd.setTextScale(fs*0.5)if ft then self:setSize(fd:getSize())end end;return self,ff end,setFrameAsMonitor=function(self,fu)ff=fu or true;return self end,showBar=function(self,fv)self.barActive=fv or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,ar,aB,aC)self.barText=ar or""self.barBackground=aB or self.barBackground;self.barTextcolor=aC or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,cw)self.barTextAlign=cw or"left"self:setVisualChanged()return self end,setDisplay=function(self,a4)fd=a4;aA=a3(fd)return self end,getDisplay=function(self)return fd end,getVisualChanged=function(self)local fw=cj.getVisualChanged(self)for aO,aK in pairs(fb)do if fa[aK]~=nil then for aO,aP in pairs(fa[aK])do if aP.getVisualChanged~=nil and aP:getVisualChanged()then fw=true end end end end;return fw end,loseFocusHandler=function(self)cj.loseFocusHandler(self)end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,aL,bp)if fc~=nil then if fc.keyHandler~=nil then if fc:keyHandler(aL,bp)then return true end end end;return false end,backgroundKeyHandler=function(self,aL,bp)cj.backgroundKeyHandler(self,aL,bp)for aO,aK in pairs(fb)do if fa[aK]~=nil then for aO,aP in pairs(fa[aK])do if aP.backgroundKeyHandler~=nil then aP:backgroundKeyHandler(aL,bp)end end end end end,eventHandler=function(self,aL,c5,c6,c7,c8)cj.eventHandler(self,aL,c5,c6,c7,c8)for aO,aK in pairs(fb)do if fa[aK]~=nil then for aO,aP in pairs(fa[aK])do if aP.eventHandler~=nil then aP:eventHandler(aL,c5,c6,c7,c8)end end end end;if aL=="terminate"then fd.clear()fd.setCursorPos(1,1)a.stop()end end,mouseClickHandler=function(self,aL,c2,ap,aq)local b_,c0=self:getOffset()b_=b_<0 and math.abs(b_)or-b_;c0=c0<0 and math.abs(c0)or-c0;if self.drag then if aL=="mouse_drag"then local fx=1;local fy=1;if self.parent~=nil then fx,fy=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(ap+self.xToRem-(fx-1)+b_,aq-(fy-1)+c0)end;if aL=="mouse_up"then self.drag=false end;return true end;if cj.mouseClickHandler(self,aL,c2,ap,aq)then local bX,bY=self:getAbsolutePosition(self:getAnchorPosition())if aL~="monitor_touch"or ff then for aO,aK in pairs(fb)do if fa[aK]~=nil then for aO,aP in b4(fa[aK])do if aP.mouseClickHandler~=nil then if aP:mouseClickHandler(aL,c2,ap+b_,aq+c0)then return true end end end end end elseif not ff then for aO,fz in pairs(fe)do if c2==fz.monitor then fz.frame:mouseClickHandler(aL,c2,ap,aq)end end end;if self.isMoveable then if ap>=bX and ap<=bX+self.width-1 and aq==bY and aL=="mouse_click"then self.drag=true;self.xToRem=bX-ap end end;if fc~=nil then fc:loseFocusHandler()fc=nil end;return true end;return false end,setText=function(self,ap,aq,ar)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setText(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(ar,math.max(1-ap+1,1),self.width-ap+1))else aA.setText(math.max(ap+cn-1,cn),co+aq-1,f(ar,math.max(1-ap+1,1),self.width-ap+1))end end end,setBG=function(self,ap,aq,aB)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setBG(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(aB,math.max(1-ap+1,1),self.width-ap+1))else aA.setBG(math.max(ap+cn-1,cn),co+aq-1,f(aB,math.max(1-ap+1,1),self.width-ap+1))end end end,setFG=function(self,ap,aq,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setFG(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(aC,math.max(1-ap+1,1),self.width-ap+1))else aA.setFG(math.max(ap+cn-1,cn),co+aq-1,f(aC,math.max(1-ap+1,1),self.width-ap+1))end end end,writeText=function(self,ap,aq,ar,aB,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:writeText(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(ar,math.max(1-ap+1,1),self.width-ap+1),aB,aC)else aA.writeText(math.max(ap+cn-1,cn),co+aq-1,f(ar,math.max(1-ap+1,1),self.width-ap+1),aB,aC)end end end,drawBackgroundBox=function(self,ap,aq,a6,m,aB)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawBackgroundBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aB)else aA.drawBackgroundBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aB)end end,drawTextBox=function(self,ap,aq,a6,m,aD)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawTextBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aD:sub(1,1))else aA.drawTextBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aD:sub(1,1))end end,drawForegroundBox=function(self,ap,aq,a6,m,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawForegroundBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aC)else aA.drawForegroundBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aC)end end,draw=function(self)if self:getVisualChanged()then if cj.draw(self)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())local eY,eZ=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(eY,eZ,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(eY,eZ,self.width,self.height,self.fgColor)self.parent:drawTextBox(eY,eZ,self.width,self.height," ")else aA.drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)aA.drawForegroundBox(cn,co,self.width,self.height,self.fgColor)aA.drawTextBox(cn,co,self.width,self.height," ")end;e.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(eY,eZ,aZ(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)else aA.writeText(cn,co,aZ(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)end end;for aO,aK in b4(fb)do if fa[aK]~=nil then for aO,aP in pairs(fa[aK])do if aP.draw~=nil then aP:draw()end end end end;if dv then fd.setTextColor(fg)fd.setCursorPos(ds,dt)if self.parent~=nil then fd.setCursorBlink(self:isFocused())else fd.setCursorBlink(dv)end end;self:setVisualChanged(false)end;for aO,fz in pairs(fe)do fz.frame:draw()end;aA.update()end end,addObject=function(self,fk)return fj(fk)end,removeObject=function(self,fk)return fl(fk)end,getObject=function(self,fk)return fi(fk)end,addButton=function(self,bF)local fk=ci(bF)fk.name=bF;return fj(fk)end,addLabel=function(self,bF)local fk=d6(bF)fk.name=bF;fk.bgColor=self.bgColor;fk.fgColor=self.fgColor;return fj(fk)end,addCheckbox=function(self,bF)local fk=cq(bF)fk.name=bF;return fj(fk)end,addInput=function(self,bF)local fk=cO(bF)fk.name=bF;return fj(fk)end,addProgram=function(self,bF)local fk=dq(bF)fk.name=bF;return fj(fk)end,addTextfield=function(self,bF)local fk=eR(bF)fk.name=bF;return fj(fk)end,addList=function(self,bF)local fk=dg(bF)fk.name=bF;return fj(fk)end,addDropdown=function(self,bF)local fk=cr(bF)fk.name=bF;return fj(fk)end,addRadio=function(self,bF)local fk=ey(bF)fk.name=bF;return fj(fk)end,addTimer=function(self,bF)local fk=f2(bF)fk.name=bF;return fj(fk)end,addAnimation=function(self,bF)local fk=c9(bF)fk.name=bF;return fj(fk)end,addSlider=function(self,bF)local fk=eP(bF)fk.name=bF;return fj(fk)end,addScrollbar=function(self,bF)local fk=eD(bF)fk.name=bF;return fj(fk)end,addMenubar=function(self,bF)local fk=dj(bF)fk.name=bF;return fj(fk)end,addThread=function(self,bF)local fk=e_(bF)fk.name=bF;return fj(fk)end,addPane=function(self,bF)local fk=dp(bF)fk.name=bF;return fj(fk)end,addImage=function(self,bF)local fk=cG(bF)fk.name=bF;return fj(fk)end,addProgressbar=function(self,bF)local fk=ep(bF)fk.name=bF;return fj(fk)end,addFrame=function(self,bF)local fk=f8(bF,self)fk.name=bF;return fj(fk)end}setmetatable(bO,cj)if f9==nil then table.insert(c,bO)end;return bO end;local fA=false;local function fB(aL,c5,c6,c7,c8)if aL=="mouse_click"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_drag"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_up"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_scroll"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="monitor_touch"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="key"or aL=="char"then b:keyHandler(aL,c5)b:backgroundKeyHandler(aL,c5)end;for aO,aP in pairs(c)do aP:eventHandler(aL,c5,c6,c7,c8)end;if fA then b:draw()end end;function a.autoUpdate(f1)e.clear()fA=f1 or true;b:draw()while fA do local aL,c5,c6,c7,c8=os.pullEventRaw()fB(aL,c5,c6,c7,c8)end end;function a.update(aL,c5,c6,c7,c8)if aL~="nil"then fB(aL,c5,c6,c7,c8)else b:draw()end end;function a.stop()fA=false end;function a.getFrame(bF)for aO,aP in pairs(c)do if aP.name==bF then return aP end end end;function a.getActiveFrame()return b end;function a.setActiveFrame(bP)if bP:getType()=="Frame"then b=bP;return true end;return false end;function a.createFrame(bF)return f8(bF)end;function a.removeFrame(bF)for bp,aP in pairs(c)do if aP.name==bF then c[bp]=nil;return true end end;return false end;if a.debugger then a.debugFrame=a.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug",colors.black,colors.gray)a.debugList=a.debugFrame:addList("debugList"):setSize(a.debugFrame.width-2,a.debugFrame.height-3):setPosition(2,3):setScrollable(true):show()a.debugFrame:addButton("back"):setAnchor("right"):setSize(1,1):setText("\22"):onClick(function()a.oldFrame:show()end):setBackground(colors.red):show()a.debugLabel=a.debugFrame:addLabel("debugLabel"):onClick(function()a.oldFrame=b;a.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):setZIndex(20):show()end;if a.debugger then function a.debug(...)local aV={...}if b.name~="basaltDebuggingFrame"then if b~=a.debugLabel.frame then a.debugLabel:setParent(b)end end;local fC=""for bp,aP in pairs(aV)do fC=fC..tostring(aP)..(#aV~=bp and", "or"")end;a.debugLabel:setText("[Debug] "..fC)a.debugList:addItem(fC)if a.debugList:getItemCount()>50 then a.debugList:removeItem(1)end;a.debugList:setValue(a.debugList:getItem(a.debugList:getItemCount()))a.debugLabel:show()end end;return a \ No newline at end of file +local a={debugger=true,version=1}local b;local c={}local d={}local e=term.current()local f=string.sub;local g={[colors.white]="0",[colors.orange]="1",[colors.magenta]="2",[colors.lightBlue]="3",[colors.yellow]="4",[colors.lime]="5",[colors.pink]="6",[colors.gray]="7",[colors.lightGray]="8",[colors.cyan]="9",[colors.purple]="a",[colors.blue]="b",[colors.brown]="c",[colors.green]="d",[colors.red]="e",[colors.black]="f"}local h={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 i={{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147","\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132","\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131","\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132","\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32","\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129","\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32","\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32","\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148","\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32","\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32","\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148","\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149","\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32","\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32","\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32","\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132","\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32","\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149","\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32","\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148","\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32","\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32","\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129","\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32","\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32","\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32","\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148","\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32","\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32","\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32","\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132","\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149","\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32","\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32","\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32","\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144","\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149","\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129"},{[[000110000110110000110010101000000010000000100101]],[[000000110110000000000010101000000010000000100101]],[[000000000000000000000000000000000000000000000000]],[[100010110100000010000110110000010100000100000110]],[[000000110000000010110110000110000000000000110000]],[[000000000000000000000000000000000000000000000000]],[[000000110110000010000000100000100000000000000010]],[[000000000110110100010000000010000000000000000100]],[[000000000000000000000000000000000000000000000000]],[[010000000000100110000000000000000000000110010000]],[[000000000000000000000000000010000000010110000000]],[[000000000000000000000000000000000000000000000000]],[[011110110000000100100010110000000100000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110000110110000000000000000000010100100010000000]],[[000010000000000000110110000000000100010010000000]],[[000000000000000000000000000000000000000000000000]],[[010110010110100110110110010000000100000110110110]],[[000000000000000000000110000000000110000000000000]],[[000000000000000000000000000000000000000000000000]],[[010100010110110000000000000000110000000010000000]],[[110110000000000000110000110110100000000010000000]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[100100100100100100100100100100100100100100100100]],[[000000110100110110000010000011110000000000011000]],[[000000000100000000000010000011000110000000001000]],[[000000000000000000000000000000000000000000000000]],[[010000100100000000000000000100000000010010110000]],[[000000000000000000000000000000110110110110110000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110000000110110110110110110110110]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000110110000110010000000000000000010010]],[[000010000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110110110110000000000000]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110000000000000000010000]],[[000000000000000000000000100000000000000110000110]],[[000000000000000000000000000000000000000000000000]]}}local j={}local k={}do local l=0;local m=#i[1]local n=#i[1][1]for o=1,m,3 do for p=1,n,3 do local q=string.char(l)local r={}r[1]=i[1][o]:sub(p,p+2)r[2]=i[1][o+1]:sub(p,p+2)r[3]=i[1][o+2]:sub(p,p+2)local s={}s[1]=i[2][o]:sub(p,p+2)s[2]=i[2][o+1]:sub(p,p+2)s[3]=i[2][o+2]:sub(p,p+2)k[q]={r,s}l=l+1 end end;j[1]=k end;local function t(u,v)local w={["0"]="1",["1"]="0"}if u<=#j then return true end;for x=#j+1,u do local y={}local z=j[x-1]for l=0,255 do local q=string.char(l)local r={}local s={}local A=z[q][1]local B=z[q][2]for o=1,#A do local C,D,E,F,G,H={},{},{},{},{},{}for p=1,#A[1]do local I=k[A[o]:sub(p,p)][1]table.insert(C,I[1])table.insert(D,I[2])table.insert(E,I[3])local J=k[A[o]:sub(p,p)][2]if B[o]:sub(p,p)=="1"then table.insert(F,J[1]:gsub("[01]",w))table.insert(G,J[2]:gsub("[01]",w))table.insert(H,J[3]:gsub("[01]",w))else table.insert(F,J[1])table.insert(G,J[2])table.insert(H,J[3])end end;table.insert(r,table.concat(C))table.insert(r,table.concat(D))table.insert(r,table.concat(E))table.insert(s,table.concat(F))table.insert(s,table.concat(G))table.insert(s,table.concat(H))end;y[q]={r,s}if v then v="Font"..x.."Yeld"..l;os.queueEvent(v)os.pullEvent(v)end end;j[x]=y end;return true end;local function K(L,M,N,O,P)if not type(M)=="string"then error("Not a String",3)end;local Q=type(N)=="string"and N:sub(1,1)or g[N]or error("Wrong Front Color",3)local R=type(O)=="string"and O:sub(1,1)or g[O]or error("Wrong Back Color",3)if j[L]==nil then t(3,false)end;local S=j[L]or error("Wrong font size selected",3)if M==""then return{{""},{""},{""}}end;local T={}for o in M:gmatch('.')do table.insert(T,o)end;local U={}local m=#S[T[1]][1]for V=1,m do local W={}for o=1,#T do W[o]=S[T[o]]and S[T[o]][1][V]or""end;U[V]=table.concat(W)end;local X={}local Y={}local Z={["0"]=Q,["1"]=R}local _={["0"]=R,["1"]=Q}for V=1,m do local a0={}local a1={}for o=1,#T do local a2=S[T[o]]and S[T[o]][2][V]or""a0[o]=a2:gsub("[01]",P and{["0"]=N:sub(o,o),["1"]=O:sub(o,o)}or Z)a1[o]=a2:gsub("[01]",P and{["0"]=O:sub(o,o),["1"]=N:sub(o,o)}or _)end;X[V]=table.concat(a0)Y[V]=table.concat(a1)end;return{U,X,Y}end;local function a3(a4)local a5=a4;local a6,m=a5.getSize()local a7={}local a8={}local a9={}local aa={}local ab={}local ac={}local ad;local ae={}local function af()ad=(" "):rep(a6)for ag=0,15 do local ah=2^ag;local ai=g[ah]ae[ah]=ai:rep(a6)end end;af()local function aj()local ak=ad;local al=ae[colors.white]local am=ae[colors.black]for an=1,m do a7[an]=f(a7[an]==nil and ak or a7[an]..ak:sub(1,a6-a7[an]:len()),1,a6)a9[an]=f(a9[an]==nil and al or a9[an]..al:sub(1,a6-a9[an]:len()),1,a6)a8[an]=f(a8[an]==nil and am or a8[an]..am:sub(1,a6-a8[an]:len()),1,a6)end end;aj()local function ao(ap,aq,ar)if aq>=1 and aq<=m then if ap+ar:len()>0 and ap<=a6 then local as=a7[aq]local at;local au=ap+#ar-1;if ap<1 then local av=1-ap+1;local aw=a6-ap+1;ar=f(ar,av,aw)elseif au>a6 then local aw=a6-ap+1;ar=f(ar,1,aw)end;if ap>1 then local aw=ap-1;at=f(as,1,aw)..ar else at=ar end;if au=1 and aq<=m then if ap+ay:len()>0 and ap<=a6 then local as=a8[aq]local at;local au=ap+#ay-1;if ap<1 then ay=f(ay,1-ap+1,a6-ap+1)elseif au>a6 then ay=f(ay,1,a6-ap+1)end;if ap>1 then at=f(as,1,ap-1)..ay else at=ay end;if au=1 and aq<=m then if ap+ay:len()>0 and ap<=a6 then local as=a9[aq]local at;local au=ap+#ay-1;if ap<1 then local av=1-ap+1;local aw=a6-ap+1;ay=f(ay,av,aw)elseif au>a6 then local aw=a6-ap+1;ay=f(ay,1,aw)end;if ap>1 then local aw=ap-1;at=f(as,1,aw)..ay else at=ay end;if au1 then while#bg>2 do table.sort(bg,function(bq,br)return bq[2]>br[2]end)local bs,bt=bf(bg),#bg;local bu,bv=bg[bt][1],bg[bs][1]for o=1,6 do if bk[o]==bu then bk[o]=bv;bg[bs][2]=bg[bs][2]+1 end end;bg[bt]=nil end;local bw=128;for o=1,#bk-1 do if bk[o]~=bk[6]then bw=bw+2^(o-1)end end;return string.char(bw),bc[bg[1][1]==bk[6]and bg[2][1]or bg[1][1]],bc[bk[6]]else return"\128",bc[bk[1]],bc[bk[1]]end end;local bx,a6,m,aB={{},{},{}},0,#b7+#b7%3,b8 or colors.black;for o=1,#b7 do if#b7[o]>a6 then a6=#b7[o]end end;for aq=0,m-1,3 do local by,bz,bA,bB={},{},{},1;for ap=0,a6-1,2 do local bk,bl={},{}for bC=1,3 do for bD=1,2 do bk[#bk+1]=b7[aq+bC]and b7[aq+bC][ap+bD]and(b7[aq+bC][ap+bD]==0 and aB or b7[aq+bC][ap+bD])or aB;bl[bk[#bk]]=bl[bk[#bk]]and bl[bk[#bk]]+1 or 1 end end;by[bB],bz[bB],bA[bB]=bj(bk,bl)bB=bB+1 end;bx[1][#bx[1]+1],bx[2][#bx[2]+1],bx[3][#bx[3]+1]=table.concat(by),table.concat(bz),table.concat(bA)end;bx.width,bx.height=#bx[1][1],#bx[1]return bx end;local function bE(bF)local bG="Object"local aP;local bH=1;local bI="left"local bJ="top"local bK=false;local bL=false;local bM=true;local bN=aI()local bO={x=1,y=1,width=1,height=1,bgColor=colors.black,fgColor=colors.white,name=bF or"Object",parent=nil,show=function(self)bL=true;bM=true;return self end,hide=function(self)bL=false;bM=true;return self end,isVisible=function(self)return bL end,setFocus=function(self)if self.parent~=nil then self.parent:setFocusedObject(self)end;return self end,setZIndex=function(self,aK)bH=aK;if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end;return self end,getZIndex=function(self)return bH end,getType=function(self)return bG end,getName=function(self)return self.name end,remove=function(self)if self.parent~=nil then self.parent:removeObject(self)end;return self end,setParent=function(self,bP)if bP.getType~=nil and bP:getType()=="Frame"then self:remove()bP:addObject(self)if self.draw then self:show()end end;return self end,setValue=function(self,bQ)if aP~=bQ then aP=bQ;bM=true;self:valueChangedHandler()end;return self end,getValue=function(self)return aP end,getVisualChanged=function(self)return bM end,setVisualChanged=function(self,bR)bM=bR or true;if bR==nil then bM=true end;return self end,getEventSystem=function(self)return bN end,getParent=function(self)return self.parent end,setPosition=function(self,bS,bT,bU)if bU then self.x,self.y=math.floor(self.x+bS),math.floor(self.y+bT)else self.x,self.y=math.floor(bS),math.floor(bT)end;bM=true;return self end,getPosition=function(self)return self.x,self.y end,getVisibility=function(self)return bL end,setVisibility=function(self,bV)bL=bV or not bL;bM=true;return self end,setSize=function(self,a6,m)self.width,self.height=a6,m;bM=true;return self end,getHeight=function(self)return self.height end,getWidth=function(self)return self.width end,getSize=function(self)return self.width,self.height end,setBackground=function(self,bW)self.bgColor=bW;bM=true;return self end,getBackground=function(self)return self.bgColor end,setForeground=function(self,bW)self.fgColor=bW;bM=true;return self end,getForeground=function(self)return self.fgColor end,draw=function(self)if bL then return true end;return false end,getAbsolutePosition=function(self,ap,aq)if ap==nil then ap=self.x end;if aq==nil then aq=self.y end;if self.parent~=nil then local bX,bY=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())ap=bX+ap-1;aq=bY+aq-1 end;return ap,aq end,getAnchorPosition=function(self,ap,aq,bZ)if ap==nil then ap=self.x end;if aq==nil then aq=self.y end;if bI=="right"then ap=self.parent.width-ap-self.width+2 end;if bJ=="bottom"then aq=self.parent.height-aq-self.height+2 end;local b_,c0=self:getOffset()if bK or bZ then return ap,aq end;return ap+b_,aq+c0 end,getOffset=function(self)if self.parent~=nil and bK==false then return self.parent:getFrameOffset()end;return 0,0 end,ignoreOffset=function(self,c1)bK=c1 or true;return self end,setAnchor=function(self,...)for aO,aP in pairs(table.pack(...))do if aP=="right"or aP=="left"then bI=aP end;if aP=="top"or aP=="bottom"then bJ=aP end end;bM=true;return self end,getAnchor=function(self)return bI,bJ end,onChange=function(self,aN)self:registerEvent("value_changed",aN)return self end,onClick=function(self,aN)self:registerEvent("mouse_click",aN)self:registerEvent("monitor_touch",aN)return self end,onEvent=function(self,aN)self:registerEvent("custom_event_handler",aN)return self end,onClickUp=function(self,aN)self:registerEvent("mouse_up",aN)return self end,onKey=function(self,aN)self:registerEvent("key",aN)self:registerEvent("char",aN)return self end,onKeyUp=function(self,aN)self:registerEvent("key_up",aN)return self end,onBackgroundKey=function(self,aN)self:registerEvent("background_key",aN)self:registerEvent("background_char",aN)return self end,onBackgroundKeyUp=function(self,aN)self:registerEvent("background_key_up",aN)return self end,isFocused=function(self)if self.parent~=nil then return self.parent:getFocusedObject()==self end;return false end,onGetFocus=function(self,aN)self:registerEvent("get_focus",aN)return self end,onLoseFocus=function(self,aN)self:registerEvent("lose_focus",aN)return self end,registerEvent=function(self,aL,aN)return bN:registerEvent(aL,aN)end,removeEvent=function(self,aL,aK)return bN:removeEvent(aL,aK)end,sendEvent=function(self,aL,...)return bN:sendEvent(aL,self,...)end,mouseClickHandler=function(self,aL,c2,ap,aq)local c3,c4=self:getAbsolutePosition(self:getAnchorPosition())if c3<=ap and c3+self.width>ap and c4<=aq and c4+self.height>aq and bL then if self.parent~=nil then self.parent:setFocusedObject(self)end;bN:sendEvent(aL,self,aL,c2,ap,aq)return true end;return false end,keyHandler=function(self,aL,bp)if self:isFocused()then bN:sendEvent(aL,self,aL,bp)return true end;return false end,backgroundKeyHandler=function(self,aL,bp)bN:sendEvent("background_"..aL,self,aL,bp)end,valueChangedHandler=function(self)bN:sendEvent("value_changed",self)end,eventHandler=function(self,aL,c5,c6,c7,c8)bN:sendEvent("custom_event_handler",self,aL,c5,c6,c7,c8)end,getFocusHandler=function(self)bN:sendEvent("get_focus",self)end,loseFocusHandler=function(self)bN:sendEvent("lose_focus",self)end}bO.__index=bO;return bO end;local function c9(bF)local bO={}local bG="Animation"local ca;local cb={}local aK=1;local cc=0;local cd;local function ce()if cb[aK]~=nil then cb[aK].f(bO,aK)end;aK=aK+1;if cb[aK]~=nil then if cb[aK].t>0 then ca=os.startTimer(cb[aK].t)else ce()end end end;bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,aN,cf)cd=aN;table.insert(cb,{f=aN,t=cf or cc})return self end,wait=function(self,cf)cc=cf;return self end,rep=function(self,cg)for ap=1,cg do table.insert(cb,{f=cd,t=cc})end;return self end,clear=function(self)cb={}cd=nil;cc=0;aK=1;return self end,play=function(self)aK=1;if cb[aK]~=nil then if cb[aK].t>0 then ca=os.startTimer(cb[aK].t)else ce()end end;return self end,cancel=function(self)os.cancelTimer(ca)return self end,eventHandler=function(self,aL,ch)if aL=="timer"and ch==ca then if cb[aK]~=nil then ce()end end end}bO.__index=bO;return bO end;local function ci(bF)local cj=bE(bF)local bG="Button"cj:setValue("Button")cj:setZIndex(5)cj.width=8;cj.bgColor=h.ButtonBG;cj.fgColor=h.ButtonFG;local ck="center"local cl="center"local bO={getType=function(self)return bG end,setHorizontalAlign=function(self,cm)ck=cm end,setVerticalAlign=function(self,cm)cl=cm end,setText=function(self,ar)cj:setValue(ar)return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,cl)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height," ")for ag=1,self.height do if ag==cp then self.parent:setText(cn,co+ag-1,aZ(self:getValue(),self.width,ck))end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cq(bF)local cj=bE(bF)local bG="Checkbox"cj:setZIndex(5)cj:setValue(false)cj.width=1;cj.height=1;cj.bgColor=h.CheckboxBG;cj.fgColor=h.CheckboxFG;local bO={symbol="\42",getType=function(self)return bG end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if aL=="mouse_click"and c2==1 or aL=="monitor_touch"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 cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,"center")self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if ag==cp then if self:getValue()==true then self.parent:writeText(cn,co+ag-1,aZ(self.symbol,self.width,"center"),self.bgColor,self.fgColor)else self.parent:writeText(cn,co+ag-1,aZ(" ",self.width,"center"),self.bgColor,self.fgColor)end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cr(bF)local cj=bE(bF)local bG="Dropdown"cj.width=12;cj.height=1;cj.bgColor=h.dropdownBG;cj.fgColor=h.dropdownFG;cj:setZIndex(6)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local cx=0;local cy=16;local cz=6;local cA="\16"local cB="\31"local cC=false;local bO={getType=function(self)return bG end,setIndexOffset=function(self,cD)cx=cD;return self end,getIndexOffset=function(self)return cx end,addItem=function(self,ar,aB,aC,...)table.insert(cs,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,getAll=function(self)return cs end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,setDropdownSize=function(self,a6,m)cy,cz=a6,m;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cC then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then if#cs>0 then for ag=1,cz do if cs[ag+cx]~=nil then if cn<=ap and cn+cy>ap and co+ag==aq then self:setValue(cs[ag+cx])return true end end end end end;if aL=="mouse_scroll"then cx=cx+c2;if cx<0 then cx=0 end;if c2==1 then if#cs>cz then if cx>#cs-cz then cx=#cs-cz end else cx=cs-1 end end;return true end;self:setVisualChanged()end;if cj.mouseClickHandler(self,aL,c2,ap,aq)then cC=true else cC=false end end,draw=function(self)if cj.draw(self)then local cn,co=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)local cG=self:getValue()local ar=aZ(cG~=nil and cG.text or"",self.width,cw):sub(1,self.width-1)..(cC and cB or cA)self.parent:writeText(cn,co,ar,self.bgColor,self.fgColor)if cC then for ag=1,cz do if cs[ag+cx]~=nil then if cs[ag+cx]==cG then if cv then self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),ct,cu)else self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end else self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cH(bF)local cj=bE(bF)local bG="Image"cj:setZIndex(2)local cI;local cJ;local cK=false;local function b6()local b9={[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 ba,bb,bc={},{},{}for o=0,15 do bb[2^o]=o end;do local bd="0123456789abcdef"for o=1,16 do ba[bd:sub(o,o)]=o-1;ba[o-1]=bd:sub(o,o)bc[bd:sub(o,o)]=2^(o-1)bc[2^(o-1)]=bd:sub(o,o)local be=b9[o-1]for o=1,#be do be[o]=2^be[o]end end end;local function bf(bg)local bh=b9[bb[bg[#bg][1]]]for p=1,#bh do local bi=bh[p]for o=1,#bg-1 do if bg[o][1]==bi then return o end end end;return 1 end;local function bj(bk,bl)if not bl then local bm={}bl={}for o=1,6 do local bn=bk[o]local bo=bl[bn]bl[bn],bm[o]=bo and bo+1 or 1,bn end;bk=bm end;local bg={}for bp,aP in pairs(bl)do bg[#bg+1]={bp,aP}end;if#bg>1 then while#bg>2 do table.sort(bg,function(bq,br)return bq[2]>br[2]end)local bs,bt=bf(bg),#bg;local bu,bv=bg[bt][1],bg[bs][1]for o=1,6 do if bk[o]==bu then bk[o]=bv;bg[bs][2]=bg[bs][2]+1 end end;bg[bt]=nil end;local bw=128;for o=1,#bk-1 do if bk[o]~=bk[6]then bw=bw+2^(o-1)end end;return string.char(bw),bc[bg[1][1]==bk[6]and bg[2][1]or bg[1][1]],bc[bk[6]]else return"\128",bc[bk[1]],bc[bk[1]]end end;local bx,a6,m,aB={{},{},{}},0,#cI+#cI%3,cj.bgColor or colors.black;for o=1,#cI do if#cI[o]>a6 then a6=#cI[o]end end;for aq=0,m-1,3 do local by,bz,bA,bB={},{},{},1;for ap=0,a6-1,2 do local bk,bl={},{}for bC=1,3 do for bD=1,2 do bk[#bk+1]=cI[aq+bC]and cI[aq+bC][ap+bD]and(cI[aq+bC][ap+bD]==0 and aB or cI[aq+bC][ap+bD])or aB;bl[bk[#bk]]=bl[bk[#bk]]and bl[bk[#bk]]+1 or 1 end end;by[bB],bz[bB],bA[bB]=bj(bk,bl)bB=bB+1 end;bx[1][#bx[1]+1],bx[2][#bx[2]+1],bx[3][#bx[3]+1]=table.concat(by),table.concat(bz),table.concat(bA)end;bx.width,bx.height=#bx[1][1],#bx[1]cJ=bx end;local bO={getType=function(self)return bG end,loadImage=function(self,aT)cI=paintutils.loadImage(aT)cK=false;return self end,loadBlittleImage=function(self,aT)cK=true;return self end,shrink=function(self)b6()cK=true;return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then if cI~=nil then local cn,co=self:getAnchorPosition()if cK then local b5,cL,cM=cJ[1],cJ[2],cJ[3]for o=1,cJ.height do local cN=b5[o]if type(cN)=="string"then self.parent:setText(cn,co+o-1,cN)self.parent:setFG(cn,co+o-1,cL[o])self.parent:setBG(cn,co+o-1,cM[o])elseif type(cN)=="table"then self.parent:setText(cn,co+o-1,cN[2])self.parent:setFG(cn,co+o-1,cL[o])self.parent:setBG(cn,co+o-1,cM[o])end end else for bT=1,math.min(#cI,self.height)do local cO=cI[bT]for bS=1,math.min(#cO,self.width)do if cO[bS]>0 then self.parent:drawBackgroundBox(cn+bS-1,co+bT-1,1,1,cO[bS])end end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cP(bF)local cj=bE(bF)local bG="Input"local cQ="text"local cR=0;cj:setZIndex(5)cj:setValue("")cj.width=10;cj.height=1;cj.bgColor=h.InputBG;cj.fgColor=h.InputFG;local cS=1;local cT=1;local cU=""local cV;local cW;local cX=cU;local cY=false;local bO={getType=function(self)return bG end,setInputType=function(self,cZ)if cZ=="password"or cZ=="number"or cZ=="text"then cQ=cZ end;return self end,setDefaultText=function(self,ar,c_,d0)cU=ar;cV=d0 or cV;cW=c_ or cW;if self:isFocused()then cX=""else cX=cU end;return self end,getInputType=function(self)return cQ end,setValue=function(self,cG)cj.setValue(self,tostring(cG))if not cY then cS=tostring(cG):len()+1 end;return self end,getValue=function(self)local cG=cj.getValue(self)return cQ=="number"and tonumber(cG)or cG end,setInputLimit=function(self,d1)cR=tonumber(d1)or cR;return self end,getInputLimit=function(self)return cR end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then local cn,co=self:getAnchorPosition()cX=""if self.parent~=nil then self.parent:setCursor(true,cn+cS-cT,co,self.fgColor)end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)cX=cU end end,keyHandler=function(self,aL,bp)if cj.keyHandler(self,aL,bp)then cY=true;if aL=="key"then if bp==keys.backspace then local ar=tostring(cj.getValue())if cS>1 then self:setValue(ar:sub(1,cS-2)..ar:sub(cS,ar:len()))if cS>1 then cS=cS-1 end;if cT>1 then if cSd2 then cS=d2+1 end;if cS<1 then cS=1 end;if cS=self.width+cT then cT=cS-self.width+1 end;if cT<1 then cT=1 end end;if bp==keys.left then cS=cS-1;if cS>=1 then if cS=self.width+cT then cT=cS end end;if cS<1 then cS=1 end;if cT<1 then cT=1 end end end;if aL=="char"then local ar=cj.getValue()if ar:len()=self.width+cT then cT=cT+1 end end end;local cn,co=self:getAnchorPosition()local cG=tostring(cj.getValue())local d4=(cS<=cG:len()and cS-1 or cG:len())-(cT-1)if d4>self.x+self.width-1 then d4=self.x+self.width-1 end;if self.parent~=nil then self.parent:setCursor(true,cn+d4,co,self.fgColor)end;cY=false end end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if aL=="mouse_click"and c2==1 then end;return true end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,"center")self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if ag==cp then local cG=tostring(cj.getValue())local d0=self.bgColor;local c_=self.fgColor;local ar;if cG:len()<=0 then ar=cX;d0=cV or d0;c_=cW or c_ end;ar=cX;if cG~=""then ar=cG end;ar=ar:sub(cT,self.width+cT-1)local d5=self.width-ar:len()if d5<0 then d5=0 end;if cQ=="password"and cG~=""then ar=string.rep("*",ar:len())end;ar=ar..string.rep(" ",d5)self.parent:writeText(cn,co+ag-1,ar,d0,c_)end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function d6(bF)local cj=bE(bF)local bG="Label"cj:setZIndex(3)cj.fgColor=colors.white;cj.bgcolor=colors.black;local d7=true;cj:setValue("")local ck="left"local cl="top"local d8=0;local bO={getType=function(self)return bG end,setText=function(self,ar)ar=tostring(ar)cj:setValue(ar)if d7 then self.width=ar:len()end;return self end,setTextAlign=function(self,d9,da)ck=d9 or ck;cl=da or cl;self:setVisualChanged()return self end,setFontSize=function(self,u)if u>0 and u<=4 then d8=u-1 or 0 end;return self end,getFontSize=function(self)return d8+1 end,setSize=function(self,a6,m)cj.setSize(self,a6,m)d7=false;self:setVisualChanged()return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,cl)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height," ")if d8==0 then for ag=1,self.height do if ag==cp then self.parent:writeText(cn,co+ag-1,aZ(self:getValue(),self.width,ck),self.bgColor,self.fgColor)end end else local db=K(d8,self:getValue(),self.fgColor,self.bgColor)if d7 then self.height=#db[1]-1;self.width=#db[1][1]end;for ag=1,self.height do if ag==cp then local dc,dd=self.parent:getSize()local de,df=#db[1][1],#db[1]cn=cn or math.floor((dc-de)/2)+1;co=co or math.floor((dd-df)/2)+1;for o=1,df do self.parent:setFG(cn,co+o+ag-2,aZ(db[2][o],self.width,ck))self.parent:setBG(cn,co+o+ag-2,aZ(db[3][o],self.width,ck,g[self.bgColor]))self.parent:setText(cn,co+o+ag-2,aZ(db[1][o],self.width,ck))end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function dg(bF)local cj=bE(bF)local bG="List"cj.width=16;cj.height=6;cj.bgColor=h.listBG;cj.fgColor=h.listFG;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local cx=0;local dh=true;local bO={getType=function(self)return bG end,addItem=function(self,ar,aB,aC,...)table.insert(cs,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})if#cs==1 then self:setValue(cs[1])end;return self end,setIndexOffset=function(self,cD)cx=cD;return self end,getIndexOffset=function(self)return cx end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getAll=function(self)return cs end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,setScrollable=function(self,di)dh=di;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if cn<=ap and cn+self.width>ap and co<=aq and co+self.height>aq and self:isVisible()then if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if#cs>0 then for ag=1,self.height do if cs[ag+cx]~=nil then if cn<=ap and cn+self.width>ap and co+ag-1==aq then self:setValue(cs[ag+cx])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,ap,aq,cs[ag+cx])end end end end end;if aL=="mouse_scroll"and dh then cx=cx+c2;if cx<0 then cx=0 end;if c2>=1 then if#cs>self.height then if cx>#cs-self.height then cx=#cs-self.height end;if cx>=#cs then cx=#cs-1 end else cx=cx-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if cs[ag+cx]~=nil then if cs[ag+cx]==self:getValue()then if cv then self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),ct,cu)else self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end else self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function dj(bF)local cj=bE(bF)local bG="Menubar"local bO={}cj.width=30;cj.height=1;cj.bgColor=colors.gray;cj.fgColor=colors.lightGray;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local dk=0;local d5=1;local dh=false;local function dl()local dm=0;local bS=0;for ag=1,#cs do if bS+cs[ag].text:len()+d5*2>bO.width then if bSdm then dk=dm end;return self end,getPositionOffset=function(self)return dk end,setScrollable=function(self,di)dh=di;if di==nil then dh=true end;return self end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local c3,c4=self:getAbsolutePosition(self:getAnchorPosition())if c3<=ap and c3+self.width>ap and c4<=aq and c4+self.height>aq and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if aL=="mouse_click"or aL=="monitor_touch"then local bS=0;for ag=1,#cs do if cs[ag]~=nil then if c3+bS<=ap+dk and c3+bS+cs[ag].text:len()+d5*2>ap+dk and c4==aq then self:setValue(cs[ag])self:getEventSystem():sendEvent(aL,self,aL,0,ap,aq,cs[ag])end;bS=bS+cs[ag].text:len()+d5*2 end end end;if aL=="mouse_scroll"and dh then dk=dk+c2;if dk<0 then dk=0 end;local dm=dl()if dk>dm then dk=dm end end;self:setVisualChanged(true)return true end end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)local ar=""local dp=""local dq=""for aO,dr in pairs(cs)do local ds=(" "):rep(d5)..dr.text..(" "):rep(d5)ar=ar..ds;if dr==self:getValue()then dp=dp..g[ct or dr.bgCol or self.bgColor]:rep(ds:len())dq=dq..g[cu or dr.FgCol or self.fgColor]:rep(ds:len())else dp=dp..g[dr.bgCol or self.bgColor]:rep(ds:len())dq=dq..g[dr.FgCol or self.fgColor]:rep(ds:len())end end;self.parent:setText(cn,co,ar:sub(dk+1,self.width+dk))self.parent:setBG(cn,co,dp:sub(dk+1,self.width+dk))self.parent:setFG(cn,co,dq:sub(dk+1,self.width+dk))end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function dt(bF)local cj=bE(bF)local bG="Pane"local bO={getType=function(self)return bG end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.bgColor)end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function du(bF)local cj=bE(bF)local bG="Program"cj:setZIndex(5)local bO;local function dv(ap,aq,a6,m)local dw,dx=1,1;local b8,dy=colors.black,colors.white;local dz=false;local dA=false;local a7={}local a8={}local a9={}local dB={}local ad;local ae={}for o=0,15 do local dC=2^o;dB[dC]={e.getPaletteColour(dC)}end;local function af()ad=(" "):rep(a6)for ag=0,15 do local ah=2^ag;local ai=g[ah]ae[ah]=ai:rep(a6)end end;local function aj()af()local ak=ad;local al=ae[colors.white]local am=ae[colors.black]for ag=1,m do a7[ag]=f(a7[ag]==nil and ak or a7[ag]..ak:sub(1,a6-a7[ag]:len()),1,a6)a9[ag]=f(a9[ag]==nil and al or a9[ag]..al:sub(1,a6-a9[ag]:len()),1,a6)a8[ag]=f(a8[ag]==nil and am or a8[ag]..am:sub(1,a6-a8[ag]:len()),1,a6)end end;aj()local function dD()if dw>=1 and dx>=1 and dw<=a6 and dx<=m then else end end;local function dE(dF,dG,dH)local dI=dw;local au=dI+#dF-1;if dx>=1 and dx<=m then if dI<=a6 and au>=1 then if dI==1 and au==a6 then a7[dx]=dF;a9[dx]=dG;a8[dx]=dH else local dJ,dK,dL;if dI<1 then local dM=1-dI+1;local dN=a6-dI+1;dJ=f(dF,dM,dN)dK=f(dG,dM,dN)dL=f(dH,dM,dN)elseif au>a6 then local dN=a6-dI+1;dJ=f(dF,1,dN)dK=f(dG,1,dN)dL=f(dH,1,dN)else dJ=dF;dK=dG;dL=dH end;local dO=a7[dx]local dP=a9[dx]local dQ=a8[dx]local dR,dS,dT;if dI>1 then local dU=dI-1;dR=f(dO,1,dU)..dJ;dS=f(dP,1,dU)..dK;dT=f(dQ,1,dU)..dL else dR=dJ;dS=dK;dT=dL end;if au=1 and aq<=m then a7[eg]=a7[aq]a8[eg]=a8[aq]a9[eg]=a9[aq]else a7[eg]=ed;a9[eg]=ee;a8[eg]=ef end end end;if dA then dD()end end,isColor=function()return e.isColor()end,isColour=function()return e.isColor()end,write=function(ar)ar=tostring(ar)if dA then dE(ar,g[dy]:rep(ar:len()),g[b8]:rep(ar:len()))end end,clearLine=function()if dA then ao(1,dx,(" "):rep(a6))ax(1,dx,g[b8]:rep(a6))az(1,dx,g[dy]:rep(a6))end;if dA then dD()end end,clear=function()for ag=1,m do ao(1,ag,(" "):rep(a6))ax(1,ag,g[b8]:rep(a6))az(1,ag,g[dy]:rep(a6))end;if dA then dD()end end,blit=function(ar,eh,ei)if type(ar)~="string"then error("bad argument #1 (expected string, got "..type(ar)..")",2)end;if type(eh)~="string"then error("bad argument #2 (expected string, got "..type(eh)..")",2)end;if type(ei)~="string"then error("bad argument #3 (expected string, got "..type(ei)..")",2)end;if#eh~=#ar or#ei~=#ar then error("Arguments must be the same length",2)end;if dA then dE(ar,eh,ei)end end}return e8 end;cj.width=30;cj.height=12;local ej=dv(1,1,cj.width,cj.height)local ek;local el=false;local em={}bO={getType=function(self)return bG end,show=function(self)cj.show(self)ej.setBackgroundColor(self.bgColor)ej.setTextColor(self.fgColor)ej.basalt_setVisible(true)return self end,hide=function(self)cj.hide(self)ej.basalt_setVisible(false)return self end,setPosition=function(self,ap,aq,bU)cj.setPosition(self,ap,aq,bU)ej.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return ej end,getBasaltProcess=function()return ek end,setSize=function(self,a6,m)cj.setSize(self,a6,m)ej.basalt_resize(self.width,self.height)return self end,getStatus=function(self)if ek~=nil then return ek:getStatus()end;return"inactive"end,execute=function(self,aT,...)ek=aR:new(aT,ej,...)ej.setBackgroundColor(colors.black)ej.setTextColor(colors.white)ej.clear()ej.setCursorPos(1,1)ek:resume()el=false;return self end,stop=function(self)if ek~=nil then if not ek:isDead()then ek:resume("terminate")if ek:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,en)el=en or not el;if ek~=nil then if not ek:isDead()then if not el then self:injectEvents(em)em={}end end end;return self end,isPaused=function(self)return el end,injectEvent=function(self,aL,c5,c6,c7,c8,eo)if ek~=nil then if not ek:isDead()then if el==false or eo then ek:resume(aL,c5,c6,c7,c8)else table.insert(em,{event=aL,args={c5,c6,c7,c8}})end end end;return self end,getQueuedEvents=function(self)return em end,updateQueuedEvents=function(self,aJ)em=aJ or em;return self end,injectEvents=function(self,aJ)if ek~=nil then if not ek:isDead()then for aO,aP in pairs(aJ)do ek:resume(aP.event,table.unpack(aP.args))end end end;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if ek==nil then return false end;if not ek:isDead()then if not el then local ep,eq=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))ek:resume(aL,c2,ap-ep+1,aq-eq+1)end end;return true end end,keyHandler=function(self,aL,bp)cj.keyHandler(self,aL,bp)if self:isFocused()then if ek==nil then return false end;if not ek:isDead()then if not el then if self.draw then ek:resume(aL,bp)end end end end end,getFocusHandler=function(self)cj.getFocusHandler(self)if ek~=nil then if not ek:isDead()then if not el then if self.parent~=nil then local er,es=ej.getCursorPos()local cn,co=self:getAnchorPosition()if self.parent~=nil then if cn+er-1>=1 and cn+er-1<=cn+self.width-1 and es+co-1>=1 and es+co-1<=co+self.height-1 then self.parent:setCursor(ej.getCursorBlink(),cn+er-1,es+co-1,ej.getTextColor())end end end end end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if ek~=nil then if not ek:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,aL,c5,c6,c7,c8)if ek==nil then return end;if not ek:isDead()then if not el then if aL~="mouse_click"and aL~="monitor_touch"and aL~="mouse_up"and aL~="mouse_scroll"and aL~="mouse_drag"and aL~="key_up"and aL~="key"and aL~="char"and aL~="terminate"then ek:resume(aL,c5,c6,c7,c8)end;if self:isFocused()then local cn,co=self:getAnchorPosition()local er,es=ej.getCursorPos()if self.parent~=nil then if cn+er-1>=1 and cn+er-1<=cn+self.width-1 and es+co-1>=1 and es+co-1<=co+self.height-1 then self.parent:setCursor(ej.getCursorBlink(),cn+er-1,es+co-1,ej.getTextColor())end end;if aL=="terminate"and self:isFocused()then self:stop()end end else if aL~="mouse_click"and aL~="monitor_touch"and aL~="mouse_up"and aL~="mouse_scroll"and aL~="mouse_drag"and aL~="key_up"and aL~="key"and aL~="char"and aL~="terminate"then table.insert(em,{event=aL,args={c5,c6,c7,c8}})end end end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()ej.basalt_reposition(cn,co)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)ej.basalt_update()end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function et(bF)local cj=bE(bF)local bG="Progressbar"local eu=0;cj:setZIndex(5)cj:setValue(false)cj.width=25;cj.height=1;cj.bgColor=h.CheckboxBG;cj.fgColor=h.CheckboxFG;local ev=colors.black;local ew=""local ex=colors.white;local ey=""local ez=0;local bO={getType=function(self)return bG end,setDirection=function(self,eA)ez=eA;return self end,setProgressBar=function(self,bW,aD,eB)ev=bW or ev;ew=aD or ew;ex=eB or ex;return self end,setBackgroundSymbol=function(self,aD)ey=aD:sub(1,1)return self end,setProgress=function(self,aP)if aP>=0 and aP<=100 and eu~=aP then eu=aP;self:setValue(eu)if eu==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return eu end,onProgressDone=function(self,x)self:registerEvent("progress_done",x)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done")end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height,ey)if ez==1 then self.parent:drawBackgroundBox(cn,co,self.width,self.height/100*eu,ev)self.parent:drawForegroundBox(cn,co,self.width,self.height/100*eu,ex)self.parent:drawTextBox(cn,co,self.width,self.height/100*eu,ew)elseif ez==2 then self.parent:drawBackgroundBox(cn,co+math.ceil(self.height-self.height/100*eu),self.width,self.height/100*eu,ev)self.parent:drawForegroundBox(cn,co+math.ceil(self.height-self.height/100*eu),self.width,self.height/100*eu,ex)self.parent:drawTextBox(cn,co+math.ceil(self.height-self.height/100*eu),self.width,self.height/100*eu,ew)elseif ez==3 then self.parent:drawBackgroundBox(cn+math.ceil(self.width-self.width/100*eu),co,self.width/100*eu,self.height,ev)self.parent:drawForegroundBox(cn+math.ceil(self.width-self.width/100*eu),co,self.width/100*eu,self.height,ex)self.parent:drawTextBox(cn+math.ceil(self.width-self.width/100*eu),co,self.width/100*eu,self.height,ew)else self.parent:drawBackgroundBox(cn,co,self.width/100*eu,self.height,ev)self.parent:drawForegroundBox(cn,co,self.width/100*eu,self.height,ex)self.parent:drawTextBox(cn,co,self.width/100*eu,self.height,ew)end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eC(bF)local cj=bE(bF)local bG="Radio"cj.width=8;cj.bgColor=h.listBG;cj.fgColor=h.listFG;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local eD=cj.bgColor;local eE=cj.fgColor;local cv=true;local aD="\7"local cw="left"local bO={getType=function(self)return bG end,addItem=function(self,ar,ap,aq,aB,aC,...)table.insert(cs,{x=ap or 1,y=aq or 1,text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})if#cs==1 then self:setValue(cs[1])end;return self end,getAll=function(self)return cs end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,ap,aq,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{x=ap or 1,y=aq or 1,text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,eF,eG,cF)ct=aB or ct;cu=aC or cu;eD=eF or eD;eE=eG or eE;cv=cF;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then if#cs>0 then for aO,aP in pairs(cs)do if cn+aP.x-1<=ap and cn+aP.x-1+aP.text:len()+2>=ap and co+aP.y-1==aq then self:setValue(aP)if self.parent~=nil then self.parent:setFocusedObject(self)end;self:setVisualChanged()return true end end end end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()for aO,aP in pairs(cs)do if aP==self:getValue()then if cw=="left"then self.parent:writeText(aP.x+cn-1,aP.y+co-1,aD,eD,eE)self.parent:writeText(aP.x+2+cn-1,aP.y+co-1,aP.text,ct,cu)end else self.parent:drawBackgroundBox(aP.x+cn-1,aP.y+co-1,1,1,self.bgColor)self.parent:writeText(aP.x+2+cn-1,aP.y+co-1,aP.text,aP.bgCol,aP.fgCol)end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eH(bF)local cj=bE(bF)local bG="Scrollbar"cj.width=1;cj.height=8;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(1)cj:setZIndex(2)local eI="vertical"local aD=" "local eJ=colors.black;local eK="\127"local eL=cj.height;local aK=1;local eM=1;local bO={getType=function(self)return bG end,setSymbol=function(self,eN)aD=eN:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,u)eM=tonumber(u)or 1;if eI=="vertical"then self:setValue(aK-1*eL/(self.height-(eM-1))-eL/(self.height-(eM-1)))elseif eI=="horizontal"then self:setValue(aK-1*eL/(self.width-(eM-1))-eL/(self.width-(eM-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,cG)eL=cG;return self end,setBackgroundSymbol=function(self,eO)eK=string.sub(eO,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eP)eJ=eP;self:setVisualChanged()return self end,setBarType=function(self,eQ)eI=eQ:lower()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if eI=="horizontal"then for eR=0,self.width do if cn+eR==ap and co<=aq and co+self.height>aq then aK=math.min(eR+1,self.width-(eM-1))self:setValue(eL/self.width*aK)self:setVisualChanged()end end end;if eI=="vertical"then for eR=0,self.height do if co+eR==aq and cn<=ap and cn+self.width>ap then aK=math.min(eR+1,self.height-(eM-1))self:setValue(eL/self.height*aK)self:setVisualChanged()end end end end;if aL=="mouse_scroll"then aK=aK+c2;if aK<1 then aK=1 end;aK=math.min(aK,(eI=="vertical"and self.height or self.width)-(eM-1))self:setValue(eL/(eI=="vertical"and self.height or self.width)*aK)end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()if eI=="horizontal"then self.parent:writeText(cn,co,eK:rep(aK-1),self.bgColor,self.fgColor)self.parent:writeText(cn+aK-1,co,aD:rep(eM),eJ,eJ)self.parent:writeText(cn+aK+eM-1,co,eK:rep(self.width-(aK+eM-1)),self.bgColor,self.fgColor)end;if eI=="vertical"then for ag=0,self.height-1 do if aK==ag+1 then for eS=0,math.min(eM-1,self.height)do self.parent:writeText(cn,co+ag+eS,aD,eJ,eJ)end else if ag+1aK-1+eM then self.parent:writeText(cn,co+ag,eK,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eT(bF)local cj=bE(bF)local bG="Slider"cj.width=8;cj.height=1;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(1)local eI="horizontal"local aD=" "local eJ=colors.black;local eK="\140"local eL=cj.width;local aK=1;local eM=1;local bO={getType=function(self)return bG end,setSymbol=function(self,eN)aD=eN:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,u)eM=tonumber(u)or 1;if eI=="vertical"then self:setValue(aK-1*eL/(self.height-(eM-1))-eL/(self.height-(eM-1)))elseif eI=="horizontal"then self:setValue(aK-1*eL/(self.width-(eM-1))-eL/(self.width-(eM-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,cG)eL=cG;return self end,setBackgroundSymbol=function(self,eO)eK=string.sub(eO,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eP)eJ=eP;self:setVisualChanged()return self end,setBarType=function(self,eQ)eI=eQ:lower()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if eI=="horizontal"then for eR=0,self.width do if cn+eR==ap and co<=aq and co+self.height>aq then aK=math.min(eR+1,self.width-(eM-1))self:setValue(eL/self.width*aK)self:setVisualChanged()end end end;if eI=="vertical"then for eR=0,self.height do if co+eR==aq and cn<=ap and cn+self.width>ap then aK=math.min(eR+1,self.height-(eM-1))self:setValue(eL/self.height*aK)self:setVisualChanged()end end end end;if aL=="mouse_scroll"then aK=aK+c2;if aK<1 then aK=1 end;aK=math.min(aK,(eI=="vertical"and self.height or self.width)-(eM-1))self:setValue(eL/(eI=="vertical"and self.height or self.width)*aK)end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()if eI=="horizontal"then self.parent:writeText(cn,co,eK:rep(aK-1),self.bgColor,self.fgColor)self.parent:writeText(cn+aK-1,co,aD:rep(eM),eJ,eJ)self.parent:writeText(cn+aK+eM-1,co,eK:rep(self.width-(aK+eM-1)),self.bgColor,self.fgColor)end;if eI=="vertical"then for ag=0,self.height-1 do if aK==ag+1 then for eS=0,math.min(eM-1,self.height)do self.parent:writeText(cn,co+ag+eS,aD,eJ,eJ)end else if ag+1aK-1+eM then self.parent:writeText(cn,co+ag,eK,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eU(bF)local cj=bE(bF)local bG="Switch"cj.width=2;cj.height=1;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(false)cj:setZIndex(5)local eK=colors.black;local eV=colors.red;local eW=colors.green;local bO={getType=function(self)return bG end,setSymbolColor=function(self,eJ)eK=eJ;self:setVisualChanged()return self end,setActiveBackground=function(self,ei)eW=ei;self:setVisualChanged()return self end,setInactiveBackground=function(self,ei)eV=ei;self:setVisualChanged()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then self:setValue(not self:getValue())end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)if self:getValue()then self.parent:drawBackgroundBox(cn,co,1,self.height,eW)self.parent:drawBackgroundBox(cn+1,co,1,self.height,eK)else self.parent:drawBackgroundBox(cn,co,1,self.height,eK)self.parent:drawBackgroundBox(cn+1,co,1,self.height,eV)end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eX(bF)local cj=bE(bF)local bG="Textfield"local eY,cT,cS,eZ=1,1,1,1;local e_={""}local f0={[colors.purple]={"break"}}cj.width=20;cj.height=8;cj.bgColor=h.textfieldBG;cj.fgColor=h.textfieldFG;cj:setZIndex(5)local bO={getType=function(self)return bG end,getLines=function(self)return e_ end,getLine=function(self,aK)return e_[aK]or""end,editLine=function(self,aK,ar)e_[aK]=ar or e_[aK]return self end,addLine=function(self,ar,aK)if aK~=nil then table.insert(e_,aK,ar)else table.insert(e_,ar)end;return self end,addKeyword=function(self,f1,bW)end,removeLine=function(self,aK)table.remove(e_,aK or#e_)if#e_<=0 then table.insert(e_,"")end;return self end,getTextCursor=function(self)return cS,eZ end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then local cn,co=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,cn+cS-cT,co+eZ-eY,self.fgColor)end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,aL,bp)if cj.keyHandler(self,aL,bp)then local cn,co=self:getAnchorPosition()if aL=="key"then if bp==keys.backspace then if e_[eZ]==""then if eZ>1 then table.remove(e_,eZ)cS=e_[eZ-1]:len()+1;cT=cS-self.width+1;if cT<1 then cT=1 end;eZ=eZ-1 end elseif cS<=1 then if eZ>1 then cS=e_[eZ-1]:len()+1;cT=cS-self.width+1;if cT<1 then cT=1 end;e_[eZ-1]=e_[eZ-1]..e_[eZ]table.remove(e_,eZ)eZ=eZ-1 end else e_[eZ]=e_[eZ]:sub(1,cS-2)..e_[eZ]:sub(cS,e_[eZ]:len())if cS>1 then cS=cS-1 end;if cT>1 then if cSe_[eZ]:len()then if e_[eZ+1]~=nil then e_[eZ]=e_[eZ]..e_[eZ+1]table.remove(e_,eZ+1)end else e_[eZ]=e_[eZ]:sub(1,cS-1)..e_[eZ]:sub(cS+1,e_[eZ]:len())end end;if bp==keys.enter then table.insert(e_,eZ+1,e_[eZ]:sub(cS,e_[eZ]:len()))e_[eZ]=e_[eZ]:sub(1,cS-1)eZ=eZ+1;cS=1;cT=1;if eZ-eY>=self.height then eY=eY+1 end;self:setValue("")end;if bp==keys.up then if eZ>1 then eZ=eZ-1;if cS>e_[eZ]:len()+1 then cS=e_[eZ]:len()+1 end;if cT>1 then if cS1 then if eZe_[eZ]:len()+1 then cS=e_[eZ]:len()+1 end;if eZ>=eY+self.height then eY=eY+1 end end end;if bp==keys.right then cS=cS+1;if eZ<#e_ then if cS>e_[eZ]:len()+1 then cS=1;eZ=eZ+1 end elseif cS>e_[eZ]:len()then cS=e_[eZ]:len()+1 end;if cS<1 then cS=1 end;if cS=self.width+cT then cT=cS-self.width+1 end;if cT<1 then cT=1 end end;if bp==keys.left then cS=cS-1;if cS>=1 then if cS=self.width+cT then cT=cS end end;if eZ>1 then if cS<1 then eZ=eZ-1;cS=e_[eZ]:len()+1;cT=cS-self.width+1 end end;if cS<1 then cS=1 end;if cT<1 then cT=1 end end end;if aL=="char"then e_[eZ]=e_[eZ]:sub(1,cS-1)..bp..e_[eZ]:sub(cS,e_[eZ]:len())cS=cS+1;if cS>=self.width+cT then cT=cT+1 end;self:setValue("")end;local d4=(cS<=e_[eZ]:len()and cS-1 or e_[eZ]:len())-(cT-1)if d4>self.x+self.width-1 then d4=self.x+self.width-1 end;local f2=eZ-eYe_[eZ]:len()then cS=e_[eZ]:len()+1 end;if cSe_[eZ]:len()then cS=e_[eZ]:len()+1 end;if cS#e_-(self.height-1)then eY=#e_-(self.height-1)end;if eY<1 then eY=1 end;if self.parent~=nil then if cn+cS-cT>=cn and cn+cS-cT<=cn+self.width and(co+eZ-eY>=co and co+eZ-eY<=co+self.height)then self.parent:setCursor(true,f3+cS-cT,f4+eZ-eY)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)for ag=1,self.height do local ar=""if e_[ag+eY-1]~=nil then ar=e_[ag+eY-1]end;ar=ar:sub(cT,self.width+cT-1)local d5=self.width-ar:len()if d5<0 then d5=0 end;ar=ar..string.rep(" ",d5)self.parent:setText(cn,co+ag-1,ar)end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function f5(bF)local bO;local bG="Thread"local aN;local f6;local f7=false;bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,x)if x==nil then error("Function provided to thread is nil")end;aN=x;f6=coroutine.create(aN)f7=true;local aX,aY=coroutine.resume(f6)if not aX then if aY~="Terminated"then error("Thread Error Occurred - "..aY)end end;return self end,getStatus=function(self,x)if f6~=nil then return coroutine.status(f6)end;return nil end,stop=function(self,x)f7=false;return self end,eventHandler=function(self,aL,c5,c6,c7)if f7 then if coroutine.status(f6)~="dead"then local aX,aY=coroutine.resume(f6,aL,c5,c6,c7)if not aX then if aY~="Terminated"then error("Thread Error Occurred - "..aY)end end else f7=false end end end}bO.__index=bO;return bO end;local function f8(bF)local bG="Timer"local f9=0;local fa=0;local fb=0;local ca;local bN=aI()local fc=false;local bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,fd,fe)f9=fd or 0;fa=fe or 1;return self end,start=function(self)if fc then os.cancelTimer(ca)end;fb=fa;ca=os.startTimer(f9)fc=true;return self end,isActive=function(self)return fc end,cancel=function(self)if ca~=nil then os.cancelTimer(ca)end;fc=false;return self end,onCall=function(self,aN)bN:registerEvent("timed_event",aN)return self end,eventHandler=function(self,aL,ch)if aL=="timer"and ch==ca and fc then bN:sendEvent("timed_event",self)if fb>=1 then fb=fb-1;if fb>=1 then ca=os.startTimer(f9)end elseif fb==-1 then ca=os.startTimer(f9)end end end}bO.__index=bO;return bO end;local function ff(bF,fg)local cj=bE(bF)local bG="Frame"local fh={}local fi={}local bO={}local fj;local fk=e;local fl={}local fm=false;cj:setZIndex(10)local aA=a3(fk)local dz=false;local dw=1;local dx=1;local fn=colors.white;local fo,cx=0,0;if fg~=nil then cj.parent=fg;cj.width,cj.height=fg:getSize()cj.bgColor=h.FrameBG;cj.fgColor=h.FrameFG else cj.width,cj.height=fk.getSize()cj.bgColor=h.basaltBG;cj.fgColor=h.basaltFG end;local function fp(bF)for aO,aP in pairs(fh)do for aO,br in pairs(aP)do if br.name==bF then return aP end end end end;local function fq(fr)local bH=fr:getZIndex()if fp(fr.name)~=nil then return nil end;if fh[bH]==nil then for ap=1,#fi+1 do if fi[ap]~=nil then if bH==fi[ap]then break end;if bH>fi[ap]then table.insert(fi,ap,bH)break end else table.insert(fi,bH)end end;if#fi<=0 then table.insert(fi,bH)end;fh[bH]={}end;fr.parent=bO;table.insert(fh[bH],fr)return fr end;local function fs(fr)for bq,br in pairs(fh)do for bp,aP in pairs(br)do if aP==fr then table.remove(fh[bq],bp)return true end end end;return false end;bO={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return bG end,setFocusedObject=function(self,fr)for aO,aK in pairs(fi)do for aO,aP in pairs(fh[aK])do if aP==fr then if fj~=nil then fj:loseFocusHandler()end;fj=fr;fj:getFocusHandler()end end end;return self end,setOffset=function(self,b_,c0)fo=b_~=nil and math.floor(b_<0 and math.abs(b_)or-b_)or fo;cx=c0~=nil and math.floor(c0<0 and math.abs(c0)or-c0)or cx;return self end,getFrameOffset=function(self)return fo,cx end,removeFocusedObject=function(self)if fj~=nil then fj:loseFocusHandler()end;fj=nil;return self end,getFocusedObject=function(self)return fj end,show=function(self)cj:show()if self.parent==nil and not fm then b=self end;return self end,setCursor=function(self,ft,fu,fv,bW)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())dz=ft or false;if fu~=nil then dw=cn+fu-1 end;if fv~=nil then dx=co+fv-1 end;fn=bW or fn;self:setVisualChanged()return self end,setMoveable=function(self,fw)self.isMoveable=fw or not self.isMoveable;self:setVisualChanged()return self end,addMonitor=function(self,fx)local fy=peripheral.wrap(fx)fl[fx]={monitor=fx,frame=a.createFrame(self:getName().."_monitor_"..fx)}fl[fx].frame:setDisplay(fy):setFrameAsMonitor()fl[fx].frame:setSize(fy:getSize())return fl[fx].frame end,setMonitorScale=function(self,fz,fA)if fm then fk.setTextScale(fz*0.5)if fA then self:setSize(fk:getSize())end end;return self,fm end,setFrameAsMonitor=function(self,fB)fm=fB;if fB==nil then fm=true end;return self end,showBar=function(self,fC)self.barActive=fC or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,ar,aB,aC)self.barText=ar or""self.barBackground=aB or self.barBackground;self.barTextcolor=aC or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,cw)self.barTextAlign=cw or"left"self:setVisualChanged()return self end,setDisplay=function(self,a4)fk=a4;aA=a3(fk)return self end,getDisplay=function(self)return fk end,getVisualChanged=function(self)local fD=cj.getVisualChanged(self)for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.getVisualChanged~=nil and aP:getVisualChanged()then fD=true end end end end;return fD end,loseFocusHandler=function(self)cj.loseFocusHandler(self)end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,aL,bp)if fj~=nil then if fj.keyHandler~=nil then if fj:keyHandler(aL,bp)then return true end end end;return false end,backgroundKeyHandler=function(self,aL,bp)cj.backgroundKeyHandler(self,aL,bp)for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.backgroundKeyHandler~=nil then aP:backgroundKeyHandler(aL,bp)end end end end end,eventHandler=function(self,aL,c5,c6,c7,c8)cj.eventHandler(self,aL,c5,c6,c7,c8)for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.eventHandler~=nil then aP:eventHandler(aL,c5,c6,c7,c8)end end end end;if aL=="terminate"then fk.clear()fk.setCursorPos(1,1)a.stop()end end,mouseClickHandler=function(self,aL,c2,ap,aq)local b_,c0=self:getOffset()b_=b_<0 and math.abs(b_)or-b_;c0=c0<0 and math.abs(c0)or-c0;if self.drag then if aL=="mouse_drag"then local fE=1;local fF=1;if self.parent~=nil then fE,fF=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(ap+self.xToRem-(fE-1)+b_,aq-(fF-1)+c0)end;if aL=="mouse_up"then self.drag=false end;return true end;if cj.mouseClickHandler(self,aL,c2,ap,aq)then local bX,bY=self:getAbsolutePosition(self:getAnchorPosition())if aL~="monitor_touch"or fm then for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in b4(fh[aK])do if aP.mouseClickHandler~=nil then if aP:mouseClickHandler(aL,c2,ap+b_,aq+c0)then return true end end end end end elseif not fm then for aO,dr in pairs(fl)do if c2==dr.monitor then dr.frame:mouseClickHandler(aL,c2,ap,aq)end end end;if self.isMoveable then if ap>=bX and ap<=bX+self.width-1 and aq==bY and aL=="mouse_click"then self.drag=true;self.xToRem=bX-ap end end;if fj~=nil then fj:loseFocusHandler()fj=nil end;return true end;return false end,setText=function(self,ap,aq,ar)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setText(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(ar,math.max(1-ap+1,1),self.width-ap+1))else aA.setText(math.max(ap+cn-1,cn),co+aq-1,f(ar,math.max(1-ap+1,1),self.width-ap+1))end end end,setBG=function(self,ap,aq,aB)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setBG(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(aB,math.max(1-ap+1,1),self.width-ap+1))else aA.setBG(math.max(ap+cn-1,cn),co+aq-1,f(aB,math.max(1-ap+1,1),self.width-ap+1))end end end,setFG=function(self,ap,aq,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setFG(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(aC,math.max(1-ap+1,1),self.width-ap+1))else aA.setFG(math.max(ap+cn-1,cn),co+aq-1,f(aC,math.max(1-ap+1,1),self.width-ap+1))end end end,writeText=function(self,ap,aq,ar,aB,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:writeText(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(ar,math.max(1-ap+1,1),self.width-ap+1),aB,aC)else aA.writeText(math.max(ap+cn-1,cn),co+aq-1,f(ar,math.max(1-ap+1,1),self.width-ap+1),aB,aC)end end end,drawBackgroundBox=function(self,ap,aq,a6,m,aB)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawBackgroundBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aB)else aA.drawBackgroundBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aB)end end,drawTextBox=function(self,ap,aq,a6,m,aD)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawTextBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aD:sub(1,1))else aA.drawTextBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aD:sub(1,1))end end,drawForegroundBox=function(self,ap,aq,a6,m,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawForegroundBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aC)else aA.drawForegroundBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aC)end end,draw=function(self)for aO,dr in pairs(fl)do dr.frame:draw()end;if self:getVisualChanged()then if cj.draw(self)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())local f3,f4=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(f3,f4,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(f3,f4,self.width,self.height,self.fgColor)self.parent:drawTextBox(f3,f4,self.width,self.height," ")else aA.drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)aA.drawForegroundBox(cn,co,self.width,self.height,self.fgColor)aA.drawTextBox(cn,co,self.width,self.height," ")end;fk.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(f3,f4,aZ(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)else aA.writeText(cn,co,aZ(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)end end;for aO,aK in b4(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.draw~=nil then aP:draw()end end end end;if dz then fk.setTextColor(fn)fk.setCursorPos(dw,dx)if self.parent~=nil then fk.setCursorBlink(self:isFocused())else fk.setCursorBlink(dz)end end;self:setVisualChanged(false)end end end,drawUpdate=function(self)aA.update()for fG,dr in pairs(fl)do dr.frame:drawUpdate()end end,addObject=function(self,fr)return fq(fr)end,removeObject=function(self,fr)return fs(fr)end,getObject=function(self,fr)return fp(fr)end,addButton=function(self,bF)local fr=ci(bF)fr.name=bF;return fq(fr)end,addLabel=function(self,bF)local fr=d6(bF)fr.bgColor=self.bgColor;fr.fgColor=self.fgColor;return fq(fr)end,addCheckbox=function(self,bF)local fr=cq(bF)return fq(fr)end,addInput=function(self,bF)local fr=cP(bF)return fq(fr)end,addProgram=function(self,bF)local fr=du(bF)return fq(fr)end,addTextfield=function(self,bF)local fr=eX(bF)return fq(fr)end,addList=function(self,bF)local fr=dg(bF)fr.name=nam;return fq(fr)end,addDropdown=function(self,bF)local fr=cr(bF)return fq(fr)end,addRadio=function(self,bF)local fr=eC(bF)return fq(fr)end,addTimer=function(self,bF)local fr=f8(bF)return fq(fr)end,addAnimation=function(self,bF)local fr=c9(bF)return fq(fr)end,addSlider=function(self,bF)local fr=eT(bF)return fq(fr)end,addScrollbar=function(self,bF)local fr=eH(bF)return fq(fr)end,addMenubar=function(self,bF)local fr=dj(bF)return fq(fr)end,addThread=function(self,bF)local fr=f5(bF)return fq(fr)end,addPane=function(self,bF)local fr=dt(bF)return fq(fr)end,addImage=function(self,bF)local fr=cH(bF)return fq(fr)end,addProgressbar=function(self,bF)local fr=et(bF)return fq(fr)end,addSwitch=function(self,bF)local fr=eU(bF)return fq(fr)end,addFrame=function(self,bF)local fr=ff(bF,self)return fq(fr)end}setmetatable(bO,cj)if fg==nil then table.insert(c,bO)end;return bO end;local fH=false;local function fI(aL,c5,c6,c7,c8)if aL=="mouse_click"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_drag"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_up"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_scroll"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="monitor_touch"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="key"or aL=="char"then b:keyHandler(aL,c5)b:backgroundKeyHandler(aL,c5)end;if aL=="key"then d[c5]=true end;if aL=="key_up"then d[c5]=false end;for aO,aP in pairs(c)do aP:eventHandler(aL,c5,c6,c7,c8)end;if fH then b:draw()b:drawUpdate()end end;function a.autoUpdate(f7)e.clear()fH=f7 or true;b:draw()b:drawUpdate()while fH do local aL,c5,c6,c7,c8=os.pullEventRaw()fI(aL,c5,c6,c7,c8)end end;function a.update(aL,c5,c6,c7,c8)if aL~=nil then fI(aL,c5,c6,c7,c8)else b:draw()b:drawUpdate()end end;function a.stop()fH=false end;function a.isKeyDown(bp)if d[bp]==nil then return false end;return d[bp]end;function a.getFrame(bF)for aO,aP in pairs(c)do if aP.name==bF then return aP end end end;function a.getActiveFrame()return b end;function a.setActiveFrame(bP)if bP:getType()=="Frame"then b=bP;return true end;return false end;function a.createFrame(bF)return ff(bF)end;function a.removeFrame(bF)for bp,aP in pairs(c)do if aP.name==bF then c[bp]=nil;return true end end;return false end;if a.debugger then a.debugFrame=a.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug",colors.black,colors.gray)a.debugList=a.debugFrame:addList("debugList"):setSize(a.debugFrame.width-2,a.debugFrame.height-3):setPosition(2,3):setScrollable(true):show()a.debugFrame:addButton("back"):setAnchor("right"):setSize(1,1):setText("\22"):onClick(function()a.oldFrame:show()end):setBackground(colors.red):show()a.debugLabel=a.debugFrame:addLabel("debugLabel"):onClick(function()a.oldFrame=b;a.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):setZIndex(20):show()end;if a.debugger then function a.debug(...)local aV={...}if b.name~="basaltDebuggingFrame"then if b~=a.debugLabel.frame then a.debugLabel:setParent(b)end end;local fJ=""for bp,aP in pairs(aV)do fJ=fJ..tostring(aP)..(#aV~=bp and", "or"")end;a.debugLabel:setText("[Debug] "..fJ)a.debugList:addItem(fJ)if a.debugList:getItemCount()>50 then a.debugList:removeItem(1)end;a.debugList:setValue(a.debugList:getItem(a.debugList:getItemCount()))if a.debugList.getItemCount()>a.debugList:getHeight()then a.debugList:setIndexOffset(a.debugList:getItemCount()-a.debugList:getHeight())end;a.debugLabel:show()end end;return a \ No newline at end of file diff --git a/docs/Home.md b/docs/Home.md index 7066497..52cb1ea 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -1,24 +1,24 @@ -# Welcome to The Basalt Wiki!
+# Welcome to The Basalt Wiki! -_Note: The Basalt Wiki is a work in progress. Please treat Wiki errors the same as bugs and report them accordingly._ +*Note: The Basalt Wiki is a work in progress. Please treat Wiki errors the same as bugs and report them accordingly.* Here you can find information about how to use Basalt as well as examples of functional Basalt code. The aim of Basalt is to improve user interaction through visual display. ## About Basalt -Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (AKA Computer Craft: Tweaked) - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's home page. -

+Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also know as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://www.curseforge.com/minecraft/mc-mods/cc-tweaked). ## Quick Demo ![Preview](https://media0.giphy.com/media/fvmNPshXKeU7FFA9iA/giphy.gif) -

## Questions & Bugs -Obviously I've implemented some easter eggs, _some people_ call them "bugs". If you happen to discover one of these just make a new issue. +Obviously NyoriE has implemented some easter eggs, *some people* call them "bugs". If you happen to discover one of these just make a new issue. -Additionally, if you have questions about Basalt or how to make use of it, feel free to create a new discussion on Basalt's Discussion Board. +Additionally, if you have questions about Basalt or how to make use of it, feel free to create a new discussion on Basalt's Discussion Board, or ask in our [discord](https://discord.gg/yNNnmBVBpE). -You may also message me on Discord: NyoriE#8206 +--- + +Feel free to join our [discord](https://discord.gg/yNNnmBVBpE)!

\ No newline at end of file diff --git a/docs/_media/installer.png b/docs/_media/installer.png new file mode 100644 index 0000000..dcdd535 Binary files /dev/null and b/docs/_media/installer.png differ diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 26b9778..67de1ec 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -3,7 +3,7 @@ - [Quick Start](home/Quick-Start.md) - [Installer](home/installer) - Objects - - [Animation](objects/Animation.md) + - [Object](objects/Object) - [Basalt](objects/Basalt) - [Button](objects/Button) - [Checkbox](objects/Checkbox) @@ -14,16 +14,18 @@ - [Label](objects/Label) - [List](objects/List) - [Menubar](objects/Menubar) - - [Object](objects/Object) - [Pane](objects/Pane) - [Program](objects/Program) - [Radio](objects/Radio) - [Scrollbar](objects/Scrollbar) - [Slider](objects/Slider) - [Text Field](objects/Textfield) + - [Animation](objects/Animation.md) - [Thread](objects/Thread) - [Timer](objects/Timer) - +- Events + - [Mouse Events](events/mouseEvents.md) - Tips & Tricks - [Component Logic](tips/logic) - - [Changing Button Color](tips/buttons) \ No newline at end of file + - [Changing Button Color](tips/buttons) + - [Advanced usage of Events](tips/events.md) diff --git a/docs/events/mouseEvents.md b/docs/events/mouseEvents.md new file mode 100644 index 0000000..d113114 --- /dev/null +++ b/docs/events/mouseEvents.md @@ -0,0 +1,63 @@ +Here we will talk about mouse events and how you can manipulate them. There are 2 possible mouse events you can add to almost every visual object. + +# onClick +`onClick(self, button, x, y)`
+The computercraft event which triggers this method is `mouse_click` and `monitor_touch`. +Any visual object can register onClick events. + +Here is a example on how to add a onClick event to your button: + +```lua +local basalt = dofile("basalt.lua") + +local mainFrame = basalt.createFrame("myMainFrame"):show() +local button = mainFrame:addButton("myButton"):setPosition(3,3):setSize(12,3):setText("Click"):show() + +function buttonOnClick() + basalt.debug("Button got clicked!") +end +button:onClick(buttonOnClick()) +``` + +# onClickUp +`onClickUp(self, button, x, y)`
+The computercraft event which triggers this method is `mouse_up`. +Any visual object can register onClickUp events. + +Here is a example on how to add a onClickUp event to your button: + +```lua +local basalt = dofile("basalt.lua") + +local mainFrame = basalt.createFrame("myMainFrame"):show() +local button = mainFrame:addButton("myButton"):setPosition(3,3):setSize(12,3):setText("Click"):show() + +function buttonOnClick() + basalt.debug("Button got clicked!") +end +button:onClick(buttonOnClick) + +function buttonOnRelease() + basalt.debug("Button got released!") +end +button:onClickUp(buttonOnRelease) +``` + +# onScroll +`onScroll(self, direction, x, y)`
+The computercraft event which triggers this method is `mouse_scroll`. +Any visual object can register a onScroll events. + +Here is a example on how to add a onScroll event to your button: + +```lua +local basalt = dofile("basalt.lua") + +local mainFrame = basalt.createFrame("myMainFrame"):show() +local button = mainFrame:addButton("myButton"):setPosition(3,3):setSize(12,3):setText("Click"):show() + +function buttonOnScroll() + basalt.debug("Someone scrolls on me!") +end +button:onScroll(buttonOnScroll) +``` diff --git a/docs/favicon-16x16.png b/docs/favicon-16x16.png new file mode 100644 index 0000000..222b2e0 Binary files /dev/null and b/docs/favicon-16x16.png differ diff --git a/docs/favicon-32x32.png b/docs/favicon-32x32.png new file mode 100644 index 0000000..64a8256 Binary files /dev/null and b/docs/favicon-32x32.png differ diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000..c45aaee Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/home/gettingStarted.md b/docs/home/gettingStarted.md deleted file mode 100644 index b7c497f..0000000 --- a/docs/home/gettingStarted.md +++ /dev/null @@ -1,71 +0,0 @@ -# Getting Started! - -Basalt aims to be a relatively small, easy to use framework. - -Accordingly, we have provided an installation script. - - -Just use the following command in any CC:Tweaked shell: - -`wget https://github.com/Pyroxenium/Basalt/raw/master/basalt.lua basalt.lua` - -This will download `basalt.lua` to your local directory. - -To load the framework, make use of the following snippet: -```lua ---> For those who are unfamiliar with lua, dofile executes the code in the referenced file -local basalt = dofile("basalt.lua") -``` - - -Here is a fully functioning example of Basalt code: - -```lua -local basalt = dofile("basalt.lua") --> Load the Basalt framework - ---> Create the first frame. Please note that Basalt needs at least one active "non-parent" frame to properly supply events ---> When Basalt#createFrame makes use of unique identifiers (commonly referred to as UIDs), meaning that the supplied value must be UNIQUE ---> If the supplied UID is ambiguous, Basalt#createFrame returns a nil value -local mainFrame = basalt.createFrame("mainFrame") - ---> Show the frame to the user -mainFrame:show() - -local button = mainFrame:addButton("clickableButton") --> Add a button to the mainFrame (With a unique identifier) - ---> Set the position of the button, Button#setPosition follows an x, y pattern. ---> The x value is how far right the object should be from its anchor (negative values from an anchor will travel left) ---> The y value is how far down the object should be from its anchor (negative values from an anchor will travel up) -button:setPosition(4, 4) - -button:setText("Click me!") --> Set the text of our button - -local function buttonClick() --> This function serves as our click logic - basalt.debug("I got clicked!") -end - ---> Remember! You cannot supply buttonClick(), that will only supply the result of the function ---> Make sure the button knows which function to call when it's clicked -button:onClick(buttonClick) - -button:show() --> Make the button visible, so the user can click it - -basalt.autoUpdate() --> Basalt#autoUpdate starts the event listener to detect user input -``` -If you're like us and strive for succinct and beautiful code, here is a cleaner implementation of the code above: -```lua -local basalt = dofile("basalt.lua") - -local mainFrame = basalt.createFrame("mainFrame"):show() -local button = mainFrame --> Basalt returns an instance of the object on most methods, to make use of "call-chaining" - :addButton("clickableButton") --> This is an example of call chaining - :setPosition(4,4) - :setText("Click me!") - :onClick( - function() - basalt.debug("I got clicked!") - end) - :show() - -basalt.autoUpdate() -``` diff --git a/docs/home/installer.md b/docs/home/installer.md index c252fde..cddd247 100644 --- a/docs/home/installer.md +++ b/docs/home/installer.md @@ -1,10 +1,21 @@ # Installer -This is just a script which helps you to install basalt.lua, if it's not already on the computer. Means, you create your program (which requires basalt) and add this on the top of your program. Now, everytime you execute your program it checks if basalt.lua exists or not. +This is just a script which helps you to setup your program to automatically install the Basalt UI Framework, if it doesn't exists. Means, you create your program (which requires basalt) and add this on the top of your program. Now, everytime you execute your program it checks if basalt.lua (or your custom filepath) exists or not, if not it installs it, or if you are using the advanced installer, it asks the user if the program is allowed to install basalt for you. -## Visual Installer +## Basic Installer +Here is a very basic one which just installs basalt.lua if don't exist: +```lua +--Basalt configurated installer +local filePath = "basalt.lua" --here you can change the file path default: basalt.lua +if not(fs.exists(filePath))then + shell.run("pastebin run ESs1mg7P "..filePath) -- this is an alternative to the wget command +end +local basalt = dofile(filePath) -- here you can change the variablename in any variablename you want default: basalt +``` + +## Advanced Installer This is a visual version, it asks the user if he wants to install basalt.lua (if not found)
-![](https://i.imgur.com/b4Ys7FB.png) +![](https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/installer.png) ```lua --Basalt configurated installer local filePath = "basalt.lua" --here you can change the file path default: basalt.lua @@ -40,12 +51,12 @@ if not(fs.exists(filePath))then local event, p1,p2,p3,p4 = os.pullEvent() if(event=="mouse_click")then if(p3==math.floor(h/2+2))and(p2>=w/2-8)and(p2<=w/2-2)then - shell.run("pastebin run ESs1mg7P") -- this is an alternative to the wget command + shell.run("pastebin run ESs1mg7P "..filePath) _installerWindow.setVisible(false) term.clear() break end - if(p3==h/2+2)and(p2<=w/2+9)and(p2>=w/2+4)then + if(p3==math.floor(h/2+2))and(p2<=w/2+9)and(p2>=w/2+4)then _installerWindow.clear() _installerWindow.setVisible(false) term.setCursorPos(1,1) @@ -59,16 +70,5 @@ if not(fs.exists(filePath))then end local basalt = dofile(filePath) -- here you can change the variablename in any variablename you want default: basalt +------------------------------ ``` - -## Basic Installer -Here is a very basic one which just installs basalt.lua if don't exist: -```lua ---Basalt configurated installer -local filePath = "basalt.lua" --here you can change the file path default: basalt.lua -if not(fs.exists(filePath))then - shell.run("wget https://github.com/Pyroxenium/Basalt/raw/master/basalt.lua basalt.lua") -end -local basalt = dofile(filePath) -- here you can change the variablename in any variablename you want default: basalt - -``` \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index a36b1f7..3c20abc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,6 +8,8 @@ + +