From df4ad896b2471157621d446ed337aa4767a8bcd2 Mon Sep 17 00:00:00 2001 From: Robert Jelic <36573031+NoryiE@users.noreply.github.com> Date: Fri, 24 Jun 2022 19:33:37 +0200 Subject: [PATCH] Some changes -reworked monitor support -fixed small draw bugs -changed focus behaviour -added some events -fixed offset bug -added border -added shadow -reworkd anchor system -added possibility to remove background by setting the value to false --- basalt-source.lua | 444 +++++++++++++++++++++------ basalt.lua | 2 +- docs/_sidebar.md | 4 +- docs/events/otherEvents.md | 50 +++ source/project/Frame.lua | 83 +++-- source/project/Object.lua | 281 ++++++++++++++--- source/project/lib/eventSystem.lua | 10 +- source/project/lib/process.lua | 2 +- source/project/lib/utils.lua | 3 +- source/project/mainBottom.lua | 19 +- source/project/objects/Button.lua | 8 +- source/project/objects/Checkbox.lua | 2 +- source/project/objects/Dropdown.lua | 2 +- source/project/objects/Image.lua | 2 +- source/project/objects/Input.lua | 6 +- source/project/objects/Label.lua | 7 +- source/project/objects/List.lua | 4 +- source/project/objects/Menubar.lua | 4 +- source/project/objects/Program.lua | 5 +- source/project/objects/Textfield.lua | 8 +- 20 files changed, 745 insertions(+), 201 deletions(-) create mode 100644 docs/events/otherEvents.md diff --git a/basalt-source.lua b/basalt-source.lua index 639d753..b00552d 100644 --- a/basalt-source.lua +++ b/basalt-source.lua @@ -389,16 +389,22 @@ local function BasaltEvents() end; sendEvent = function(self, _event, ...) + local returnValue if (events[_event] ~= nil) then for _, value in pairs(events[_event]) do - value(...) + local val = value(...) + if(val==false)then + returnValue = val + end end end + return returnValue end; } event.__index = event return event end +local eventSystem = BasaltEvents() local processes = {} local process = {} local processId = 0 @@ -409,7 +415,7 @@ function process:new(path, window, ...) newP.window = window newP.processId = processId newP.coroutine = coroutine.create(function() - os.run({ basalt = basalt }, path, table.unpack(args)) + os.run({ }, path, table.unpack(args)) end) processes[processId] = newP processId = processId + 1 @@ -487,9 +493,8 @@ local function rpairs(t) end, t, #t + 1 end +-- shrink system is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ local function shrink(bLittleData, bgColor) - - -- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 }, { 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } } @@ -613,11 +618,19 @@ local function Object(name) local objectType = "Object" -- not changeable local value local zIndex = 1 - local hanchor = "left" - local vanchor = "top" + local anchor = "topLeft" local ignOffset = false local isVisible = false + local shadow = false + local borderLeft = false + local borderTop = false + local borderRight = false + local borderBottom = false + + local shadowColor = colors.black + local borderColor = colors.black + local visualsChanged = true local eventSystem = BasaltEvents() @@ -789,8 +802,104 @@ local function Object(name) return self.fgColor end; + showShadow = function(self, show) + shadow = show or (not shadow) + return self + end; + + setShadow = function(self, color) + shadowColor = color + return self + end; + + isShadowActive = function(self) + return shadow; + end; + + showBorder = function(self, ...) + for _,v in pairs(table.pack(...))do + if(v=="left")then + borderLeft = true + end + if(v=="top")then + borderTop = true + end + if(v=="right")then + borderRight = true + end + if(v=="bottom")then + borderBottom = true + end + end + return self + end; + + setBorder = function(self, color) + shadowColor = color + return self + end; + + getBorder = function(self, side) + if(side=="left")then + return borderLeft; + end + if(side=="top")then + return borderTop; + end + if(side=="right")then + return borderRight; + end + if(side=="bottom")then + return borderBottom; + end + end; + draw = function(self) if (isVisible) then + if(self.parent~=nil)then + local x, y = self:getAnchorPosition() + if(shadow)then + self.parent:drawBackgroundBox(x+1, y+self.height, self.width, 1, shadowColor) + self.parent:drawBackgroundBox(x+self.width, y+1, 1, self.height, shadowColor) + self.parent:drawForegroundBox(x+1, y+self.height, self.width, 1, shadowColor) + self.parent:drawForegroundBox(x+self.width, y+1, 1, self.height, shadowColor) + end + if(borderLeft)then + self.parent:drawTextBox(x-1, y, 1, self.height, "\149") + self.parent:drawForegroundBox(x-1, y, 1, self.height, borderColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y, 1, self.height, self.bgColor) end + end + if(borderLeft)and(borderTop)then + self.parent:drawTextBox(x-1, y-1, 1, 1, "\151") + self.parent:drawForegroundBox(x-1, y-1, 1, 1, borderColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y-1, 1, 1, self.bgColor) end + end + if(borderTop)then + self.parent:drawTextBox(x, y-1, self.width, 1, "\131") + self.parent:drawForegroundBox(x, y-1, self.width, 1, borderColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(x, y-1, self.width, 1, self.bgColor) end + end + if(borderTop)and(borderRight)then + self.parent:drawTextBox(x+self.width, y-1, 1, 1, "\149") + self.parent:drawForegroundBox(x+self.width, y-1, 1, 1, borderColor) + end + if(borderRight)then + self.parent:drawTextBox(x+self.width, y, 1, self.height, "\149") + self.parent:drawForegroundBox(x+self.width, y, 1, self.height, borderColor) + end + if(borderRight)and(borderBottom)then + self.parent:drawTextBox(x+self.width, y+self.height, 1, 1, "\129") + self.parent:drawForegroundBox(x+self.width, y+self.height, 1, 1, borderColor) + end + if(borderBottom)then + self.parent:drawTextBox(x, y+self.height, self.width, 1, "\131") + self.parent:drawForegroundBox(x, y+self.height, self.width, 1, borderColor) + end + if(borderBottom)and(borderLeft)then + self.parent:drawTextBox(x-1, y+self.height, 1, 1, "\131") + self.parent:drawForegroundBox(x-1, y+self.height, 1, 1, borderColor) + end + end return true end return false @@ -818,11 +927,26 @@ local function Object(name) if (y == nil) then y = self.y end - if (hanchor == "right") then - x = self.parent.width - x - self.width + 2 - end - if (vanchor == "bottom") then - y = self.parent.height - y - self.height + 2 + if (anchor == "top") then + x = math.floor(self.parent.width/2) + x - 1 + elseif(anchor == "topRight") then + x = self.parent.width + x - 1 + elseif(anchor == "right") then + x = self.parent.width + x - 1 + y = math.floor(self.parent.height/2) + y - 1 + elseif(anchor == "bottomRight") then + x = self.parent.width + x - 1 + y = self.parent.height + y - 1 + elseif(anchor == "bottom") then + x = math.floor(self.parent.width/2) + x - 1 + y = self.parent.height + y - 1 + elseif(anchor == "bottomLeft") then + y = self.parent.height + y - 1 + elseif(anchor == "left") then + y = math.floor(self.parent.height/2) + y - 1 + elseif(anchor == "center") then + x = math.floor(self.parent.width/2) + x - 1 + y = math.floor(self.parent.height/2) + y - 1 end local xO, yO = self:getOffset() if not(ignOffset or ignOff) then @@ -851,74 +975,116 @@ local function Object(name) return self end; - setAnchor = function(self, ...) - for _, value in pairs(table.pack(...)) do - if (value == "right") or (value == "left") then - hanchor = value - end - if (value == "top") or (value == "bottom") then - vanchor = value - end - end + setAnchor = function(self, newAnchor) + anchor = newAnchor visualsChanged = true return self end; getAnchor = function(self) - return hanchor, vanchor + return anchor end; - onChange = function(self, func) - self:registerEvent("value_changed", func) + onChange = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("value_changed", v) + end + end return self end; - onClick = function(self, func) - self:registerEvent("mouse_click", func) - self:registerEvent("monitor_touch", func) + onClick = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_click", v) + self:registerEvent("monitor_touch", v) + end + end return self end; - onClickUp = function(self, func) - self:registerEvent("mouse_up", func) + onClickUp = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_up", v) + end + end return self end; - onScroll = function(self, func) - self:registerEvent("mouse_scroll", func) + onScroll = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_scroll", v) + end + end return self end; - onDrag = function(self, func) - self:registerEvent("mouse_drag", func) + onDrag = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_drag", v) + end + end return self end; - onEvent = function(self, func) - self:registerEvent("custom_event_handler", func) + onEvent = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("custom_event_handler", v) + end + end return self end; - onKey = function(self, func) - self:registerEvent("key", func) - self:registerEvent("char", func) + onKey = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("key", v) + self:registerEvent("char", v) + end + end return self end; - onKeyUp = function(self, func) - self:registerEvent("key_up", func) + onResize = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("basalt_resize", v) + end + end return self end; - onBackgroundKey = function(self, func) - self:registerEvent("background_key", func) - self:registerEvent("background_char", func) + onKeyUp = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("key_up", v) + end + end return self end; - onBackgroundKeyUp = function(self, func) - self:registerEvent("background_key_up", func) + onBackgroundKey = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("background_key", v) + self:registerEvent("background_char", v) + end + end + return self + end; + + onBackgroundKeyUp = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("background_key_up", v) + end + end return self end; @@ -929,13 +1095,21 @@ local function Object(name) return false end; - onGetFocus = function(self, func) - self:registerEvent("get_focus", func) + onGetFocus = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("get_focus", v) + end + end return self end; - onLoseFocus = function(self, func) - self:registerEvent("lose_focus", func) + onLoseFocus = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("lose_focus", v) + end + end return self end; @@ -953,11 +1127,18 @@ local function Object(name) mouseHandler = function(self, event, button, x, y) local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + local yOff = false + if(objY-1 == y)and(self:getBorder("top"))then + y = y+1 + yOff = true + end + if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (isVisible) then if (self.parent ~= nil) then self.parent:setFocusedObject(self) end - eventSystem:sendEvent(event, self, event, button, x, y) + local val = eventSystem:sendEvent(event, self, event, button, x, y) + if(val~=nil)then return val end return true end return false @@ -965,14 +1146,17 @@ local function Object(name) keyHandler = function(self, event, key) if (self:isFocused()) then - eventSystem:sendEvent(event, self, event, key) + local val = eventSystem:sendEvent(event, self, event, key) + if(val~=nil)then return val end return true end return false end; backgroundKeyHandler = function(self, event, key) - eventSystem:sendEvent("background_" .. event, self, event, key) + local val = eventSystem:sendEvent("background_"..event, self, event, key) + if(val~=nil)then return val end + return true end; valueChangedHandler = function(self) @@ -984,11 +1168,15 @@ local function Object(name) end; getFocusHandler = function(self) - eventSystem:sendEvent("get_focus", self) + local val = eventSystem:sendEvent("get_focus", self) + if(val~=nil)then return val end + return true end; loseFocusHandler = function(self) - eventSystem:sendEvent("lose_focus", self) + local val = eventSystem:sendEvent("lose_focus", self) + if(val~=nil)then return val end + return true end; @@ -1129,9 +1317,11 @@ local function Button(name) local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + self.parent:drawTextBox(obx, oby, self.width, self.height, " ") + end + if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end for n = 1, self.height do if (n == verticalAlign) then self.parent:setText(obx, oby + (n - 1), getTextHorizontalAlign(self:getValue(), self.width, textHorizontalAlign)) @@ -1184,7 +1374,7 @@ local function Checkbox(name) local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, "center") - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end for n = 1, self.height do if (n == verticalAlign) then if (self:getValue() == true) then @@ -1345,7 +1535,7 @@ local function Dropdown(name) if (base.draw(self)) then local obx, oby = self:getAnchorPosition() if (self.parent ~= nil) then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) 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) @@ -1517,7 +1707,7 @@ local function Image(name) loadBlittleImage = function(self, path) -- not done yet --image = paintutils.loadImage(path) - imageGotShrinked = true + --imageGotShrinked = true return self end; @@ -1646,7 +1836,7 @@ local function Input(name) local obx, oby = self:getAnchorPosition() showingText = "" if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby, self.fgColor) + self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor) end end end; @@ -1749,7 +1939,7 @@ local function Input(name) cursorX = self.x + self.width - 1 end if (self.parent ~= nil) then - self.parent:setCursor(true, obx + cursorX, oby, self.fgColor) + self.parent:setCursor(true, obx + cursorX, oby+math.floor(self.height/2), self.fgColor) end internalValueChange = false end @@ -1771,7 +1961,7 @@ local function Input(name) local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, "center") - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end for n = 1, self.height do if (n == verticalAlign) then local val = tostring(base.getValue()) @@ -1867,9 +2057,10 @@ local function Label(name) if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + self.parent:drawTextBox(obx, oby, self.width, self.height, " ") end + if(self.bgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end if(fontsize==0)then for n = 1, self.height do if (n == verticalAlign) then @@ -2043,7 +2234,9 @@ local function List(name) 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.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end for n = 1, self.height do if (list[n + yOffset] ~= nil) then if (list[n + yOffset] == self:getValue()) then @@ -2237,7 +2430,9 @@ local function Menubar(name) 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.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end local text = "" local textBGCol = "" local textFGCol = "" @@ -2834,6 +3029,7 @@ local function Program(name) if not (paused) then local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true)) curProcess:resume(event, button, x - (absX - 1), y - (absY - 1)) + basalt.debug(event, button, x - (absX - 1), y - (absY - 1)) end end return true @@ -2921,7 +3117,9 @@ local function Program(name) if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() pWindow.basalt_reposition(obx, oby) - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end pWindow.basalt_update() end self:setVisualChanged(false) @@ -3798,8 +3996,12 @@ local function Textfield(name) 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) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end + if(self.fgColor~=false)then + self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) + end for n = 1, self.height do local text = "" if (lines[n + hIndex - 1] ~= nil) then @@ -3977,7 +4179,8 @@ local function Frame(name, parent) local monSide = "" local isMonitor = false local monitorAttached = false - local dragOffset = 0 + local dragXOffset = 0 + local dragYOffset = 0 base:setZIndex(10) @@ -4076,6 +4279,19 @@ local function Frame(name, parent) return self end; + setSize = function(self, w, h) + base.setSize(self, w, h) + for _, index in pairs(objZIndex) do + if (objects[index] ~= nil) then + for _, value in pairs(objects[index]) do + if (value.eventHandler ~= nil) then + value:sendEvent("basalt_resize", value, self) + end + end + end + end + end; + setOffset = function(self, xO, yO) xOffset = xO ~= nil and math.floor(xO < 0 and math.abs(xO) or -xO) or xOffset yOffset = yO ~= nil and math.floor(yO < 0 and math.abs(yO) or -yO) or yOffset @@ -4175,7 +4391,7 @@ local function Frame(name, parent) end; setMonitor = function(self, side) - if(side~=nil)or(side~=false)then + if(side~=nil)and(side~=false)then if(peripheral.getType(side)=="monitor")then termObject = peripheral.wrap(side) monitorAttached = true @@ -4288,7 +4504,7 @@ local function Frame(name, parent) if (self.parent ~= nil) then parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) end - self:setPosition(x + dragOffset - (parentX - 1) + xO, y - (parentY - 1) + yO) + self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO) end if (event == "mouse_up") then self.drag = false @@ -4296,6 +4512,13 @@ local function Frame(name, parent) return true end + local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + local yOff = false + if(objY-1 == y)and(self:getBorder("top"))then + y = y+1 + yOff = true + end + if (base.mouseHandler(self, event, button, x, y)) then local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) fx = fx + xOffset;fy = fy + yOffset; @@ -4310,13 +4533,14 @@ local function Frame(name, parent) end end end - - if (self.isMoveable) then - if (x >= fx) and (x <= fx + self.width - 1) and (y == fy) and (event == "mouse_click") then - self.drag = true - dragOffset = fx - x + if (self.isMoveable) then + local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) + if (x >= fx) and (x <= fx + self.width - 1) and (y == fy) and (event == "mouse_click") then + self.drag = true + dragXOffset = fx - x + dragYOffset = yOff and 1 or 0 + end end - end if (focusedObject ~= nil) then focusedObject:loseFocusHandler() focusedObject = nil @@ -4331,9 +4555,9 @@ local function Frame(name, parent) if (y >= 1) and (y <= self.height) then if (self.parent ~= nil) then local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1)) + self.parent:setText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) else - drawHelper.setText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), self.width - x + 1)) + drawHelper.setText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) -- math.max(self.width - x + 1,1) now, before: self.width - x + 1 end end end; @@ -4343,9 +4567,9 @@ local function Frame(name, parent) if (y >= 1) and (y <= self.height) then if (self.parent ~= nil) then local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setBG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(bgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + self.parent:setBG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) else - drawHelper.setBG(math.max(x + (obx - 1), obx), oby + y - 1, sub(bgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + drawHelper.setBG(math.max(x + (obx - 1), obx), oby + y - 1, sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) end end end; @@ -4355,9 +4579,9 @@ local function Frame(name, parent) if (y >= 1) and (y <= self.height) then if (self.parent ~= nil) then local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setFG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(fgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + self.parent:setFG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) else - drawHelper.setFG(math.max(x + (obx - 1), obx), oby + y - 1, sub(fgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + drawHelper.setFG(math.max(x + (obx - 1), obx), oby + y - 1, sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) end end end; @@ -4369,7 +4593,7 @@ local function Frame(name, parent) local parentX, parentY = self.parent:getAnchorPosition() self.parent:writeText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) else - drawHelper.writeText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) + drawHelper.writeText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1)), bgCol, fgCol) end end end; @@ -4417,13 +4641,17 @@ local function Frame(name, parent) local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) local anchx, anchy = self:getAnchorPosition() if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx, anchy, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(anchx, anchy, self.width, self.height, self.fgColor) - self.parent:drawTextBox(anchx, anchy, self.width, self.height, " ") + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(anchx, anchy, self.width, self.height, self.bgColor) + self.parent:drawTextBox(anchx, anchy, self.width, self.height, " ") + end + if(self.bgColor~=false)then self.parent:drawForegroundBox(anchx, anchy, self.width, self.height, self.fgColor) end else - drawHelper.drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") + if(self.bgColor~=false)then + drawHelper.drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") + end + if(self.fgColor~=false)then drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end end termObject.setCursorBlink(false) if (self.barActive) then @@ -4432,6 +4660,19 @@ local function Frame(name, parent) else drawHelper.writeText(obx, oby, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) end + if(self:getBorder("left"))then + if (self.parent ~= nil) then + self.parent:drawBackgroundBox(anchx-1, anchy, 1, 1, self.barBackground) + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(anchx-1, anchy+1, 1, self.height-1, self.bgColor) + end + end + end + if(self:getBorder("top"))then + if (self.parent ~= nil) then + self.parent:drawBackgroundBox(anchx-1, anchy-1, self.width+1, 1, self.barBackground) + end + end end for _, index in rpairs(objZIndex) do @@ -4593,6 +4834,7 @@ end local updaterActive = false local function basaltUpdateEvent(event, p1, p2, p3, p4) + if(eventSystem:sendEvent("basaltEventCycle", event, p1, p2, p3, p4)==false)then return end if(mainFrame~=nil)then if (event == "mouse_click") then mainFrame:mouseHandler(event, p1, p2, p3, p4) @@ -4630,9 +4872,7 @@ local function basaltUpdateEvent(event, p1, p2, p3, p4) for _, v in pairs(frames) do v:eventHandler(event, p1, p2, p3, p4) end - if (updaterActive) then - drawFrames() - end + drawFrames() end function basalt.autoUpdate(isActive) @@ -4648,8 +4888,6 @@ end function basalt.update(event, p1, p2, p3, p4) if (event ~= nil) then basaltUpdateEvent(event, p1, p2, p3, p4) - else - drawFrames() end end @@ -4682,6 +4920,14 @@ function basalt.setActiveFrame(frame) return false end +function basalt.onEvent(...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + eventSystem:registerEvent("basaltEventCycle", v) + end + end +end + function basalt.createFrame(name) for _, v in pairs(frames) do if (v.name == name) then @@ -4701,8 +4947,8 @@ end if (basalt.debugger) then basalt.debugFrame = basalt.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug", colors.black, colors.gray) basalt.debugList = basalt.debugFrame:addList("debugList"):setSize(basalt.debugFrame.width - 2, basalt.debugFrame.height - 3):setPosition(2, 3):setScrollable(true):show() - basalt.debugFrame:addButton("back"):setAnchor("right"):setSize(1, 1):setText("\22"):onClick(function() basalt.oldFrame:show() end):setBackground(colors.red):show() - basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):ignoreOffset():setZIndex(20):show() + basalt.debugFrame:addButton("back"):setAnchor("topRight"):setSize(1, 1):setText("\22"):onClick(function() basalt.oldFrame:show() end):setBackground(colors.red):show() + basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show() end if (basalt.debugger) then diff --git a/basalt.lua b/basalt.lua index f0fdb86..d1c61b5 100644 --- a/basalt.lua +++ b/basalt.lua @@ -1 +1 @@ -local a={debugger=true,version=1}local b={}local c;local d={}local e;local f;local g={}local h=term.current()local i=string.sub;local j={[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 k={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 l={{"\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 m={}local n={}do local o=0;local p=#l[1]local q=#l[1][1]for r=1,p,3 do for s=1,q,3 do local t=string.char(o)local u={}u[1]=l[1][r]:sub(s,s+2)u[2]=l[1][r+1]:sub(s,s+2)u[3]=l[1][r+2]:sub(s,s+2)local v={}v[1]=l[2][r]:sub(s,s+2)v[2]=l[2][r+1]:sub(s,s+2)v[3]=l[2][r+2]:sub(s,s+2)n[t]={u,v}o=o+1 end end;m[1]=n end;local function w(x,y)local z={["0"]="1",["1"]="0"}if x<=#m then return true end;for A=#m+1,x do local B={}local C=m[A-1]for o=0,255 do local t=string.char(o)local u={}local v={}local D=C[t][1]local E=C[t][2]for r=1,#D do local F,G,H,I,J,K={},{},{},{},{},{}for s=1,#D[1]do local L=n[D[r]:sub(s,s)][1]table.insert(F,L[1])table.insert(G,L[2])table.insert(H,L[3])local M=n[D[r]:sub(s,s)][2]if E[r]:sub(s,s)=="1"then table.insert(I,M[1]:gsub("[01]",z))table.insert(J,M[2]:gsub("[01]",z))table.insert(K,M[3]:gsub("[01]",z))else table.insert(I,M[1])table.insert(J,M[2])table.insert(K,M[3])end end;table.insert(u,table.concat(F))table.insert(u,table.concat(G))table.insert(u,table.concat(H))table.insert(v,table.concat(I))table.insert(v,table.concat(J))table.insert(v,table.concat(K))end;B[t]={u,v}if y then y="Font"..A.."Yeld"..o;os.queueEvent(y)os.pullEvent(y)end end;m[A]=B end;return true end;local function N(O,P,Q,R,S)if not type(P)=="string"then error("Not a String",3)end;local T=type(Q)=="string"and Q:sub(1,1)or j[Q]or error("Wrong Front Color",3)local U=type(R)=="string"and R:sub(1,1)or j[R]or error("Wrong Back Color",3)if m[O]==nil then w(3,false)end;local V=m[O]or error("Wrong font size selected",3)if P==""then return{{""},{""},{""}}end;local W={}for r in P:gmatch('.')do table.insert(W,r)end;local X={}local p=#V[W[1]][1]for Y=1,p do local Z={}for r=1,#W do Z[r]=V[W[r]]and V[W[r]][1][Y]or""end;X[Y]=table.concat(Z)end;local _={}local a0={}local a1={["0"]=T,["1"]=U}local a2={["0"]=U,["1"]=T}for Y=1,p do local a3={}local a4={}for r=1,#W do local a5=V[W[r]]and V[W[r]][2][Y]or""a3[r]=a5:gsub("[01]",S and{["0"]=Q:sub(r,r),["1"]=R:sub(r,r)}or a1)a4[r]=a5:gsub("[01]",S and{["0"]=R:sub(r,r),["1"]=Q:sub(r,r)}or a2)end;_[Y]=table.concat(a3)a0[Y]=table.concat(a4)end;return{X,_,a0}end;local function a6(a7)local a8=a7;local a9,p=a8.getSize()local aa={}local ab={}local ac={}local ad={}local ae={}local af={}local ag;local ah={}local function ai()ag=(" "):rep(a9)for aj=0,15 do local ak=2^aj;local al=j[ak]ah[ak]=al:rep(a9)end end;ai()local function am()local an=ag;local ao=ah[colors.white]local ap=ah[colors.black]for aq=1,p do aa[aq]=i(aa[aq]==nil and an or aa[aq]..an:sub(1,a9-aa[aq]:len()),1,a9)ac[aq]=i(ac[aq]==nil and ao or ac[aq]..ao:sub(1,a9-ac[aq]:len()),1,a9)ab[aq]=i(ab[aq]==nil and ap or ab[aq]..ap:sub(1,a9-ab[aq]:len()),1,a9)end end;am()local function ar(as,at,au)if at>=1 and at<=p then if as+au:len()>0 and as<=a9 then local av=aa[at]local aw;local ax=as+#au-1;if as<1 then local ay=1-as+1;local az=a9-as+1;au=i(au,ay,az)elseif ax>a9 then local az=a9-as+1;au=i(au,1,az)end;if as>1 then local az=as-1;aw=i(av,1,az)..au else aw=au end;if ax=1 and at<=p then if as+aB:len()>0 and as<=a9 then local av=ab[at]local aw;local ax=as+#aB-1;if as<1 then aB=i(aB,1-as+1,a9-as+1)elseif ax>a9 then aB=i(aB,1,a9-as+1)end;if as>1 then aw=i(av,1,as-1)..aB else aw=aB end;if ax=1 and at<=p then if as+aB:len()>0 and as<=a9 then local av=ac[at]local aw;local ax=as+#aB-1;if as<1 then local ay=1-as+1;local az=a9-as+1;aB=i(aB,ay,az)elseif ax>a9 then local az=a9-as+1;aB=i(aB,1,az)end;if as>1 then local az=as-1;aw=i(av,1,az)..aB else aw=aB end;if ax1 then while#bj>2 do table.sort(bj,function(bt,bu)return bt[2]>bu[2]end)local bv,bw=bi(bj),#bj;local bx,by=bj[bw][1],bj[bv][1]for r=1,6 do if bn[r]==bx then bn[r]=by;bj[bv][2]=bj[bv][2]+1 end end;bj[bw]=nil end;local bz=128;for r=1,#bn-1 do if bn[r]~=bn[6]then bz=bz+2^(r-1)end end;return string.char(bz),bf[bj[1][1]==bn[6]and bj[2][1]or bj[1][1]],bf[bn[6]]else return"\128",bf[bn[1]],bf[bn[1]]end end;local bA,a9,p,aE={{},{},{}},0,#ba+#ba%3,bb or colors.black;for r=1,#ba do if#ba[r]>a9 then a9=#ba[r]end end;for at=0,p-1,3 do local bB,bC,bD,bE={},{},{},1;for as=0,a9-1,2 do local bn,bo={},{}for bF=1,3 do for bG=1,2 do bn[#bn+1]=ba[at+bF]and ba[at+bF][as+bG]and(ba[at+bF][as+bG]==0 and aE or ba[at+bF][as+bG])or aE;bo[bn[#bn]]=bo[bn[#bn]]and bo[bn[#bn]]+1 or 1 end end;bB[bE],bC[bE],bD[bE]=bm(bn,bo)bE=bE+1 end;bA[1][#bA[1]+1],bA[2][#bA[2]+1],bA[3][#bA[3]+1]=table.concat(bB),table.concat(bC),table.concat(bD)end;bA.width,bA.height=#bA[1][1],#bA[1]return bA end;local function bH(bI)local bJ="Object"local aS;local bK=1;local bL="left"local bM="top"local bN=false;local bO=false;local bP=true;local bQ=aL()local bR={x=1,y=1,width=1,height=1,bgColor=colors.black,fgColor=colors.white,name=bI or"Object",parent=nil,show=function(self)bO=true;bP=true;return self end,hide=function(self)bO=false;bP=true;return self end,isVisible=function(self)return bO end,setFocus=function(self)if self.parent~=nil then self.parent:setFocusedObject(self)end;return self end,setZIndex=function(self,aN)bK=aN;if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end;return self end,getZIndex=function(self)return bK end,getType=function(self)return bJ 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,bS)if bS.getType~=nil and bS:getType()=="Frame"then self:remove()bS:addObject(self)if self.draw then self:show()end end;return self end,setValue=function(self,bT)if aS~=bT then aS=bT;bP=true;self:valueChangedHandler()end;return self end,getValue=function(self)return aS end,getVisualChanged=function(self)return bP end,setVisualChanged=function(self,bU)bP=bU or true;if bU==nil then bP=true end;return self end,getEventSystem=function(self)return bQ end,getParent=function(self)return self.parent end,setPosition=function(self,bV,bW,bX)if bX then self.x,self.y=math.floor(self.x+bV),math.floor(self.y+bW)else self.x,self.y=math.floor(bV),math.floor(bW)end;bP=true;return self end,getPosition=function(self)return self.x,self.y end,getVisibility=function(self)return bO end,setVisibility=function(self,bY)bO=bY or not bO;bP=true;return self end,setSize=function(self,a9,p)self.width,self.height=a9,p;bP=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,bZ)self.bgColor=bZ;bP=true;return self end,getBackground=function(self)return self.bgColor end,setForeground=function(self,bZ)self.fgColor=bZ;bP=true;return self end,getForeground=function(self)return self.fgColor end,draw=function(self)if bO then return true end;return false end,getAbsolutePosition=function(self,as,at)if as==nil or at==nil then as,at=self:getAnchorPosition()end;if self.parent~=nil then local b_,c0=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())as=b_+as-1;at=c0+at-1 end;return as,at end,getAnchorPosition=function(self,as,at,c1)if as==nil then as=self.x end;if at==nil then at=self.y end;if bL=="right"then as=self.parent.width-as-self.width+2 end;if bM=="bottom"then at=self.parent.height-at-self.height+2 end;local c2,c3=self:getOffset()if not(bN or c1)then return as+c2,at+c3 end;return as,at end,getOffset=function(self)if self.parent~=nil then return self.parent:getFrameOffset()end;return 0,0 end,ignoreOffset=function(self,c4)bN=c4;if c4==nil then bN=true end;return self end,getBaseFrame=function(self)if self.parent~=nil then return self.parent:getBaseFrame()end;return self end,setAnchor=function(self,...)for aR,aS in pairs(table.pack(...))do if aS=="right"or aS=="left"then bL=aS end;if aS=="top"or aS=="bottom"then bM=aS end end;bP=true;return self end,getAnchor=function(self)return bL,bM end,onChange=function(self,aQ)self:registerEvent("value_changed",aQ)return self end,onClick=function(self,aQ)self:registerEvent("mouse_click",aQ)self:registerEvent("monitor_touch",aQ)return self end,onClickUp=function(self,aQ)self:registerEvent("mouse_up",aQ)return self end,onScroll=function(self,aQ)self:registerEvent("mouse_scroll",aQ)return self end,onDrag=function(self,aQ)self:registerEvent("mouse_drag",aQ)return self end,onEvent=function(self,aQ)self:registerEvent("custom_event_handler",aQ)return self end,onKey=function(self,aQ)self:registerEvent("key",aQ)self:registerEvent("char",aQ)return self end,onKeyUp=function(self,aQ)self:registerEvent("key_up",aQ)return self end,onBackgroundKey=function(self,aQ)self:registerEvent("background_key",aQ)self:registerEvent("background_char",aQ)return self end,onBackgroundKeyUp=function(self,aQ)self:registerEvent("background_key_up",aQ)return self end,isFocused=function(self)if self.parent~=nil then return self.parent:getFocusedObject()==self end;return false end,onGetFocus=function(self,aQ)self:registerEvent("get_focus",aQ)return self end,onLoseFocus=function(self,aQ)self:registerEvent("lose_focus",aQ)return self end,registerEvent=function(self,aO,aQ)return bQ:registerEvent(aO,aQ)end,removeEvent=function(self,aO,aN)return bQ:removeEvent(aO,aN)end,sendEvent=function(self,aO,...)return bQ:sendEvent(aO,self,...)end,mouseHandler=function(self,aO,c5,as,at)local c6,c7=self:getAbsolutePosition(self:getAnchorPosition())if c6<=as and c6+self.width>as and c7<=at and c7+self.height>at and bO then if self.parent~=nil then self.parent:setFocusedObject(self)end;bQ:sendEvent(aO,self,aO,c5,as,at)return true end;return false end,keyHandler=function(self,aO,bs)if self:isFocused()then bQ:sendEvent(aO,self,aO,bs)return true end;return false end,backgroundKeyHandler=function(self,aO,bs)bQ:sendEvent("background_"..aO,self,aO,bs)end,valueChangedHandler=function(self)bQ:sendEvent("value_changed",self)end,eventHandler=function(self,aO,c8,c9,ca,cb)bQ:sendEvent("custom_event_handler",self,aO,c8,c9,ca,cb)end,getFocusHandler=function(self)bQ:sendEvent("get_focus",self)end,loseFocusHandler=function(self)bQ:sendEvent("lose_focus",self)end}bR.__index=bR;return bR end;local function cc(bI)local bR={}local bJ="Animation"local cd;local ce={}local aN=1;local cf=0;local cg;local function ch()if ce[aN]~=nil then ce[aN].f(bR,aN)end;aN=aN+1;if ce[aN]~=nil then if ce[aN].t>0 then cd=os.startTimer(ce[aN].t)else ch()end end end;bR={name=bI,getType=function(self)return bJ end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,aQ,ci)cg=aQ;table.insert(ce,{f=aQ,t=ci or cf})return self end,wait=function(self,ci)cf=ci;return self end,rep=function(self,cj)for as=1,cj do table.insert(ce,{f=cg,t=cf})end;return self end,clear=function(self)ce={}cg=nil;cf=0;aN=1;return self end,play=function(self)aN=1;if ce[aN]~=nil then if ce[aN].t>0 then cd=os.startTimer(ce[aN].t)else ch()end end;return self end,cancel=function(self)os.cancelTimer(cd)return self end,eventHandler=function(self,aO,ck)if aO=="timer"and ck==cd then if ce[aN]~=nil then ch()end end end}bR.__index=bR;return bR end;local function cl(bI)local cm=bH(bI)local bJ="Button"cm:setValue("Button")cm:setZIndex(5)cm.width=8;cm.bgColor=k.ButtonBG;cm.fgColor=k.ButtonFG;local cn="center"local co="center"local bR={getType=function(self)return bJ end,setHorizontalAlign=function(self,cp)cn=cp end,setVerticalAlign=function(self,cp)co=cp end,setText=function(self,au)cm:setValue(au)return self end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()local cs=b5(self.height,co)self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cq,cr,self.width,self.height,self.fgColor)self.parent:drawTextBox(cq,cr,self.width,self.height," ")for aj=1,self.height do if aj==cs then self.parent:setText(cq,cr+aj-1,b1(self:getValue(),self.width,cn))end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function ct(bI)local cm=bH(bI)local bJ="Checkbox"cm:setZIndex(5)cm:setValue(false)cm.width=1;cm.height=1;cm.bgColor=k.CheckboxBG;cm.fgColor=k.CheckboxFG;local bR={symbol="\42",getType=function(self)return bJ end,mouseHandler=function(self,aO,c5,as,at)if cm.mouseHandler(self,aO,c5,as,at)then if aO=="mouse_click"and c5==1 or aO=="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 cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()local cs=b5(self.height,"center")self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)for aj=1,self.height do if aj==cs then if self:getValue()==true then self.parent:writeText(cq,cr+aj-1,b1(self.symbol,self.width,"center"),self.bgColor,self.fgColor)else self.parent:writeText(cq,cr+aj-1,b1(" ",self.width,"center"),self.bgColor,self.fgColor)end end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function cu(bI)local cm=bH(bI)local bJ="Dropdown"cm.width=12;cm.height=1;cm.bgColor=k.dropdownBG;cm.fgColor=k.dropdownFG;cm:setZIndex(6)local cv={}local cw=k.selectionBG;local cx=k.selectionFG;local cy=true;local cz="left"local cA=0;local cB=16;local cC=6;local cD="\16"local cE="\31"local cF=false;local bR={getType=function(self)return bJ end,setIndexOffset=function(self,cG)cA=cG;return self end,getIndexOffset=function(self)return cA end,addItem=function(self,au,aE,aF,...)table.insert(cv,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,getAll=function(self)return cv end,removeItem=function(self,aN)table.remove(cv,aN)return self end,getItem=function(self,aN)return cv[aN]end,getItemIndex=function(self)local cH=self:getValue()for bs,aS in pairs(cv)do if aS==cH then return bs end end end,clear=function(self)cv={}self:setValue({})return self end,getItemCount=function(self)return#cv end,editItem=function(self,aN,au,aE,aF,...)table.remove(cv,aN)table.insert(cv,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cv[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cI)cw=aE or self.bgColor;cx=aF or self.fgColor;cy=cI;return self end,setDropdownSize=function(self,a9,p)cB,cC=a9,p;return self end,mouseHandler=function(self,aO,c5,as,at)if cF then local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and c5==1 or aO=="monitor_touch"then if#cv>0 then for aj=1,cC do if cv[aj+cA]~=nil then if cq<=as and cq+cB>as and cr+aj==at then self:setValue(cv[aj+cA])return true end end end end end;if aO=="mouse_scroll"then cA=cA+c5;if cA<0 then cA=0 end;if c5==1 then if#cv>cC then if cA>#cv-cC then cA=#cv-cC end else cA=cv-1 end end;return true end;self:setVisualChanged()end;if cm.mouseHandler(self,aO,c5,as,at)then cF=true else cF=false end end,draw=function(self)if cm.draw(self)then local cq,cr=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)local cJ=self:getValue()local au=b1(cJ~=nil and cJ.text or"",self.width,cz):sub(1,self.width-1)..(cF and cE or cD)self.parent:writeText(cq,cr,au,self.bgColor,self.fgColor)if cF then for aj=1,cC do if cv[aj+cA]~=nil then if cv[aj+cA]==cJ then if cy then self.parent:writeText(cq,cr+aj,b1(cv[aj+cA].text,cB,cz),cw,cx)else self.parent:writeText(cq,cr+aj,b1(cv[aj+cA].text,cB,cz),cv[aj+cA].bgCol,cv[aj+cA].fgCol)end else self.parent:writeText(cq,cr+aj,b1(cv[aj+cA].text,cB,cz),cv[aj+cA].bgCol,cv[aj+cA].fgCol)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function cK(bI)local cm=bH(bI)local bJ="Image"cm:setZIndex(2)local cL;local cM;local cN=false;local function b9()local bc={[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 bd,be,bf={},{},{}for r=0,15 do be[2^r]=r end;do local bg="0123456789abcdef"for r=1,16 do bd[bg:sub(r,r)]=r-1;bd[r-1]=bg:sub(r,r)bf[bg:sub(r,r)]=2^(r-1)bf[2^(r-1)]=bg:sub(r,r)local bh=bc[r-1]for r=1,#bh do bh[r]=2^bh[r]end end end;local function bi(bj)local bk=bc[be[bj[#bj][1]]]for s=1,#bk do local bl=bk[s]for r=1,#bj-1 do if bj[r][1]==bl then return r end end end;return 1 end;local function bm(bn,bo)if not bo then local bp={}bo={}for r=1,6 do local bq=bn[r]local br=bo[bq]bo[bq],bp[r]=br and br+1 or 1,bq end;bn=bp end;local bj={}for bs,aS in pairs(bo)do bj[#bj+1]={bs,aS}end;if#bj>1 then while#bj>2 do table.sort(bj,function(bt,bu)return bt[2]>bu[2]end)local bv,bw=bi(bj),#bj;local bx,by=bj[bw][1],bj[bv][1]for r=1,6 do if bn[r]==bx then bn[r]=by;bj[bv][2]=bj[bv][2]+1 end end;bj[bw]=nil end;local bz=128;for r=1,#bn-1 do if bn[r]~=bn[6]then bz=bz+2^(r-1)end end;return string.char(bz),bf[bj[1][1]==bn[6]and bj[2][1]or bj[1][1]],bf[bn[6]]else return"\128",bf[bn[1]],bf[bn[1]]end end;local bA,a9,p,aE={{},{},{}},0,#cL+#cL%3,cm.bgColor or colors.black;for r=1,#cL do if#cL[r]>a9 then a9=#cL[r]end end;for at=0,p-1,3 do local bB,bC,bD,bE={},{},{},1;for as=0,a9-1,2 do local bn,bo={},{}for bF=1,3 do for bG=1,2 do bn[#bn+1]=cL[at+bF]and cL[at+bF][as+bG]and(cL[at+bF][as+bG]==0 and aE or cL[at+bF][as+bG])or aE;bo[bn[#bn]]=bo[bn[#bn]]and bo[bn[#bn]]+1 or 1 end end;bB[bE],bC[bE],bD[bE]=bm(bn,bo)bE=bE+1 end;bA[1][#bA[1]+1],bA[2][#bA[2]+1],bA[3][#bA[3]+1]=table.concat(bB),table.concat(bC),table.concat(bD)end;bA.width,bA.height=#bA[1][1],#bA[1]cM=bA end;local bR={getType=function(self)return bJ end,loadImage=function(self,aW)cL=paintutils.loadImage(aW)cN=false;return self end,loadBlittleImage=function(self,aW)cN=true;return self end,shrink=function(self)b9()cN=true;return self end,draw=function(self)if cm.draw(self)then if self.parent~=nil then if cL~=nil then local cq,cr=self:getAnchorPosition()if cN then local b8,cO,cP=cM[1],cM[2],cM[3]for r=1,cM.height do local cQ=b8[r]if type(cQ)=="string"then self.parent:setText(cq,cr+r-1,cQ)self.parent:setFG(cq,cr+r-1,cO[r])self.parent:setBG(cq,cr+r-1,cP[r])elseif type(cQ)=="table"then self.parent:setText(cq,cr+r-1,cQ[2])self.parent:setFG(cq,cr+r-1,cO[r])self.parent:setBG(cq,cr+r-1,cP[r])end end else for bW=1,math.min(#cL,self.height)do local cR=cL[bW]for bV=1,math.min(#cR,self.width)do if cR[bV]>0 then self.parent:drawBackgroundBox(cq+bV-1,cr+bW-1,1,1,cR[bV])end end end end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function cS(bI)local cm=bH(bI)local bJ="Input"local cT="text"local cU=0;cm:setZIndex(5)cm:setValue("")cm.width=10;cm.height=1;cm.bgColor=k.InputBG;cm.fgColor=k.InputFG;local cV=1;local cW=1;local cX=""local cY;local cZ;local c_=cX;local d0=false;local bR={getType=function(self)return bJ end,setInputType=function(self,d1)if d1=="password"or d1=="number"or d1=="text"then cT=d1 end;return self end,setDefaultText=function(self,au,d2,d3)cX=au;cY=d3 or cY;cZ=d2 or cZ;if self:isFocused()then c_=""else c_=cX end;return self end,getInputType=function(self)return cT end,setValue=function(self,cJ)cm.setValue(self,tostring(cJ))if not d0 then cV=tostring(cJ):len()+1 end;return self end,getValue=function(self)local cJ=cm.getValue(self)return cT=="number"and tonumber(cJ)or cJ end,setInputLimit=function(self,d4)cU=tonumber(d4)or cU;return self end,getInputLimit=function(self)return cU end,getFocusHandler=function(self)cm.getFocusHandler(self)if self.parent~=nil then local cq,cr=self:getAnchorPosition()c_=""if self.parent~=nil then self.parent:setCursor(true,cq+cV-cW,cr,self.fgColor)end end end,loseFocusHandler=function(self)cm.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)c_=cX end end,keyHandler=function(self,aO,bs)if cm.keyHandler(self,aO,bs)then d0=true;if aO=="key"then if bs==keys.backspace then local au=tostring(cm.getValue())if cV>1 then self:setValue(au:sub(1,cV-2)..au:sub(cV,au:len()))if cV>1 then cV=cV-1 end;if cW>1 then if cVd5 then cV=d5+1 end;if cV<1 then cV=1 end;if cV=self.width+cW then cW=cV-self.width+1 end;if cW<1 then cW=1 end end;if bs==keys.left then cV=cV-1;if cV>=1 then if cV=self.width+cW then cW=cV end end;if cV<1 then cV=1 end;if cW<1 then cW=1 end end end;if aO=="char"then local au=cm.getValue()if au:len()=self.width+cW then cW=cW+1 end end end;local cq,cr=self:getAnchorPosition()local cJ=tostring(cm.getValue())local d7=(cV<=cJ:len()and cV-1 or cJ:len())-(cW-1)if d7>self.x+self.width-1 then d7=self.x+self.width-1 end;if self.parent~=nil then self.parent:setCursor(true,cq+d7,cr,self.fgColor)end;d0=false end end,mouseHandler=function(self,aO,c5,as,at)if cm.mouseHandler(self,aO,c5,as,at)then if aO=="mouse_click"and c5==1 then end;return true end;return false end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()local cs=b5(self.height,"center")self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)for aj=1,self.height do if aj==cs then local cJ=tostring(cm.getValue())local d3=self.bgColor;local d2=self.fgColor;local au;if cJ:len()<=0 then au=c_;d3=cY or d3;d2=cZ or d2 end;au=c_;if cJ~=""then au=cJ end;au=au:sub(cW,self.width+cW-1)local d8=self.width-au:len()if d8<0 then d8=0 end;if cT=="password"and cJ~=""then au=string.rep("*",au:len())end;au=au..string.rep(" ",d8)self.parent:writeText(cq,cr+aj-1,au,d3,d2)end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function d9(bI)local cm=bH(bI)local bJ="Label"cm:setZIndex(3)cm.fgColor=colors.white;cm.bgcolor=colors.black;local da=true;cm:setValue("")local cn="left"local co="top"local db=0;local bR={getType=function(self)return bJ end,setText=function(self,au)au=tostring(au)cm:setValue(au)if da then self.width=au:len()end;return self end,setTextAlign=function(self,dc,dd)cn=dc or cn;co=dd or co;self:setVisualChanged()return self end,setFontSize=function(self,x)if x>0 and x<=4 then db=x-1 or 0 end;return self end,getFontSize=function(self)return db+1 end,setSize=function(self,a9,p)cm.setSize(self,a9,p)da=false;self:setVisualChanged()return self end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()local cs=b5(self.height,co)self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cq,cr,self.width,self.height,self.fgColor)self.parent:drawTextBox(cq,cr,self.width,self.height," ")if db==0 then for aj=1,self.height do if aj==cs then self.parent:writeText(cq,cr+aj-1,b1(self:getValue(),self.width,cn),self.bgColor,self.fgColor)end end else local de=N(db,self:getValue(),self.fgColor,self.bgColor)if da then self.height=#de[1]-1;self.width=#de[1][1]end;for aj=1,self.height do if aj==cs then local df,dg=self.parent:getSize()local dh,di=#de[1][1],#de[1]cq=cq or math.floor((df-dh)/2)+1;cr=cr or math.floor((dg-di)/2)+1;for r=1,di do self.parent:setFG(cq,cr+r+aj-2,b1(de[2][r],self.width,cn))self.parent:setBG(cq,cr+r+aj-2,b1(de[3][r],self.width,cn,j[self.bgColor]))self.parent:setText(cq,cr+r+aj-2,b1(de[1][r],self.width,cn))end end end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function dj(bI)local cm=bH(bI)local bJ="List"cm.width=16;cm.height=6;cm.bgColor=k.listBG;cm.fgColor=k.listFG;cm:setZIndex(5)local cv={}local cw=k.selectionBG;local cx=k.selectionFG;local cy=true;local cz="left"local cA=0;local dk=true;local bR={getType=function(self)return bJ end,addItem=function(self,au,aE,aF,...)table.insert(cv,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})if#cv==1 then self:setValue(cv[1])end;return self end,setIndexOffset=function(self,cG)cA=cG;return self end,getIndexOffset=function(self)return cA end,removeItem=function(self,aN)table.remove(cv,aN)return self end,getItem=function(self,aN)return cv[aN]end,getAll=function(self)return cv end,getItemIndex=function(self)local cH=self:getValue()for bs,aS in pairs(cv)do if aS==cH then return bs end end end,clear=function(self)cv={}self:setValue({})return self end,getItemCount=function(self)return#cv end,editItem=function(self,aN,au,aE,aF,...)table.remove(cv,aN)table.insert(cv,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cv[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cI)cw=aE or self.bgColor;cx=aF or self.fgColor;cy=cI;return self end,setScrollable=function(self,dl)dk=dl;return self end,mouseHandler=function(self,aO,c5,as,at)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if cq<=as and cq+self.width>as and cr<=at and cr+self.height>at and self:isVisible()then if(aO=="mouse_click"or aO=="mouse_drag")and c5==1 or aO=="monitor_touch"then if#cv>0 then for aj=1,self.height do if cv[aj+cA]~=nil then if cq<=as and cq+self.width>as and cr+aj-1==at then self:setValue(cv[aj+cA])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,as,at,cv[aj+cA])end end end end end;if aO=="mouse_scroll"and dk then cA=cA+c5;if cA<0 then cA=0 end;if c5>=1 then if#cv>self.height then if cA>#cv-self.height then cA=#cv-self.height end;if cA>=#cv then cA=#cv-1 end else cA=cA-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)for aj=1,self.height do if cv[aj+cA]~=nil then if cv[aj+cA]==self:getValue()then if cy then self.parent:writeText(cq,cr+aj-1,b1(cv[aj+cA].text,self.width,cz),cw,cx)else self.parent:writeText(cq,cr+aj-1,b1(cv[aj+cA].text,self.width,cz),cv[aj+cA].bgCol,cv[aj+cA].fgCol)end else self.parent:writeText(cq,cr+aj-1,b1(cv[aj+cA].text,self.width,cz),cv[aj+cA].bgCol,cv[aj+cA].fgCol)end end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function dm(bI)local cm=bH(bI)local bJ="Menubar"local bR={}cm.width=30;cm.height=1;cm.bgColor=colors.gray;cm.fgColor=colors.lightGray;cm:setZIndex(5)local cv={}local cw=k.selectionBG;local cx=k.selectionFG;local cy=true;local cz="left"local dn=0;local d8=1;local dk=false;local function dp()local dq=0;local bV=0;for aj=1,#cv do if bV+cv[aj].text:len()+d8*2>bR.width then if bVdq then dn=dq end;return self end,getPositionOffset=function(self)return dn end,setScrollable=function(self,dl)dk=dl;if dl==nil then dk=true end;return self end,removeItem=function(self,aN)table.remove(cv,aN)return self end,getItem=function(self,aN)return cv[aN]end,getItemCount=function(self)return#cv end,editItem=function(self,aN,au,aE,aF,...)table.remove(cv,aN)table.insert(cv,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cv[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cI)cw=aE or self.bgColor;cx=aF or self.fgColor;cy=cI;return self end,mouseHandler=function(self,aO,c5,as,at)if cm.mouseHandler(self,aO,c5,as,at)then local c6,c7=self:getAbsolutePosition(self:getAnchorPosition())if c6<=as and c6+self.width>as and c7<=at and c7+self.height>at and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if aO=="mouse_click"or aO=="monitor_touch"then local bV=0;for aj=1,#cv do if cv[aj]~=nil then if c6+bV<=as+dn and c6+bV+cv[aj].text:len()+d8*2>as+dn and c7==at then self:setValue(cv[aj])self:getEventSystem():sendEvent(aO,self,aO,0,as,at,cv[aj])end;bV=bV+cv[aj].text:len()+d8*2 end end end;if aO=="mouse_scroll"and dk then dn=dn+c5;if dn<0 then dn=0 end;local dq=dp()if dn>dq then dn=dq end end;self:setVisualChanged(true)return true end end;return false end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)local au=""local ds=""local dt=""for aR,du in pairs(cv)do local dv=(" "):rep(d8)..du.text..(" "):rep(d8)au=au..dv;if du==self:getValue()then ds=ds..j[cw or du.bgCol or self.bgColor]:rep(dv:len())dt=dt..j[cx or du.FgCol or self.fgColor]:rep(dv:len())else ds=ds..j[du.bgCol or self.bgColor]:rep(dv:len())dt=dt..j[du.FgCol or self.fgColor]:rep(dv:len())end end;self.parent:setText(cq,cr,au:sub(dn+1,self.width+dn))self.parent:setBG(cq,cr,ds:sub(dn+1,self.width+dn))self.parent:setFG(cq,cr,dt:sub(dn+1,self.width+dn))end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function dw(bI)local cm=bH(bI)local bJ="Pane"local bR={getType=function(self)return bJ end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cq,cr,self.width,self.height,self.bgColor)end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function dx(bI)local cm=bH(bI)local bJ="Program"cm:setZIndex(5)local bR;local function dy(as,at,a9,p)local dz,dA=1,1;local bb,dB=colors.black,colors.white;local dC=false;local dD=false;local aa={}local ab={}local ac={}local dE={}local ag;local ah={}for r=0,15 do local dF=2^r;dE[dF]={h.getPaletteColour(dF)}end;local function ai()ag=(" "):rep(a9)for aj=0,15 do local ak=2^aj;local al=j[ak]ah[ak]=al:rep(a9)end end;local function am()ai()local an=ag;local ao=ah[colors.white]local ap=ah[colors.black]for aj=1,p do aa[aj]=i(aa[aj]==nil and an or aa[aj]..an:sub(1,a9-aa[aj]:len()),1,a9)ac[aj]=i(ac[aj]==nil and ao or ac[aj]..ao:sub(1,a9-ac[aj]:len()),1,a9)ab[aj]=i(ab[aj]==nil and ap or ab[aj]..ap:sub(1,a9-ab[aj]:len()),1,a9)end end;am()local function dG()if dz>=1 and dA>=1 and dz<=a9 and dA<=p then else end end;local function dH(dI,dJ,dK)local dL=dz;local ax=dL+#dI-1;if dA>=1 and dA<=p then if dL<=a9 and ax>=1 then if dL==1 and ax==a9 then aa[dA]=dI;ac[dA]=dJ;ab[dA]=dK else local dM,dN,dO;if dL<1 then local dP=1-dL+1;local dQ=a9-dL+1;dM=i(dI,dP,dQ)dN=i(dJ,dP,dQ)dO=i(dK,dP,dQ)elseif ax>a9 then local dQ=a9-dL+1;dM=i(dI,1,dQ)dN=i(dJ,1,dQ)dO=i(dK,1,dQ)else dM=dI;dN=dJ;dO=dK end;local dR=aa[dA]local dS=ac[dA]local dT=ab[dA]local dU,dV,dW;if dL>1 then local dX=dL-1;dU=i(dR,1,dX)..dM;dV=i(dS,1,dX)..dN;dW=i(dT,1,dX)..dO else dU=dM;dV=dN;dW=dO end;if ax=1 and at<=p then aa[ej]=aa[at]ab[ej]=ab[at]ac[ej]=ac[at]else aa[ej]=eg;ac[ej]=eh;ab[ej]=ei end end end;if dD then dG()end end,isColor=function()return h.isColor()end,isColour=function()return h.isColor()end,write=function(au)au=tostring(au)if dD then dH(au,j[dB]:rep(au:len()),j[bb]:rep(au:len()))end end,clearLine=function()if dD then ar(1,dA,(" "):rep(a9))aA(1,dA,j[bb]:rep(a9))aC(1,dA,j[dB]:rep(a9))end;if dD then dG()end end,clear=function()for aj=1,p do ar(1,aj,(" "):rep(a9))aA(1,aj,j[bb]:rep(a9))aC(1,aj,j[dB]:rep(a9))end;if dD then dG()end end,blit=function(au,ek,el)if type(au)~="string"then error("bad argument #1 (expected string, got "..type(au)..")",2)end;if type(ek)~="string"then error("bad argument #2 (expected string, got "..type(ek)..")",2)end;if type(el)~="string"then error("bad argument #3 (expected string, got "..type(el)..")",2)end;if#ek~=#au or#el~=#au then error("Arguments must be the same length",2)end;if dD then dH(au,ek,el)end end}return eb end;cm.width=30;cm.height=12;local em=dy(1,1,cm.width,cm.height)local en;local eo=false;local ep={}bR={getType=function(self)return bJ end,show=function(self)cm.show(self)em.setBackgroundColor(self.bgColor)em.setTextColor(self.fgColor)em.basalt_setVisible(true)return self end,hide=function(self)cm.hide(self)em.basalt_setVisible(false)return self end,setPosition=function(self,as,at,bX)cm.setPosition(self,as,at,bX)em.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return em end,getBasaltProcess=function()return en end,setSize=function(self,a9,p)cm.setSize(self,a9,p)em.basalt_resize(self.width,self.height)return self end,getStatus=function(self)if en~=nil then return en:getStatus()end;return"inactive"end,execute=function(self,aW,...)en=aU:new(aW,em,...)em.setBackgroundColor(colors.black)em.setTextColor(colors.white)em.clear()em.setCursorPos(1,1)en:resume()eo=false;return self end,stop=function(self)if en~=nil then if not en:isDead()then en:resume("terminate")if en:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,eq)eo=eq or not eo;if en~=nil then if not en:isDead()then if not eo then self:injectEvents(ep)ep={}end end end;return self end,isPaused=function(self)return eo end,injectEvent=function(self,aO,c8,c9,ca,cb,er)if en~=nil then if not en:isDead()then if eo==false or er then en:resume(aO,c8,c9,ca,cb)else table.insert(ep,{event=aO,args={c8,c9,ca,cb}})end end end;return self end,getQueuedEvents=function(self)return ep end,updateQueuedEvents=function(self,aM)ep=aM or ep;return self end,injectEvents=function(self,aM)if en~=nil then if not en:isDead()then for aR,aS in pairs(aM)do en:resume(aS.event,table.unpack(aS.args))end end end;return self end,mouseHandler=function(self,aO,c5,as,at)if cm.mouseHandler(self,aO,c5,as,at)then if en==nil then return false end;if not en:isDead()then if not eo then local es,et=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))en:resume(aO,c5,as-(es-1),at-(et-1))end end;return true end end,keyHandler=function(self,aO,bs)cm.keyHandler(self,aO,bs)if self:isFocused()then if en==nil then return false end;if not en:isDead()then if not eo then if self.draw then en:resume(aO,bs)end end end end end,getFocusHandler=function(self)cm.getFocusHandler(self)if en~=nil then if not en:isDead()then if not eo then if self.parent~=nil then local eu,ev=em.getCursorPos()local cq,cr=self:getAnchorPosition()if self.parent~=nil then if cq+eu-1>=1 and cq+eu-1<=cq+self.width-1 and ev+cr-1>=1 and ev+cr-1<=cr+self.height-1 then self.parent:setCursor(em.getCursorBlink(),cq+eu-1,ev+cr-1,em.getTextColor())end end end end end end end,loseFocusHandler=function(self)cm.loseFocusHandler(self)if en~=nil then if not en:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,aO,c8,c9,ca,cb)if en==nil then return end;if not en:isDead()then if not eo then if aO~="mouse_click"and aO~="monitor_touch"and aO~="mouse_up"and aO~="mouse_scroll"and aO~="mouse_drag"and aO~="key_up"and aO~="key"and aO~="char"and aO~="terminate"then en:resume(aO,c8,c9,ca,cb)end;if self:isFocused()then local cq,cr=self:getAnchorPosition()local eu,ev=em.getCursorPos()if self.parent~=nil then if cq+eu-1>=1 and cq+eu-1<=cq+self.width-1 and ev+cr-1>=1 and ev+cr-1<=cr+self.height-1 then self.parent:setCursor(em.getCursorBlink(),cq+eu-1,ev+cr-1,em.getTextColor())end end;if aO=="terminate"and self:isFocused()then self:stop()end end else if aO~="mouse_click"and aO~="monitor_touch"and aO~="mouse_up"and aO~="mouse_scroll"and aO~="mouse_drag"and aO~="key_up"and aO~="key"and aO~="char"and aO~="terminate"then table.insert(ep,{event=aO,args={c8,c9,ca,cb}})end end end end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()em.basalt_reposition(cq,cr)self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)em.basalt_update()end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function ew(bI)local cm=bH(bI)local bJ="Progressbar"local ex=0;cm:setZIndex(5)cm:setValue(false)cm.width=25;cm.height=1;cm.bgColor=k.CheckboxBG;cm.fgColor=k.CheckboxFG;local ey=colors.black;local ez=""local eA=colors.white;local eB=""local eC=0;local bR={getType=function(self)return bJ end,setDirection=function(self,eD)eC=eD;return self end,setProgressBar=function(self,bZ,aG,eE)ey=bZ or ey;ez=aG or ez;eA=eE or eA;return self end,setBackgroundSymbol=function(self,aG)eB=aG:sub(1,1)return self end,setProgress=function(self,aS)if aS>=0 and aS<=100 and ex~=aS then ex=aS;self:setValue(ex)if ex==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return ex end,onProgressDone=function(self,A)self:registerEvent("progress_done",A)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done")end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cq,cr,self.width,self.height,self.fgColor)self.parent:drawTextBox(cq,cr,self.width,self.height,eB)if eC==1 then self.parent:drawBackgroundBox(cq,cr,self.width,self.height/100*ex,ey)self.parent:drawForegroundBox(cq,cr,self.width,self.height/100*ex,eA)self.parent:drawTextBox(cq,cr,self.width,self.height/100*ex,ez)elseif eC==2 then self.parent:drawBackgroundBox(cq,cr+math.ceil(self.height-self.height/100*ex),self.width,self.height/100*ex,ey)self.parent:drawForegroundBox(cq,cr+math.ceil(self.height-self.height/100*ex),self.width,self.height/100*ex,eA)self.parent:drawTextBox(cq,cr+math.ceil(self.height-self.height/100*ex),self.width,self.height/100*ex,ez)elseif eC==3 then self.parent:drawBackgroundBox(cq+math.ceil(self.width-self.width/100*ex),cr,self.width/100*ex,self.height,ey)self.parent:drawForegroundBox(cq+math.ceil(self.width-self.width/100*ex),cr,self.width/100*ex,self.height,eA)self.parent:drawTextBox(cq+math.ceil(self.width-self.width/100*ex),cr,self.width/100*ex,self.height,ez)else self.parent:drawBackgroundBox(cq,cr,self.width/100*ex,self.height,ey)self.parent:drawForegroundBox(cq,cr,self.width/100*ex,self.height,eA)self.parent:drawTextBox(cq,cr,self.width/100*ex,self.height,ez)end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function eF(bI)local cm=bH(bI)local bJ="Radio"cm.width=8;cm.bgColor=k.listBG;cm.fgColor=k.listFG;cm:setZIndex(5)local cv={}local cw=k.selectionBG;local cx=k.selectionFG;local eG=cm.bgColor;local eH=cm.fgColor;local cy=true;local aG="\7"local cz="left"local bR={getType=function(self)return bJ end,addItem=function(self,au,as,at,aE,aF,...)table.insert(cv,{x=as or 1,y=at or 1,text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})if#cv==1 then self:setValue(cv[1])end;return self end,getAll=function(self)return cv end,removeItem=function(self,aN)table.remove(cv,aN)return self end,getItem=function(self,aN)return cv[aN]end,getItemIndex=function(self)local cH=self:getValue()for bs,aS in pairs(cv)do if aS==cH then return bs end end end,clear=function(self)cv={}self:setValue({})return self end,getItemCount=function(self)return#cv end,editItem=function(self,aN,au,as,at,aE,aF,...)table.remove(cv,aN)table.insert(cv,aN,{x=as or 1,y=at or 1,text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cv[aN]or{})return self end,setSelectedItem=function(self,aE,aF,eI,eJ,cI)cw=aE or cw;cx=aF or cx;eG=eI or eG;eH=eJ or eH;cy=cI;return self end,mouseHandler=function(self,aO,c5,as,at)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and c5==1 or aO=="monitor_touch"then if#cv>0 then for aR,aS in pairs(cv)do if cq+aS.x-1<=as and cq+aS.x-1+aS.text:len()+2>=as and cr+aS.y-1==at then self:setValue(aS)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 cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()for aR,aS in pairs(cv)do if aS==self:getValue()then if cz=="left"then self.parent:writeText(aS.x+cq-1,aS.y+cr-1,aG,eG,eH)self.parent:writeText(aS.x+2+cq-1,aS.y+cr-1,aS.text,cw,cx)end else self.parent:drawBackgroundBox(aS.x+cq-1,aS.y+cr-1,1,1,self.bgColor)self.parent:writeText(aS.x+2+cq-1,aS.y+cr-1,aS.text,aS.bgCol,aS.fgCol)end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function eK(bI)local cm=bH(bI)local bJ="Scrollbar"cm.width=1;cm.height=8;cm.bgColor=colors.lightGray;cm.fgColor=colors.gray;cm:setValue(1)cm:setZIndex(2)local eL="vertical"local aG=" "local eM=colors.black;local eN="\127"local eO=cm.height;local aN=1;local eP=1;local bR={getType=function(self)return bJ end,setSymbol=function(self,eQ)aG=eQ:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,x)eP=tonumber(x)or 1;if eL=="vertical"then self:setValue(aN-1*eO/(self.height-(eP-1))-eO/(self.height-(eP-1)))elseif eL=="horizontal"then self:setValue(aN-1*eO/(self.width-(eP-1))-eO/(self.width-(eP-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,cJ)eO=cJ;return self end,setBackgroundSymbol=function(self,eR)eN=string.sub(eR,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eS)eM=eS;self:setVisualChanged()return self end,setBarType=function(self,eT)eL=eT:lower()return self end,mouseHandler=function(self,aO,c5,as,at)if cm.mouseHandler(self,aO,c5,as,at)then local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if(aO=="mouse_click"or aO=="mouse_drag")and c5==1 or aO=="monitor_touch"then if eL=="horizontal"then for eU=0,self.width do if cq+eU==as and cr<=at and cr+self.height>at then aN=math.min(eU+1,self.width-(eP-1))self:setValue(eO/self.width*aN)self:setVisualChanged()end end end;if eL=="vertical"then for eU=0,self.height do if cr+eU==at and cq<=as and cq+self.width>as then aN=math.min(eU+1,self.height-(eP-1))self:setValue(eO/self.height*aN)self:setVisualChanged()end end end end;if aO=="mouse_scroll"then aN=aN+c5;if aN<1 then aN=1 end;aN=math.min(aN,(eL=="vertical"and self.height or self.width)-(eP-1))self:setValue(eO/(eL=="vertical"and self.height or self.width)*aN)end;return true end end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()if eL=="horizontal"then self.parent:writeText(cq,cr,eN:rep(aN-1),self.bgColor,self.fgColor)self.parent:writeText(cq+aN-1,cr,aG:rep(eP),eM,eM)self.parent:writeText(cq+aN+eP-1,cr,eN:rep(self.width-(aN+eP-1)),self.bgColor,self.fgColor)end;if eL=="vertical"then for aj=0,self.height-1 do if aN==aj+1 then for eV=0,math.min(eP-1,self.height)do self.parent:writeText(cq,cr+aj+eV,aG,eM,eM)end else if aj+1aN-1+eP then self.parent:writeText(cq,cr+aj,eN,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function eW(bI)local cm=bH(bI)local bJ="Slider"cm.width=8;cm.height=1;cm.bgColor=colors.lightGray;cm.fgColor=colors.gray;cm:setValue(1)local eL="horizontal"local aG=" "local eM=colors.black;local eN="\140"local eO=cm.width;local aN=1;local eP=1;local bR={getType=function(self)return bJ end,setSymbol=function(self,eQ)aG=eQ:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,x)eP=tonumber(x)or 1;if eL=="vertical"then self:setValue(aN-1*eO/(self.height-(eP-1))-eO/(self.height-(eP-1)))elseif eL=="horizontal"then self:setValue(aN-1*eO/(self.width-(eP-1))-eO/(self.width-(eP-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,cJ)eO=cJ;return self end,setBackgroundSymbol=function(self,eR)eN=string.sub(eR,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eS)eM=eS;self:setVisualChanged()return self end,setBarType=function(self,eT)eL=eT:lower()return self end,mouseHandler=function(self,aO,c5,as,at)if cm.mouseHandler(self,aO,c5,as,at)then local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if(aO=="mouse_click"or aO=="mouse_drag")and c5==1 or aO=="monitor_touch"then if eL=="horizontal"then for eU=0,self.width do if cq+eU==as and cr<=at and cr+self.height>at then aN=math.min(eU+1,self.width-(eP-1))self:setValue(eO/self.width*aN)self:setVisualChanged()end end end;if eL=="vertical"then for eU=0,self.height do if cr+eU==at and cq<=as and cq+self.width>as then aN=math.min(eU+1,self.height-(eP-1))self:setValue(eO/self.height*aN)self:setVisualChanged()end end end end;if aO=="mouse_scroll"then aN=aN+c5;if aN<1 then aN=1 end;aN=math.min(aN,(eL=="vertical"and self.height or self.width)-(eP-1))self:setValue(eO/(eL=="vertical"and self.height or self.width)*aN)end;return true end end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()if eL=="horizontal"then self.parent:writeText(cq,cr,eN:rep(aN-1),self.bgColor,self.fgColor)self.parent:writeText(cq+aN-1,cr,aG:rep(eP),eM,eM)self.parent:writeText(cq+aN+eP-1,cr,eN:rep(self.width-(aN+eP-1)),self.bgColor,self.fgColor)end;if eL=="vertical"then for aj=0,self.height-1 do if aN==aj+1 then for eV=0,math.min(eP-1,self.height)do self.parent:writeText(cq,cr+aj+eV,aG,eM,eM)end else if aj+1aN-1+eP then self.parent:writeText(cq,cr+aj,eN,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function eX(bI)local cm=bH(bI)local bJ="Switch"cm.width=2;cm.height=1;cm.bgColor=colors.lightGray;cm.fgColor=colors.gray;cm:setValue(false)cm:setZIndex(5)local eN=colors.black;local eY=colors.red;local eZ=colors.green;local bR={getType=function(self)return bJ end,setSymbolColor=function(self,eM)eN=eM;self:setVisualChanged()return self end,setActiveBackground=function(self,el)eZ=el;self:setVisualChanged()return self end,setInactiveBackground=function(self,el)eY=el;self:setVisualChanged()return self end,mouseHandler=function(self,aO,c5,as,at)if cm.mouseHandler(self,aO,c5,as,at)then local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and c5==1 or aO=="monitor_touch"then self:setValue(not self:getValue())end;return true end end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)if self:getValue()then self.parent:drawBackgroundBox(cq,cr,1,self.height,eZ)self.parent:drawBackgroundBox(cq+1,cr,1,self.height,eN)else self.parent:drawBackgroundBox(cq,cr,1,self.height,eN)self.parent:drawBackgroundBox(cq+1,cr,1,self.height,eY)end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function e_(bI)local cm=bH(bI)local bJ="Textfield"local f0,cW,cV,f1=1,1,1,1;local f2={""}local f3={[colors.purple]={"break"}}cm.width=20;cm.height=8;cm.bgColor=k.textfieldBG;cm.fgColor=k.textfieldFG;cm:setZIndex(5)local bR={getType=function(self)return bJ end,getLines=function(self)return f2 end,getLine=function(self,aN)return f2[aN]or""end,editLine=function(self,aN,au)f2[aN]=au or f2[aN]return self end,addLine=function(self,au,aN)if aN~=nil then table.insert(f2,aN,au)else table.insert(f2,au)end;return self end,addKeyword=function(self,f4,bZ)end,removeLine=function(self,aN)table.remove(f2,aN or#f2)if#f2<=0 then table.insert(f2,"")end;return self end,getTextCursor=function(self)return cV,f1 end,getFocusHandler=function(self)cm.getFocusHandler(self)if self.parent~=nil then local cq,cr=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,cq+cV-cW,cr+f1-f0,self.fgColor)end end end,loseFocusHandler=function(self)cm.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,aO,bs)if cm.keyHandler(self,aO,bs)then local cq,cr=self:getAnchorPosition()if aO=="key"then if bs==keys.backspace then if f2[f1]==""then if f1>1 then table.remove(f2,f1)cV=f2[f1-1]:len()+1;cW=cV-self.width+1;if cW<1 then cW=1 end;f1=f1-1 end elseif cV<=1 then if f1>1 then cV=f2[f1-1]:len()+1;cW=cV-self.width+1;if cW<1 then cW=1 end;f2[f1-1]=f2[f1-1]..f2[f1]table.remove(f2,f1)f1=f1-1 end else f2[f1]=f2[f1]:sub(1,cV-2)..f2[f1]:sub(cV,f2[f1]:len())if cV>1 then cV=cV-1 end;if cW>1 then if cVf2[f1]:len()then if f2[f1+1]~=nil then f2[f1]=f2[f1]..f2[f1+1]table.remove(f2,f1+1)end else f2[f1]=f2[f1]:sub(1,cV-1)..f2[f1]:sub(cV+1,f2[f1]:len())end end;if bs==keys.enter then table.insert(f2,f1+1,f2[f1]:sub(cV,f2[f1]:len()))f2[f1]=f2[f1]:sub(1,cV-1)f1=f1+1;cV=1;cW=1;if f1-f0>=self.height then f0=f0+1 end;self:setValue("")end;if bs==keys.up then if f1>1 then f1=f1-1;if cV>f2[f1]:len()+1 then cV=f2[f1]:len()+1 end;if cW>1 then if cV1 then if f1f2[f1]:len()+1 then cV=f2[f1]:len()+1 end;if f1>=f0+self.height then f0=f0+1 end end end;if bs==keys.right then cV=cV+1;if f1<#f2 then if cV>f2[f1]:len()+1 then cV=1;f1=f1+1 end elseif cV>f2[f1]:len()then cV=f2[f1]:len()+1 end;if cV<1 then cV=1 end;if cV=self.width+cW then cW=cV-self.width+1 end;if cW<1 then cW=1 end end;if bs==keys.left then cV=cV-1;if cV>=1 then if cV=self.width+cW then cW=cV end end;if f1>1 then if cV<1 then f1=f1-1;cV=f2[f1]:len()+1;cW=cV-self.width+1 end end;if cV<1 then cV=1 end;if cW<1 then cW=1 end end end;if aO=="char"then f2[f1]=f2[f1]:sub(1,cV-1)..bs..f2[f1]:sub(cV,f2[f1]:len())cV=cV+1;if cV>=self.width+cW then cW=cW+1 end;self:setValue("")end;local d7=(cV<=f2[f1]:len()and cV-1 or f2[f1]:len())-(cW-1)if d7>self.x+self.width-1 then d7=self.x+self.width-1 end;local f5=f1-f0f2[f1]:len()then cV=f2[f1]:len()+1 end;if cVf2[f1]:len()then cV=f2[f1]:len()+1 end;if cV#f2-(self.height-1)then f0=#f2-(self.height-1)end;if f0<1 then f0=1 end;if self.parent~=nil then if cq+cV-cW>=cq and cq+cV-cW<=cq+self.width and(cr+f1-f0>=cr and cr+f1-f0<=cr+self.height)then self.parent:setCursor(true,f6+cV-cW,f7+f1-f0,self.fgColor)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if cm.draw(self)then if self.parent~=nil then local cq,cr=self:getAnchorPosition()self.parent:drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cq,cr,self.width,self.height,self.fgColor)for aj=1,self.height do local au=""if f2[aj+f0-1]~=nil then au=f2[aj+f0-1]end;au=au:sub(cW,self.width+cW-1)local d8=self.width-au:len()if d8<0 then d8=0 end;au=au..string.rep(" ",d8)self.parent:setText(cq,cr+aj-1,au)end end;self:setVisualChanged(false)end end}return setmetatable(bR,cm)end;local function f8(bI)local bR;local bJ="Thread"local aQ;local f9;local fa=false;bR={name=bI,getType=function(self)return bJ end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,A)if A==nil then error("Function provided to thread is nil")end;aQ=A;f9=coroutine.create(aQ)fa=true;local a_,b0=coroutine.resume(f9)if not a_ then if b0~="Terminated"then error("Thread Error Occurred - "..b0)end end;return self end,getStatus=function(self,A)if f9~=nil then return coroutine.status(f9)end;return nil end,stop=function(self,A)fa=false;return self end,eventHandler=function(self,aO,c8,c9,ca)if fa then if coroutine.status(f9)~="dead"then local a_,b0=coroutine.resume(f9,aO,c8,c9,ca)if not a_ then if b0~="Terminated"then error("Thread Error Occurred - "..b0)end end else fa=false end end end}bR.__index=bR;return bR end;local function fb(bI)local bJ="Timer"local fc=0;local fd=0;local fe=0;local cd;local bQ=aL()local ff=false;local bR={name=bI,getType=function(self)return bJ end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,fg,fh)fc=fg or 0;fd=fh or 1;return self end,start=function(self)if ff then os.cancelTimer(cd)end;fe=fd;cd=os.startTimer(fc)ff=true;return self end,isActive=function(self)return ff end,cancel=function(self)if cd~=nil then os.cancelTimer(cd)end;ff=false;return self end,onCall=function(self,aQ)bQ:registerEvent("timed_event",aQ)return self end,eventHandler=function(self,aO,ck)if aO=="timer"and ck==cd and ff then bQ:sendEvent("timed_event",self)if fe>=1 then fe=fe-1;if fe>=1 then cd=os.startTimer(fc)end elseif fe==-1 then cd=os.startTimer(fc)end end end}bR.__index=bR;return bR end;local function fi(bI,fj)local cm=bH(bI)local bJ="Frame"local fk={}local fl={}local bR={}local fm=h;local fn=""local fo=false;local fp=false;local fq=0;cm:setZIndex(10)local aD=a6(fm)local dC=false;local dz=1;local dA=1;local fr=colors.white;local fs,cA=0,0;if fj~=nil then cm.parent=fj;cm.width,cm.height=fj:getSize()cm.bgColor=k.FrameBG;cm.fgColor=k.FrameFG else cm.width,cm.height=fm.getSize()cm.bgColor=k.basaltBG;cm.fgColor=k.basaltFG end;local function ft(bI)for aR,aS in pairs(fk)do for aR,bu in pairs(aS)do if bu.name==bI then return aS end end end end;local function fu(fv)local bK=fv:getZIndex()if ft(fv.name)~=nil then return nil end;if fk[bK]==nil then for as=1,#fl+1 do if fl[as]~=nil then if bK==fl[as]then break end;if bK>fl[as]then table.insert(fl,as,bK)break end else table.insert(fl,bK)end end;if#fl<=0 then table.insert(fl,bK)end;fk[bK]={}end;fv.parent=bR;table.insert(fk[bK],fv)return fv end;local function fw(fv)for bt,bu in pairs(fk)do for bs,aS in pairs(bu)do if aS==fv then table.remove(fk[bt],bs)return true end end end;return false end;bR={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return bJ end,setFocusedObject=function(self,fv)if c~=nil then c:loseFocusHandler()c=nil end;if fv~=nil then c=fv;fv:getFocusHandler()end;return self end,setOffset=function(self,c2,c3)fs=c2~=nil and math.floor(c2<0 and math.abs(c2)or-c2)or fs;cA=c3~=nil and math.floor(c3<0 and math.abs(c3)or-c3)or cA;return self end,getFrameOffset=function(self)return fs,cA end,removeFocusedObject=function(self)if c~=nil then c:loseFocusHandler()end;c=nil;return self end,getFocusedObject=function(self)return c end,setCursor=function(self,fx,fy,fz,bZ)if self.parent~=nil then local cq,cr=self:getAnchorPosition()self.parent:setCursor(fx or false,(fy or 0)+cq-1,(fz or 0)+cr-1,bZ or fr)else local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())dC=fx or false;if fy~=nil then dz=cq+fy-1 end;if fz~=nil then dA=cr+fz-1 end;fr=bZ or fr;self:setVisualChanged()end;return self end,setMoveable=function(self,fA)self.isMoveable=fA or not self.isMoveable;self:setVisualChanged()return self end,show=function(self)cm.show(self)if self.parent==nil then e=self;if fo then g[fn]=self else f=self end end;return self end,hide=function(self)cm.hide(self)if self.parent==nil then if e==self then e=nil end;if fo then if g[fn]==self then g[fn]=nil end else if f==self then f=nil end end end;return self end,showBar=function(self,fB)self.barActive=fB or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,au,aE,aF)self.barText=au or""self.barBackground=aE or self.barBackground;self.barTextcolor=aF or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,cz)self.barTextAlign=cz or"left"self:setVisualChanged()return self end,setMonitor=function(self,fC)if fC~=nil or fC~=false then if peripheral.getType(fC)=="monitor"then fm=peripheral.wrap(fC)fp=true end;fo=true else fm=h;fo=false;if g[fn]==self then g[fn]=nil end end;aD=a6(fm)fn=fC or nil;return self end,getVisualChanged=function(self)local fD=cm.getVisualChanged(self)for aR,aN in pairs(fl)do if fk[aN]~=nil then for aR,aS in pairs(fk[aN])do if aS.getVisualChanged~=nil and aS:getVisualChanged()then fD=true end end end end;return fD end,loseFocusHandler=function(self)cm.loseFocusHandler(self)end,getFocusHandler=function(self)cm.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,aO,bs)if c~=nil then if c~=self then if c.keyHandler~=nil then if c:keyHandler(aO,bs)then return true end end else cm.keyHandler(self,aO,bs)end end;return false end,backgroundKeyHandler=function(self,aO,bs)cm.backgroundKeyHandler(self,aO,bs)for aR,aN in pairs(fl)do if fk[aN]~=nil then for aR,aS in pairs(fk[aN])do if aS.backgroundKeyHandler~=nil then aS:backgroundKeyHandler(aO,bs)end end end end end,eventHandler=function(self,aO,c8,c9,ca,cb)cm.eventHandler(self,aO,c8,c9,ca,cb)for aR,aN in pairs(fl)do if fk[aN]~=nil then for aR,aS in pairs(fk[aN])do if aS.eventHandler~=nil then aS:eventHandler(aO,c8,c9,ca,cb)end end end end;if fo then if aO=="peripheral"and c8==fn then if peripheral.getType(fn)=="monitor"then fp=true;fm=peripheral.wrap(fn)aD=a6(fm)end end;if aO=="peripheral_detach"and c8==fn then fp=false end end;if aO=="terminate"then fm.clear()fm.setCursorPos(1,1)a.stop()end end,mouseHandler=function(self,aO,c5,as,at)local c2,c3=self:getOffset()c2=c2<0 and math.abs(c2)or-c2;c3=c3<0 and math.abs(c3)or-c3;if self.drag then if aO=="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(as+fq-(fE-1)+c2,at-(fF-1)+c3)end;if aO=="mouse_up"then self.drag=false end;return true end;if cm.mouseHandler(self,aO,c5,as,at)then local b_,c0=self:getAbsolutePosition(self:getAnchorPosition())b_=b_+fs;c0=c0+cA;for aR,aN in pairs(fl)do if fk[aN]~=nil then for aR,aS in b7(fk[aN])do if aS.mouseHandler~=nil then if aS:mouseHandler(aO,c5,as,at)then return true end end end end end;if self.isMoveable then if as>=b_ and as<=b_+self.width-1 and at==c0 and aO=="mouse_click"then self.drag=true;fq=b_-as end end;if c~=nil then c:loseFocusHandler()c=nil end;return true end;return false end,setText=function(self,as,at,au)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fE,fF=self.parent:getAnchorPosition()self.parent:setText(math.max(as+cq-1,cq)-(fE-1),cr+at-1-(fF-1),i(au,math.max(1-as+1,1),self.width-as+1))else aD.setText(math.max(as+cq-1,cq),cr+at-1,i(au,math.max(1-as+1,1),self.width-as+1))end end end,setBG=function(self,as,at,aE)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fE,fF=self.parent:getAnchorPosition()self.parent:setBG(math.max(as+cq-1,cq)-(fE-1),cr+at-1-(fF-1),i(aE,math.max(1-as+1,1),self.width-as+1))else aD.setBG(math.max(as+cq-1,cq),cr+at-1,i(aE,math.max(1-as+1,1),self.width-as+1))end end end,setFG=function(self,as,at,aF)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fE,fF=self.parent:getAnchorPosition()self.parent:setFG(math.max(as+cq-1,cq)-(fE-1),cr+at-1-(fF-1),i(aF,math.max(1-as+1,1),self.width-as+1))else aD.setFG(math.max(as+cq-1,cq),cr+at-1,i(aF,math.max(1-as+1,1),self.width-as+1))end end end,writeText=function(self,as,at,au,aE,aF)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fE,fF=self.parent:getAnchorPosition()self.parent:writeText(math.max(as+cq-1,cq)-(fE-1),cr+at-1-(fF-1),i(au,math.max(1-as+1,1),self.width-as+1),aE,aF)else aD.writeText(math.max(as+cq-1,cq),cr+at-1,i(au,math.max(1-as+1,1),self.width-as+1),aE,aF)end end end,drawBackgroundBox=function(self,as,at,a9,p,aE)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fE,fF=self.parent:getAnchorPosition()self.parent:drawBackgroundBox(math.max(as+cq-1,cq)-(fE-1),math.max(at+cr-1,cr)-(fF-1),a9,p,aE)else aD.drawBackgroundBox(math.max(as+cq-1,cq),math.max(at+cr-1,cr),a9,p,aE)end end,drawTextBox=function(self,as,at,a9,p,aG)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fE,fF=self.parent:getAnchorPosition()self.parent:drawTextBox(math.max(as+cq-1,cq)-(fE-1),math.max(at+cr-1,cr)-(fF-1),a9,p,aG:sub(1,1))else aD.drawTextBox(math.max(as+cq-1,cq),math.max(at+cr-1,cr),a9,p,aG:sub(1,1))end end,drawForegroundBox=function(self,as,at,a9,p,aF)local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fE,fF=self.parent:getAnchorPosition()self.parent:drawForegroundBox(math.max(as+cq-1,cq)-(fE-1),math.max(at+cr-1,cr)-(fF-1),a9,p,aF)else aD.drawForegroundBox(math.max(as+cq-1,cq),math.max(at+cr-1,cr),a9,p,aF)end end,draw=function(self)if fo and not fp then return false end;if self:getVisualChanged()then if cm.draw(self)then local cq,cr=self:getAbsolutePosition(self:getAnchorPosition())local f6,f7=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(f6,f7,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(f6,f7,self.width,self.height,self.fgColor)self.parent:drawTextBox(f6,f7,self.width,self.height," ")else aD.drawBackgroundBox(cq,cr,self.width,self.height,self.bgColor)aD.drawForegroundBox(cq,cr,self.width,self.height,self.fgColor)aD.drawTextBox(cq,cr,self.width,self.height," ")end;fm.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(f6,f7,b1(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)else aD.writeText(cq,cr,b1(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)end end;for aR,aN in b7(fl)do if fk[aN]~=nil then for aR,aS in pairs(fk[aN])do if aS.draw~=nil then aS:draw()end end end end;if dC then fm.setTextColor(fr)fm.setCursorPos(dz,dA)if self.parent~=nil then fm.setCursorBlink(self:isFocused())else fm.setCursorBlink(dC)end end;self:setVisualChanged(false)end end end,drawUpdate=function(self)if fo and not fp then return false end;aD.update()end,addObject=function(self,fv)return fu(fv)end,removeObject=function(self,fv)return fw(fv)end,getObject=function(self,fv)return ft(fv)end,addButton=function(self,bI)local fv=cl(bI)fv.name=bI;return fu(fv)end,addLabel=function(self,bI)local fv=d9(bI)fv.bgColor=self.bgColor;fv.fgColor=self.fgColor;return fu(fv)end,addCheckbox=function(self,bI)local fv=ct(bI)return fu(fv)end,addInput=function(self,bI)local fv=cS(bI)return fu(fv)end,addProgram=function(self,bI)local fv=dx(bI)return fu(fv)end,addTextfield=function(self,bI)local fv=e_(bI)return fu(fv)end,addList=function(self,bI)local fv=dj(bI)fv.name=nam;return fu(fv)end,addDropdown=function(self,bI)local fv=cu(bI)return fu(fv)end,addRadio=function(self,bI)local fv=eF(bI)return fu(fv)end,addTimer=function(self,bI)local fv=fb(bI)return fu(fv)end,addAnimation=function(self,bI)local fv=cc(bI)return fu(fv)end,addSlider=function(self,bI)local fv=eW(bI)return fu(fv)end,addScrollbar=function(self,bI)local fv=eK(bI)return fu(fv)end,addMenubar=function(self,bI)local fv=dm(bI)return fu(fv)end,addThread=function(self,bI)local fv=f8(bI)return fu(fv)end,addPane=function(self,bI)local fv=dw(bI)return fu(fv)end,addImage=function(self,bI)local fv=cK(bI)return fu(fv)end,addProgressbar=function(self,bI)local fv=ew(bI)return fu(fv)end,addSwitch=function(self,bI)local fv=eX(bI)return fu(fv)end,addFrame=function(self,bI)local fv=fi(bI,self)return fu(fv)end}setmetatable(bR,cm)return bR end;local function fG()f:draw()f:drawUpdate()for aR,du in pairs(g)do du:draw()du:drawUpdate()end end;local fH=false;local function fI(aO,c8,c9,ca,cb)if f~=nil then if aO=="mouse_click"then f:mouseHandler(aO,c8,c9,ca,cb)e=f elseif aO=="mouse_drag"then f:mouseHandler(aO,c8,c9,ca,cb)e=f elseif aO=="mouse_up"then f:mouseHandler(aO,c8,c9,ca,cb)e=f elseif aO=="mouse_scroll"then f:mouseHandler(aO,c8,c9,ca,cb)e=f elseif aO=="monitor_touch"then if g[c8]~=nil then g[c8]:mouseHandler(aO,c8,c9,ca,cb)e=g[c8]end end end;if aO=="key"or aO=="char"then e:keyHandler(aO,c8)e:backgroundKeyHandler(aO,c8)end;if aO=="key"then b[c8]=true end;if aO=="key_up"then b[c8]=false end;for aR,du in pairs(d)do du:eventHandler(aO,c8,c9,ca,cb)end;if fH then fG()end end;function a.autoUpdate(fa)fH=fa;if fa==nil then fH=true end;fG()while fH do local aO,c8,c9,ca,cb=os.pullEventRaw()fI(aO,c8,c9,ca,cb)end end;function a.update(aO,c8,c9,ca,cb)if aO~=nil then fI(aO,c8,c9,ca,cb)else fG()end end;function a.stop()fH=false end;function a.isKeyDown(bs)if b[bs]==nil then return false end;return b[bs]end;function a.getFrame(bI)for aR,aS in pairs(d)do if aS.name==bI then return aS end end end;function a.getActiveFrame()return e end;function a.setActiveFrame(bS)if bS:getType()=="Frame"then e=bS;return true end;return false end;function a.createFrame(bI)for aR,du in pairs(d)do if du.name==bI then return nil end end;local fJ=fi(bI)table.insert(d,fJ)return fJ end;function a.removeFrame(bI)d[bI]=nil 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=f;a.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):ignoreOffset():setZIndex(20):show()end;if a.debugger then function a.debug(...)local aY={...}if f.name~="basaltDebuggingFrame"then if f~=a.debugFrame then a.debugLabel:setParent(f)end end;local fK=""for bs,aS in pairs(aY)do fK=fK..tostring(aS)..(#aY~=bs and", "or"")end;a.debugLabel:setText("[Debug] "..fK)a.debugList:addItem(fK)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 +local a={debugger=true,version=1}local b={}local c;local d={}local e;local f;local g={}local h=term.current()local i=string.sub;local j={[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 k={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 l={{"\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 m={}local n={}do local o=0;local p=#l[1]local q=#l[1][1]for r=1,p,3 do for s=1,q,3 do local t=string.char(o)local u={}u[1]=l[1][r]:sub(s,s+2)u[2]=l[1][r+1]:sub(s,s+2)u[3]=l[1][r+2]:sub(s,s+2)local v={}v[1]=l[2][r]:sub(s,s+2)v[2]=l[2][r+1]:sub(s,s+2)v[3]=l[2][r+2]:sub(s,s+2)n[t]={u,v}o=o+1 end end;m[1]=n end;local function w(x,y)local z={["0"]="1",["1"]="0"}if x<=#m then return true end;for A=#m+1,x do local B={}local C=m[A-1]for o=0,255 do local t=string.char(o)local u={}local v={}local D=C[t][1]local E=C[t][2]for r=1,#D do local F,G,H,I,J,K={},{},{},{},{},{}for s=1,#D[1]do local L=n[D[r]:sub(s,s)][1]table.insert(F,L[1])table.insert(G,L[2])table.insert(H,L[3])local M=n[D[r]:sub(s,s)][2]if E[r]:sub(s,s)=="1"then table.insert(I,M[1]:gsub("[01]",z))table.insert(J,M[2]:gsub("[01]",z))table.insert(K,M[3]:gsub("[01]",z))else table.insert(I,M[1])table.insert(J,M[2])table.insert(K,M[3])end end;table.insert(u,table.concat(F))table.insert(u,table.concat(G))table.insert(u,table.concat(H))table.insert(v,table.concat(I))table.insert(v,table.concat(J))table.insert(v,table.concat(K))end;B[t]={u,v}if y then y="Font"..A.."Yeld"..o;os.queueEvent(y)os.pullEvent(y)end end;m[A]=B end;return true end;local function N(O,P,Q,R,S)if not type(P)=="string"then error("Not a String",3)end;local T=type(Q)=="string"and Q:sub(1,1)or j[Q]or error("Wrong Front Color",3)local U=type(R)=="string"and R:sub(1,1)or j[R]or error("Wrong Back Color",3)if m[O]==nil then w(3,false)end;local V=m[O]or error("Wrong font size selected",3)if P==""then return{{""},{""},{""}}end;local W={}for r in P:gmatch('.')do table.insert(W,r)end;local X={}local p=#V[W[1]][1]for Y=1,p do local Z={}for r=1,#W do Z[r]=V[W[r]]and V[W[r]][1][Y]or""end;X[Y]=table.concat(Z)end;local _={}local a0={}local a1={["0"]=T,["1"]=U}local a2={["0"]=U,["1"]=T}for Y=1,p do local a3={}local a4={}for r=1,#W do local a5=V[W[r]]and V[W[r]][2][Y]or""a3[r]=a5:gsub("[01]",S and{["0"]=Q:sub(r,r),["1"]=R:sub(r,r)}or a1)a4[r]=a5:gsub("[01]",S and{["0"]=R:sub(r,r),["1"]=Q:sub(r,r)}or a2)end;_[Y]=table.concat(a3)a0[Y]=table.concat(a4)end;return{X,_,a0}end;local function a6(a7)local a8=a7;local a9,p=a8.getSize()local aa={}local ab={}local ac={}local ad={}local ae={}local af={}local ag;local ah={}local function ai()ag=(" "):rep(a9)for aj=0,15 do local ak=2^aj;local al=j[ak]ah[ak]=al:rep(a9)end end;ai()local function am()local an=ag;local ao=ah[colors.white]local ap=ah[colors.black]for aq=1,p do aa[aq]=i(aa[aq]==nil and an or aa[aq]..an:sub(1,a9-aa[aq]:len()),1,a9)ac[aq]=i(ac[aq]==nil and ao or ac[aq]..ao:sub(1,a9-ac[aq]:len()),1,a9)ab[aq]=i(ab[aq]==nil and ap or ab[aq]..ap:sub(1,a9-ab[aq]:len()),1,a9)end end;am()local function ar(as,at,au)if at>=1 and at<=p then if as+au:len()>0 and as<=a9 then local av=aa[at]local aw;local ax=as+#au-1;if as<1 then local ay=1-as+1;local az=a9-as+1;au=i(au,ay,az)elseif ax>a9 then local az=a9-as+1;au=i(au,1,az)end;if as>1 then local az=as-1;aw=i(av,1,az)..au else aw=au end;if ax=1 and at<=p then if as+aB:len()>0 and as<=a9 then local av=ab[at]local aw;local ax=as+#aB-1;if as<1 then aB=i(aB,1-as+1,a9-as+1)elseif ax>a9 then aB=i(aB,1,a9-as+1)end;if as>1 then aw=i(av,1,as-1)..aB else aw=aB end;if ax=1 and at<=p then if as+aB:len()>0 and as<=a9 then local av=ac[at]local aw;local ax=as+#aB-1;if as<1 then local ay=1-as+1;local az=a9-as+1;aB=i(aB,ay,az)elseif ax>a9 then local az=a9-as+1;aB=i(aB,1,az)end;if as>1 then local az=as-1;aw=i(av,1,az)..aB else aw=aB end;if ax1 then while#bm>2 do table.sort(bm,function(bw,bx)return bw[2]>bx[2]end)local by,bz=bl(bm),#bm;local bA,bB=bm[bz][1],bm[by][1]for r=1,6 do if bq[r]==bA then bq[r]=bB;bm[by][2]=bm[by][2]+1 end end;bm[bz]=nil end;local bC=128;for r=1,#bq-1 do if bq[r]~=bq[6]then bC=bC+2^(r-1)end end;return string.char(bC),bi[bm[1][1]==bq[6]and bm[2][1]or bm[1][1]],bi[bq[6]]else return"\128",bi[bq[1]],bi[bq[1]]end end;local bD,a9,p,aE={{},{},{}},0,#bd+#bd%3,be or colors.black;for r=1,#bd do if#bd[r]>a9 then a9=#bd[r]end end;for at=0,p-1,3 do local bE,bF,bG,bH={},{},{},1;for as=0,a9-1,2 do local bq,br={},{}for bI=1,3 do for bJ=1,2 do bq[#bq+1]=bd[at+bI]and bd[at+bI][as+bJ]and(bd[at+bI][as+bJ]==0 and aE or bd[at+bI][as+bJ])or aE;br[bq[#bq]]=br[bq[#bq]]and br[bq[#bq]]+1 or 1 end end;bE[bH],bF[bH],bG[bH]=bp(bq,br)bH=bH+1 end;bD[1][#bD[1]+1],bD[2][#bD[2]+1],bD[3][#bD[3]+1]=table.concat(bE),table.concat(bF),table.concat(bG)end;bD.width,bD.height=#bD[1][1],#bD[1]return bD end;local function bK(bL)local bM="Object"local aT;local bN=1;local bO="topLeft"local bP=false;local bQ=false;local bR=false;local bS=false;local bT=false;local bU=false;local bV=false;local bW=colors.black;local bX=colors.black;local bY=true;local aV=aL()local bZ={x=1,y=1,width=1,height=1,bgColor=colors.black,fgColor=colors.white,name=bL or"Object",parent=nil,show=function(self)bQ=true;bY=true;return self end,hide=function(self)bQ=false;bY=true;return self end,isVisible=function(self)return bQ end,setFocus=function(self)if self.parent~=nil then self.parent:setFocusedObject(self)end;return self end,setZIndex=function(self,aN)bN=aN;if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end;return self end,getZIndex=function(self)return bN end,getType=function(self)return bM 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,b_)if b_.getType~=nil and b_:getType()=="Frame"then self:remove()b_:addObject(self)if self.draw then self:show()end end;return self end,setValue=function(self,c0)if aT~=c0 then aT=c0;bY=true;self:valueChangedHandler()end;return self end,getValue=function(self)return aT end,getVisualChanged=function(self)return bY end,setVisualChanged=function(self,c1)bY=c1 or true;if c1==nil then bY=true end;return self end,getEventSystem=function(self)return aV end,getParent=function(self)return self.parent end,setPosition=function(self,c2,c3,c4)if c4 then self.x,self.y=math.floor(self.x+c2),math.floor(self.y+c3)else self.x,self.y=math.floor(c2),math.floor(c3)end;bY=true;return self end,getPosition=function(self)return self.x,self.y end,getVisibility=function(self)return bQ end,setVisibility=function(self,c5)bQ=c5 or not bQ;bY=true;return self end,setSize=function(self,a9,p)self.width,self.height=a9,p;bY=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,c6)self.bgColor=c6;bY=true;return self end,getBackground=function(self)return self.bgColor end,setForeground=function(self,c6)self.fgColor=c6;bY=true;return self end,getForeground=function(self)return self.fgColor end,showShadow=function(self,c7)bR=c7 or not bR;return self end,setShadow=function(self,c6)bW=c6;return self end,isShadowActive=function(self)return bR end,showBorder=function(self,...)for aS,c8 in pairs(table.pack(...))do if c8=="left"then bS=true end;if c8=="top"then bT=true end;if c8=="right"then bU=true end;if c8=="bottom"then bV=true end end;return self end,setBorder=function(self,c6)bW=c6;return self end,getBorder=function(self,c9)if c9=="left"then return bS end;if c9=="top"then return bT end;if c9=="right"then return bU end;if c9=="bottom"then return bV end end,draw=function(self)if bQ then if self.parent~=nil then local as,at=self:getAnchorPosition()if bR then self.parent:drawBackgroundBox(as+1,at+self.height,self.width,1,bW)self.parent:drawBackgroundBox(as+self.width,at+1,1,self.height,bW)self.parent:drawForegroundBox(as+1,at+self.height,self.width,1,bW)self.parent:drawForegroundBox(as+self.width,at+1,1,self.height,bW)end;if bS then self.parent:drawTextBox(as-1,at,1,self.height,"\149")self.parent:drawForegroundBox(as-1,at,1,self.height,bX)if self.bgColor~=false then self.parent:drawBackgroundBox(as-1,at,1,self.height,self.bgColor)end end;if bS and bT then self.parent:drawTextBox(as-1,at-1,1,1,"\151")self.parent:drawForegroundBox(as-1,at-1,1,1,bX)if self.bgColor~=false then self.parent:drawBackgroundBox(as-1,at-1,1,1,self.bgColor)end end;if bT then self.parent:drawTextBox(as,at-1,self.width,1,"\131")self.parent:drawForegroundBox(as,at-1,self.width,1,bX)if self.bgColor~=false then self.parent:drawBackgroundBox(as,at-1,self.width,1,self.bgColor)end end;if bT and bU then self.parent:drawTextBox(as+self.width,at-1,1,1,"\149")self.parent:drawForegroundBox(as+self.width,at-1,1,1,bX)end;if bU then self.parent:drawTextBox(as+self.width,at,1,self.height,"\149")self.parent:drawForegroundBox(as+self.width,at,1,self.height,bX)end;if bU and bV then self.parent:drawTextBox(as+self.width,at+self.height,1,1,"\129")self.parent:drawForegroundBox(as+self.width,at+self.height,1,1,bX)end;if bV then self.parent:drawTextBox(as,at+self.height,self.width,1,"\131")self.parent:drawForegroundBox(as,at+self.height,self.width,1,bX)end;if bV and bS then self.parent:drawTextBox(as-1,at+self.height,1,1,"\131")self.parent:drawForegroundBox(as-1,at+self.height,1,1,bX)end end;return true end;return false end,getAbsolutePosition=function(self,as,at)if as==nil or at==nil then as,at=self:getAnchorPosition()end;if self.parent~=nil then local ca,cb=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())as=ca+as-1;at=cb+at-1 end;return as,at end,getAnchorPosition=function(self,as,at,cc)if as==nil then as=self.x end;if at==nil then at=self.y end;if bO=="top"then as=math.floor(self.parent.width/2)+as-1 elseif bO=="topRight"then as=self.parent.width+as-1 elseif bO=="right"then as=self.parent.width+as-1;at=math.floor(self.parent.height/2)+at-1 elseif bO=="bottomRight"then as=self.parent.width+as-1;at=self.parent.height+at-1 elseif bO=="bottom"then as=math.floor(self.parent.width/2)+as-1;at=self.parent.height+at-1 elseif bO=="bottomLeft"then at=self.parent.height+at-1 elseif bO=="left"then at=math.floor(self.parent.height/2)+at-1 elseif bO=="center"then as=math.floor(self.parent.width/2)+as-1;at=math.floor(self.parent.height/2)+at-1 end;local cd,ce=self:getOffset()if not(bP or cc)then return as+cd,at+ce end;return as,at end,getOffset=function(self)if self.parent~=nil then return self.parent:getFrameOffset()end;return 0,0 end,ignoreOffset=function(self,cf)bP=cf;if cf==nil then bP=true end;return self end,getBaseFrame=function(self)if self.parent~=nil then return self.parent:getBaseFrame()end;return self end,setAnchor=function(self,cg)bO=cg;bY=true;return self end,getAnchor=function(self)return bO end,onChange=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("value_changed",c8)end end;return self end,onClick=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_click",c8)self:registerEvent("monitor_touch",c8)end end;return self end,onClickUp=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_up",c8)end end;return self end,onScroll=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_scroll",c8)end end;return self end,onDrag=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_drag",c8)end end;return self end,onEvent=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("custom_event_handler",c8)end end;return self end,onKey=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("key",c8)self:registerEvent("char",c8)end end;return self end,onResize=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("basalt_resize",c8)end end;return self end,onKeyUp=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("key_up",c8)end end;return self end,onBackgroundKey=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("background_key",c8)self:registerEvent("background_char",c8)end end;return self end,onBackgroundKeyUp=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("background_key_up",c8)end end;return self end,isFocused=function(self)if self.parent~=nil then return self.parent:getFocusedObject()==self end;return false end,onGetFocus=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("get_focus",c8)end end;return self end,onLoseFocus=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("lose_focus",c8)end end;return self end,registerEvent=function(self,aO,aQ)return aV:registerEvent(aO,aQ)end,removeEvent=function(self,aO,aN)return aV:removeEvent(aO,aN)end,sendEvent=function(self,aO,...)return aV:sendEvent(aO,self,...)end,mouseHandler=function(self,aO,ch,as,at)local ci,cj=self:getAbsolutePosition(self:getAnchorPosition())local ck=false;if cj-1==at and self:getBorder("top")then at=at+1;ck=true end;if ci<=as and ci+self.width>as and cj<=at and cj+self.height>at and bQ then if self.parent~=nil then self.parent:setFocusedObject(self)end;local aU=aV:sendEvent(aO,self,aO,ch,as,at)if aU~=nil then return aU end;return true end;return false end,keyHandler=function(self,aO,bv)if self:isFocused()then local aU=aV:sendEvent(aO,self,aO,bv)if aU~=nil then return aU end;return true end;return false end,backgroundKeyHandler=function(self,aO,bv)local aU=aV:sendEvent("background_"..aO,self,aO,bv)if aU~=nil then return aU end;return true end,valueChangedHandler=function(self)aV:sendEvent("value_changed",self)end,eventHandler=function(self,aO,cl,cm,cn,co)aV:sendEvent("custom_event_handler",self,aO,cl,cm,cn,co)end,getFocusHandler=function(self)local aU=aV:sendEvent("get_focus",self)if aU~=nil then return aU end;return true end,loseFocusHandler=function(self)local aU=aV:sendEvent("lose_focus",self)if aU~=nil then return aU end;return true end}bZ.__index=bZ;return bZ end;local function cp(bL)local bZ={}local bM="Animation"local cq;local cr={}local aN=1;local cs=0;local ct;local function cu()if cr[aN]~=nil then cr[aN].f(bZ,aN)end;aN=aN+1;if cr[aN]~=nil then if cr[aN].t>0 then cq=os.startTimer(cr[aN].t)else cu()end end end;bZ={name=bL,getType=function(self)return bM end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,aQ,cv)ct=aQ;table.insert(cr,{f=aQ,t=cv or cs})return self end,wait=function(self,cv)cs=cv;return self end,rep=function(self,cw)for as=1,cw do table.insert(cr,{f=ct,t=cs})end;return self end,clear=function(self)cr={}ct=nil;cs=0;aN=1;return self end,play=function(self)aN=1;if cr[aN]~=nil then if cr[aN].t>0 then cq=os.startTimer(cr[aN].t)else cu()end end;return self end,cancel=function(self)os.cancelTimer(cq)return self end,eventHandler=function(self,aO,cx)if aO=="timer"and cx==cq then if cr[aN]~=nil then cu()end end end}bZ.__index=bZ;return bZ end;local function cy(bL)local cz=bK(bL)local bM="Button"cz:setValue("Button")cz:setZIndex(5)cz.width=8;cz.bgColor=k.ButtonBG;cz.fgColor=k.ButtonFG;local cA="center"local cB="center"local bZ={getType=function(self)return bM end,setHorizontalAlign=function(self,cC)cA=cC end,setVerticalAlign=function(self,cC)cB=cC end,setText=function(self,au)cz:setValue(au)return self end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,cB)if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawTextBox(cD,cE,self.width,self.height," ")end;if self.fgColor~=false then self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end;for aj=1,self.height do if aj==cF then self.parent:setText(cD,cE+aj-1,b4(self:getValue(),self.width,cA))end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function cG(bL)local cz=bK(bL)local bM="Checkbox"cz:setZIndex(5)cz:setValue(false)cz.width=1;cz.height=1;cz.bgColor=k.CheckboxBG;cz.fgColor=k.CheckboxFG;local bZ={symbol="\42",getType=function(self)return bM end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then if aO=="mouse_click"and ch==1 or aO=="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 cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,"center")if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;for aj=1,self.height do if aj==cF then if self:getValue()==true then self.parent:writeText(cD,cE+aj-1,b4(self.symbol,self.width,"center"),self.bgColor,self.fgColor)else self.parent:writeText(cD,cE+aj-1,b4(" ",self.width,"center"),self.bgColor,self.fgColor)end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function cH(bL)local cz=bK(bL)local bM="Dropdown"cz.width=12;cz.height=1;cz.bgColor=k.dropdownBG;cz.fgColor=k.dropdownFG;cz:setZIndex(6)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local cL=true;local cM="left"local cN=0;local cO=16;local cP=6;local cQ="\16"local cR="\31"local cS=false;local bZ={getType=function(self)return bM end,setIndexOffset=function(self,ck)cN=ck;return self end,getIndexOffset=function(self)return cN end,addItem=function(self,au,aE,aF,...)table.insert(cI,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,getAll=function(self)return cI end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getItemIndex=function(self)local cT=self:getValue()for bv,aT in pairs(cI)do if aT==cT then return bv end end end,clear=function(self)cI={}self:setValue({})return self end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cU)cJ=aE or self.bgColor;cK=aF or self.fgColor;cL=cU;return self end,setDropdownSize=function(self,a9,p)cO,cP=a9,p;return self end,mouseHandler=function(self,aO,ch,as,at)if cS then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and ch==1 or aO=="monitor_touch"then if#cI>0 then for aj=1,cP do if cI[aj+cN]~=nil then if cD<=as and cD+cO>as and cE+aj==at then self:setValue(cI[aj+cN])return true end end end end end;if aO=="mouse_scroll"then cN=cN+ch;if cN<0 then cN=0 end;if ch==1 then if#cI>cP then if cN>#cI-cP then cN=#cI-cP end else cN=cI-1 end end;return true end;self:setVisualChanged()end;if cz.mouseHandler(self,aO,ch,as,at)then cS=true else cS=false end end,draw=function(self)if cz.draw(self)then local cD,cE=self:getAnchorPosition()if self.parent~=nil then if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;local aU=self:getValue()local au=b4(aU~=nil and aU.text or"",self.width,cM):sub(1,self.width-1)..(cS and cR or cQ)self.parent:writeText(cD,cE,au,self.bgColor,self.fgColor)if cS then for aj=1,cP do if cI[aj+cN]~=nil then if cI[aj+cN]==aU then if cL then self.parent:writeText(cD,cE+aj,b4(cI[aj+cN].text,cO,cM),cJ,cK)else self.parent:writeText(cD,cE+aj,b4(cI[aj+cN].text,cO,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end else self.parent:writeText(cD,cE+aj,b4(cI[aj+cN].text,cO,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function cV(bL)local cz=bK(bL)local bM="Image"cz:setZIndex(2)local cW;local cX;local cY=false;local function bc()local bf={[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 bg,bh,bi={},{},{}for r=0,15 do bh[2^r]=r end;do local bj="0123456789abcdef"for r=1,16 do bg[bj:sub(r,r)]=r-1;bg[r-1]=bj:sub(r,r)bi[bj:sub(r,r)]=2^(r-1)bi[2^(r-1)]=bj:sub(r,r)local bk=bf[r-1]for r=1,#bk do bk[r]=2^bk[r]end end end;local function bl(bm)local bn=bf[bh[bm[#bm][1]]]for s=1,#bn do local bo=bn[s]for r=1,#bm-1 do if bm[r][1]==bo then return r end end end;return 1 end;local function bp(bq,br)if not br then local bs={}br={}for r=1,6 do local bt=bq[r]local bu=br[bt]br[bt],bs[r]=bu and bu+1 or 1,bt end;bq=bs end;local bm={}for bv,aT in pairs(br)do bm[#bm+1]={bv,aT}end;if#bm>1 then while#bm>2 do table.sort(bm,function(bw,bx)return bw[2]>bx[2]end)local by,bz=bl(bm),#bm;local bA,bB=bm[bz][1],bm[by][1]for r=1,6 do if bq[r]==bA then bq[r]=bB;bm[by][2]=bm[by][2]+1 end end;bm[bz]=nil end;local bC=128;for r=1,#bq-1 do if bq[r]~=bq[6]then bC=bC+2^(r-1)end end;return string.char(bC),bi[bm[1][1]==bq[6]and bm[2][1]or bm[1][1]],bi[bq[6]]else return"\128",bi[bq[1]],bi[bq[1]]end end;local bD,a9,p,aE={{},{},{}},0,#cW+#cW%3,cz.bgColor or colors.black;for r=1,#cW do if#cW[r]>a9 then a9=#cW[r]end end;for at=0,p-1,3 do local bE,bF,bG,bH={},{},{},1;for as=0,a9-1,2 do local bq,br={},{}for bI=1,3 do for bJ=1,2 do bq[#bq+1]=cW[at+bI]and cW[at+bI][as+bJ]and(cW[at+bI][as+bJ]==0 and aE or cW[at+bI][as+bJ])or aE;br[bq[#bq]]=br[bq[#bq]]and br[bq[#bq]]+1 or 1 end end;bE[bH],bF[bH],bG[bH]=bp(bq,br)bH=bH+1 end;bD[1][#bD[1]+1],bD[2][#bD[2]+1],bD[3][#bD[3]+1]=table.concat(bE),table.concat(bF),table.concat(bG)end;bD.width,bD.height=#bD[1][1],#bD[1]cX=bD end;local bZ={getType=function(self)return bM end,loadImage=function(self,aZ)cW=paintutils.loadImage(aZ)cY=false;return self end,loadBlittleImage=function(self,aZ)return self end,shrink=function(self)bc()cY=true;return self end,draw=function(self)if cz.draw(self)then if self.parent~=nil then if cW~=nil then local cD,cE=self:getAnchorPosition()if cY then local bb,cZ,c_=cX[1],cX[2],cX[3]for r=1,cX.height do local d0=bb[r]if type(d0)=="string"then self.parent:setText(cD,cE+r-1,d0)self.parent:setFG(cD,cE+r-1,cZ[r])self.parent:setBG(cD,cE+r-1,c_[r])elseif type(d0)=="table"then self.parent:setText(cD,cE+r-1,d0[2])self.parent:setFG(cD,cE+r-1,cZ[r])self.parent:setBG(cD,cE+r-1,c_[r])end end else for c3=1,math.min(#cW,self.height)do local d1=cW[c3]for c2=1,math.min(#d1,self.width)do if d1[c2]>0 then self.parent:drawBackgroundBox(cD+c2-1,cE+c3-1,1,1,d1[c2])end end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function d2(bL)local cz=bK(bL)local bM="Input"local d3="text"local d4=0;cz:setZIndex(5)cz:setValue("")cz.width=10;cz.height=1;cz.bgColor=k.InputBG;cz.fgColor=k.InputFG;local d5=1;local d6=1;local d7=""local d8;local d9;local da=d7;local db=false;local bZ={getType=function(self)return bM end,setInputType=function(self,dc)if dc=="password"or dc=="number"or dc=="text"then d3=dc end;return self end,setDefaultText=function(self,au,dd,de)d7=au;d8=de or d8;d9=dd or d9;if self:isFocused()then da=""else da=d7 end;return self end,getInputType=function(self)return d3 end,setValue=function(self,aU)cz.setValue(self,tostring(aU))if not db then d5=tostring(aU):len()+1 end;return self end,getValue=function(self)local aU=cz.getValue(self)return d3=="number"and tonumber(aU)or aU end,setInputLimit=function(self,df)d4=tonumber(df)or d4;return self end,getInputLimit=function(self)return d4 end,getFocusHandler=function(self)cz.getFocusHandler(self)if self.parent~=nil then local cD,cE=self:getAnchorPosition()da=""if self.parent~=nil then self.parent:setCursor(true,cD+d5-d6,cE+math.floor(self.height/2),self.fgColor)end end end,loseFocusHandler=function(self)cz.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)da=d7 end end,keyHandler=function(self,aO,bv)if cz.keyHandler(self,aO,bv)then db=true;if aO=="key"then if bv==keys.backspace then local au=tostring(cz.getValue())if d5>1 then self:setValue(au:sub(1,d5-2)..au:sub(d5,au:len()))if d5>1 then d5=d5-1 end;if d6>1 then if d5dg then d5=dg+1 end;if d5<1 then d5=1 end;if d5=self.width+d6 then d6=d5-self.width+1 end;if d6<1 then d6=1 end end;if bv==keys.left then d5=d5-1;if d5>=1 then if d5=self.width+d6 then d6=d5 end end;if d5<1 then d5=1 end;if d6<1 then d6=1 end end end;if aO=="char"then local au=cz.getValue()if au:len()=self.width+d6 then d6=d6+1 end end end;local cD,cE=self:getAnchorPosition()local aU=tostring(cz.getValue())local di=(d5<=aU:len()and d5-1 or aU:len())-(d6-1)if di>self.x+self.width-1 then di=self.x+self.width-1 end;if self.parent~=nil then self.parent:setCursor(true,cD+di,cE+math.floor(self.height/2),self.fgColor)end;db=false end end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then if aO=="mouse_click"and ch==1 then end;return true end;return false end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,"center")if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;for aj=1,self.height do if aj==cF then local aU=tostring(cz.getValue())local de=self.bgColor;local dd=self.fgColor;local au;if aU:len()<=0 then au=da;de=d8 or de;dd=d9 or dd end;au=da;if aU~=""then au=aU end;au=au:sub(d6,self.width+d6-1)local dj=self.width-au:len()if dj<0 then dj=0 end;if d3=="password"and aU~=""then au=string.rep("*",au:len())end;au=au..string.rep(" ",dj)self.parent:writeText(cD,cE+aj-1,au,de,dd)end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dk(bL)local cz=bK(bL)local bM="Label"cz:setZIndex(3)cz.fgColor=colors.white;cz.bgcolor=colors.black;local dl=true;cz:setValue("")local cA="left"local cB="top"local dm=0;local bZ={getType=function(self)return bM end,setText=function(self,au)au=tostring(au)cz:setValue(au)if dl then self.width=au:len()end;return self end,setTextAlign=function(self,dn,dp)cA=dn or cA;cB=dp or cB;self:setVisualChanged()return self end,setFontSize=function(self,x)if x>0 and x<=4 then dm=x-1 or 0 end;return self end,getFontSize=function(self)return dm+1 end,setSize=function(self,a9,p)cz.setSize(self,a9,p)dl=false;self:setVisualChanged()return self end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,cB)if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawTextBox(cD,cE,self.width,self.height," ")end;if self.bgColor~=false then self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end;if dm==0 then for aj=1,self.height do if aj==cF then self.parent:writeText(cD,cE+aj-1,b4(self:getValue(),self.width,cA),self.bgColor,self.fgColor)end end else local dq=N(dm,self:getValue(),self.fgColor,self.bgColor)if dl then self.height=#dq[1]-1;self.width=#dq[1][1]end;for aj=1,self.height do if aj==cF then local dr,ds=self.parent:getSize()local dt,du=#dq[1][1],#dq[1]cD=cD or math.floor((dr-dt)/2)+1;cE=cE or math.floor((ds-du)/2)+1;for r=1,du do self.parent:setFG(cD,cE+r+aj-2,b4(dq[2][r],self.width,cA))self.parent:setBG(cD,cE+r+aj-2,b4(dq[3][r],self.width,cA,j[self.bgColor]))self.parent:setText(cD,cE+r+aj-2,b4(dq[1][r],self.width,cA))end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dv(bL)local cz=bK(bL)local bM="List"cz.width=16;cz.height=6;cz.bgColor=k.listBG;cz.fgColor=k.listFG;cz:setZIndex(5)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local cL=true;local cM="left"local cN=0;local dw=true;local bZ={getType=function(self)return bM end,addItem=function(self,au,aE,aF,...)table.insert(cI,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})if#cI==1 then self:setValue(cI[1])end;return self end,setIndexOffset=function(self,ck)cN=ck;return self end,getIndexOffset=function(self)return cN end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getAll=function(self)return cI end,getItemIndex=function(self)local cT=self:getValue()for bv,aT in pairs(cI)do if aT==cT then return bv end end end,clear=function(self)cI={}self:setValue({})return self end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cU)cJ=aE or self.bgColor;cK=aF or self.fgColor;cL=cU;return self end,setScrollable=function(self,dx)dw=dx;return self end,mouseHandler=function(self,aO,ch,as,at)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if cD<=as and cD+self.width>as and cE<=at and cE+self.height>at and self:isVisible()then if(aO=="mouse_click"or aO=="mouse_drag")and ch==1 or aO=="monitor_touch"then if#cI>0 then for aj=1,self.height do if cI[aj+cN]~=nil then if cD<=as and cD+self.width>as and cE+aj-1==at then self:setValue(cI[aj+cN])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,as,at,cI[aj+cN])end end end end end;if aO=="mouse_scroll"and dw then cN=cN+ch;if cN<0 then cN=0 end;if ch>=1 then if#cI>self.height then if cN>#cI-self.height then cN=#cI-self.height end;if cN>=#cI then cN=#cI-1 end else cN=cN-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;for aj=1,self.height do if cI[aj+cN]~=nil then if cI[aj+cN]==self:getValue()then if cL then self.parent:writeText(cD,cE+aj-1,b4(cI[aj+cN].text,self.width,cM),cJ,cK)else self.parent:writeText(cD,cE+aj-1,b4(cI[aj+cN].text,self.width,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end else self.parent:writeText(cD,cE+aj-1,b4(cI[aj+cN].text,self.width,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dy(bL)local cz=bK(bL)local bM="Menubar"local bZ={}cz.width=30;cz.height=1;cz.bgColor=colors.gray;cz.fgColor=colors.lightGray;cz:setZIndex(5)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local cL=true;local cM="left"local dz=0;local dj=1;local dw=false;local function dA()local dB=0;local c2=0;for aj=1,#cI do if c2+cI[aj].text:len()+dj*2>bZ.width then if c2dB then dz=dB end;return self end,getPositionOffset=function(self)return dz end,setScrollable=function(self,dx)dw=dx;if dx==nil then dw=true end;return self end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cU)cJ=aE or self.bgColor;cK=aF or self.fgColor;cL=cU;return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local ci,cj=self:getAbsolutePosition(self:getAnchorPosition())if ci<=as and ci+self.width>as and cj<=at and cj+self.height>at and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if aO=="mouse_click"or aO=="monitor_touch"then local c2=0;for aj=1,#cI do if cI[aj]~=nil then if ci+c2<=as+dz and ci+c2+cI[aj].text:len()+dj*2>as+dz and cj==at then self:setValue(cI[aj])self:getEventSystem():sendEvent(aO,self,aO,0,as,at,cI[aj])end;c2=c2+cI[aj].text:len()+dj*2 end end end;if aO=="mouse_scroll"and dw then dz=dz+ch;if dz<0 then dz=0 end;local dB=dA()if dz>dB then dz=dB end end;self:setVisualChanged(true)return true end end;return false end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;local au=""local dD=""local dE=""for aS,c8 in pairs(cI)do local dF=(" "):rep(dj)..c8.text..(" "):rep(dj)au=au..dF;if c8==self:getValue()then dD=dD..j[cJ or c8.bgCol or self.bgColor]:rep(dF:len())dE=dE..j[cK or c8.FgCol or self.fgColor]:rep(dF:len())else dD=dD..j[c8.bgCol or self.bgColor]:rep(dF:len())dE=dE..j[c8.FgCol or self.fgColor]:rep(dF:len())end end;self.parent:setText(cD,cE,au:sub(dz+1,self.width+dz))self.parent:setBG(cD,cE,dD:sub(dz+1,self.width+dz))self.parent:setFG(cD,cE,dE:sub(dz+1,self.width+dz))end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dG(bL)local cz=bK(bL)local bM="Pane"local bZ={getType=function(self)return bM end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.bgColor)end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dH(bL)local cz=bK(bL)local bM="Program"cz:setZIndex(5)local bZ;local function dI(as,at,a9,p)local dJ,dK=1,1;local be,dL=colors.black,colors.white;local dM=false;local dN=false;local aa={}local ab={}local ac={}local dO={}local ag;local ah={}for r=0,15 do local dP=2^r;dO[dP]={h.getPaletteColour(dP)}end;local function ai()ag=(" "):rep(a9)for aj=0,15 do local ak=2^aj;local al=j[ak]ah[ak]=al:rep(a9)end end;local function am()ai()local an=ag;local ao=ah[colors.white]local ap=ah[colors.black]for aj=1,p do aa[aj]=i(aa[aj]==nil and an or aa[aj]..an:sub(1,a9-aa[aj]:len()),1,a9)ac[aj]=i(ac[aj]==nil and ao or ac[aj]..ao:sub(1,a9-ac[aj]:len()),1,a9)ab[aj]=i(ab[aj]==nil and ap or ab[aj]..ap:sub(1,a9-ab[aj]:len()),1,a9)end end;am()local function dQ()if dJ>=1 and dK>=1 and dJ<=a9 and dK<=p then else end end;local function dR(dS,dT,dU)local dV=dJ;local ax=dV+#dS-1;if dK>=1 and dK<=p then if dV<=a9 and ax>=1 then if dV==1 and ax==a9 then aa[dK]=dS;ac[dK]=dT;ab[dK]=dU else local dW,dX,dY;if dV<1 then local dZ=1-dV+1;local d_=a9-dV+1;dW=i(dS,dZ,d_)dX=i(dT,dZ,d_)dY=i(dU,dZ,d_)elseif ax>a9 then local d_=a9-dV+1;dW=i(dS,1,d_)dX=i(dT,1,d_)dY=i(dU,1,d_)else dW=dS;dX=dT;dY=dU end;local e0=aa[dK]local e1=ac[dK]local e2=ab[dK]local e3,e4,e5;if dV>1 then local e6=dV-1;e3=i(e0,1,e6)..dW;e4=i(e1,1,e6)..dX;e5=i(e2,1,e6)..dY else e3=dW;e4=dX;e5=dY end;if ax=1 and at<=p then aa[et]=aa[at]ab[et]=ab[at]ac[et]=ac[at]else aa[et]=eq;ac[et]=er;ab[et]=es end end end;if dN then dQ()end end,isColor=function()return h.isColor()end,isColour=function()return h.isColor()end,write=function(au)au=tostring(au)if dN then dR(au,j[dL]:rep(au:len()),j[be]:rep(au:len()))end end,clearLine=function()if dN then ar(1,dK,(" "):rep(a9))aA(1,dK,j[be]:rep(a9))aC(1,dK,j[dL]:rep(a9))end;if dN then dQ()end end,clear=function()for aj=1,p do ar(1,aj,(" "):rep(a9))aA(1,aj,j[be]:rep(a9))aC(1,aj,j[dL]:rep(a9))end;if dN then dQ()end end,blit=function(au,eu,ev)if type(au)~="string"then error("bad argument #1 (expected string, got "..type(au)..")",2)end;if type(eu)~="string"then error("bad argument #2 (expected string, got "..type(eu)..")",2)end;if type(ev)~="string"then error("bad argument #3 (expected string, got "..type(ev)..")",2)end;if#eu~=#au or#ev~=#au then error("Arguments must be the same length",2)end;if dN then dR(au,eu,ev)end end}return el end;cz.width=30;cz.height=12;local ew=dI(1,1,cz.width,cz.height)local ex;local ey=false;local ez={}bZ={getType=function(self)return bM end,show=function(self)cz.show(self)ew.setBackgroundColor(self.bgColor)ew.setTextColor(self.fgColor)ew.basalt_setVisible(true)return self end,hide=function(self)cz.hide(self)ew.basalt_setVisible(false)return self end,setPosition=function(self,as,at,c4)cz.setPosition(self,as,at,c4)ew.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return ew end,getBasaltProcess=function()return ex end,setSize=function(self,a9,p)cz.setSize(self,a9,p)ew.basalt_resize(self.width,self.height)return self end,getStatus=function(self)if ex~=nil then return ex:getStatus()end;return"inactive"end,execute=function(self,aZ,...)ex=aX:new(aZ,ew,...)ew.setBackgroundColor(colors.black)ew.setTextColor(colors.white)ew.clear()ew.setCursorPos(1,1)ex:resume()ey=false;return self end,stop=function(self)if ex~=nil then if not ex:isDead()then ex:resume("terminate")if ex:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,eA)ey=eA or not ey;if ex~=nil then if not ex:isDead()then if not ey then self:injectEvents(ez)ez={}end end end;return self end,isPaused=function(self)return ey end,injectEvent=function(self,aO,cl,cm,cn,co,eB)if ex~=nil then if not ex:isDead()then if ey==false or eB then ex:resume(aO,cl,cm,cn,co)else table.insert(ez,{event=aO,args={cl,cm,cn,co}})end end end;return self end,getQueuedEvents=function(self)return ez end,updateQueuedEvents=function(self,aM)ez=aM or ez;return self end,injectEvents=function(self,aM)if ex~=nil then if not ex:isDead()then for aS,aT in pairs(aM)do ex:resume(aT.event,table.unpack(aT.args))end end end;return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then if ex==nil then return false end;if not ex:isDead()then if not ey then local eC,eD=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))ex:resume(aO,ch,as-(eC-1),at-(eD-1))a.debug(aO,ch,as-(eC-1),at-(eD-1))end end;return true end end,keyHandler=function(self,aO,bv)cz.keyHandler(self,aO,bv)if self:isFocused()then if ex==nil then return false end;if not ex:isDead()then if not ey then if self.draw then ex:resume(aO,bv)end end end end end,getFocusHandler=function(self)cz.getFocusHandler(self)if ex~=nil then if not ex:isDead()then if not ey then if self.parent~=nil then local eE,eF=ew.getCursorPos()local cD,cE=self:getAnchorPosition()if self.parent~=nil then if cD+eE-1>=1 and cD+eE-1<=cD+self.width-1 and eF+cE-1>=1 and eF+cE-1<=cE+self.height-1 then self.parent:setCursor(ew.getCursorBlink(),cD+eE-1,eF+cE-1,ew.getTextColor())end end end end end end end,loseFocusHandler=function(self)cz.loseFocusHandler(self)if ex~=nil then if not ex:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,aO,cl,cm,cn,co)if ex==nil then return end;if not ex:isDead()then if not ey then if aO~="mouse_click"and aO~="monitor_touch"and aO~="mouse_up"and aO~="mouse_scroll"and aO~="mouse_drag"and aO~="key_up"and aO~="key"and aO~="char"and aO~="terminate"then ex:resume(aO,cl,cm,cn,co)end;if self:isFocused()then local cD,cE=self:getAnchorPosition()local eE,eF=ew.getCursorPos()if self.parent~=nil then if cD+eE-1>=1 and cD+eE-1<=cD+self.width-1 and eF+cE-1>=1 and eF+cE-1<=cE+self.height-1 then self.parent:setCursor(ew.getCursorBlink(),cD+eE-1,eF+cE-1,ew.getTextColor())end end;if aO=="terminate"and self:isFocused()then self:stop()end end else if aO~="mouse_click"and aO~="monitor_touch"and aO~="mouse_up"and aO~="mouse_scroll"and aO~="mouse_drag"and aO~="key_up"and aO~="key"and aO~="char"and aO~="terminate"then table.insert(ez,{event=aO,args={cl,cm,cn,co}})end end end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()ew.basalt_reposition(cD,cE)if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;ew.basalt_update()end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function eG(bL)local cz=bK(bL)local bM="Progressbar"local eH=0;cz:setZIndex(5)cz:setValue(false)cz.width=25;cz.height=1;cz.bgColor=k.CheckboxBG;cz.fgColor=k.CheckboxFG;local eI=colors.black;local eJ=""local eK=colors.white;local eL=""local eM=0;local bZ={getType=function(self)return bM end,setDirection=function(self,eN)eM=eN;return self end,setProgressBar=function(self,c6,aG,eO)eI=c6 or eI;eJ=aG or eJ;eK=eO or eK;return self end,setBackgroundSymbol=function(self,aG)eL=aG:sub(1,1)return self end,setProgress=function(self,aT)if aT>=0 and aT<=100 and eH~=aT then eH=aT;self:setValue(eH)if eH==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return eH end,onProgressDone=function(self,A)self:registerEvent("progress_done",A)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done")end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)self.parent:drawTextBox(cD,cE,self.width,self.height,eL)if eM==1 then self.parent:drawBackgroundBox(cD,cE,self.width,self.height/100*eH,eI)self.parent:drawForegroundBox(cD,cE,self.width,self.height/100*eH,eK)self.parent:drawTextBox(cD,cE,self.width,self.height/100*eH,eJ)elseif eM==2 then self.parent:drawBackgroundBox(cD,cE+math.ceil(self.height-self.height/100*eH),self.width,self.height/100*eH,eI)self.parent:drawForegroundBox(cD,cE+math.ceil(self.height-self.height/100*eH),self.width,self.height/100*eH,eK)self.parent:drawTextBox(cD,cE+math.ceil(self.height-self.height/100*eH),self.width,self.height/100*eH,eJ)elseif eM==3 then self.parent:drawBackgroundBox(cD+math.ceil(self.width-self.width/100*eH),cE,self.width/100*eH,self.height,eI)self.parent:drawForegroundBox(cD+math.ceil(self.width-self.width/100*eH),cE,self.width/100*eH,self.height,eK)self.parent:drawTextBox(cD+math.ceil(self.width-self.width/100*eH),cE,self.width/100*eH,self.height,eJ)else self.parent:drawBackgroundBox(cD,cE,self.width/100*eH,self.height,eI)self.parent:drawForegroundBox(cD,cE,self.width/100*eH,self.height,eK)self.parent:drawTextBox(cD,cE,self.width/100*eH,self.height,eJ)end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function eP(bL)local cz=bK(bL)local bM="Radio"cz.width=8;cz.bgColor=k.listBG;cz.fgColor=k.listFG;cz:setZIndex(5)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local eQ=cz.bgColor;local eR=cz.fgColor;local cL=true;local aG="\7"local cM="left"local bZ={getType=function(self)return bM end,addItem=function(self,au,as,at,aE,aF,...)table.insert(cI,{x=as or 1,y=at or 1,text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})if#cI==1 then self:setValue(cI[1])end;return self end,getAll=function(self)return cI end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getItemIndex=function(self)local cT=self:getValue()for bv,aT in pairs(cI)do if aT==cT then return bv end end end,clear=function(self)cI={}self:setValue({})return self end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,as,at,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{x=as or 1,y=at or 1,text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,eS,eT,cU)cJ=aE or cJ;cK=aF or cK;eQ=eS or eQ;eR=eT or eR;cL=cU;return self end,mouseHandler=function(self,aO,ch,as,at)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and ch==1 or aO=="monitor_touch"then if#cI>0 then for aS,aT in pairs(cI)do if cD+aT.x-1<=as and cD+aT.x-1+aT.text:len()+2>=as and cE+aT.y-1==at then self:setValue(aT)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 cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()for aS,aT in pairs(cI)do if aT==self:getValue()then if cM=="left"then self.parent:writeText(aT.x+cD-1,aT.y+cE-1,aG,eQ,eR)self.parent:writeText(aT.x+2+cD-1,aT.y+cE-1,aT.text,cJ,cK)end else self.parent:drawBackgroundBox(aT.x+cD-1,aT.y+cE-1,1,1,self.bgColor)self.parent:writeText(aT.x+2+cD-1,aT.y+cE-1,aT.text,aT.bgCol,aT.fgCol)end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function eU(bL)local cz=bK(bL)local bM="Scrollbar"cz.width=1;cz.height=8;cz.bgColor=colors.lightGray;cz.fgColor=colors.gray;cz:setValue(1)cz:setZIndex(2)local eV="vertical"local aG=" "local eW=colors.black;local eX="\127"local eY=cz.height;local aN=1;local eZ=1;local bZ={getType=function(self)return bM end,setSymbol=function(self,e_)aG=e_:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,x)eZ=tonumber(x)or 1;if eV=="vertical"then self:setValue(aN-1*eY/(self.height-(eZ-1))-eY/(self.height-(eZ-1)))elseif eV=="horizontal"then self:setValue(aN-1*eY/(self.width-(eZ-1))-eY/(self.width-(eZ-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,aU)eY=aU;return self end,setBackgroundSymbol=function(self,f0)eX=string.sub(f0,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,f1)eW=f1;self:setVisualChanged()return self end,setBarType=function(self,f2)eV=f2:lower()return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if(aO=="mouse_click"or aO=="mouse_drag")and ch==1 or aO=="monitor_touch"then if eV=="horizontal"then for f3=0,self.width do if cD+f3==as and cE<=at and cE+self.height>at then aN=math.min(f3+1,self.width-(eZ-1))self:setValue(eY/self.width*aN)self:setVisualChanged()end end end;if eV=="vertical"then for f3=0,self.height do if cE+f3==at and cD<=as and cD+self.width>as then aN=math.min(f3+1,self.height-(eZ-1))self:setValue(eY/self.height*aN)self:setVisualChanged()end end end end;if aO=="mouse_scroll"then aN=aN+ch;if aN<1 then aN=1 end;aN=math.min(aN,(eV=="vertical"and self.height or self.width)-(eZ-1))self:setValue(eY/(eV=="vertical"and self.height or self.width)*aN)end;return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if eV=="horizontal"then self.parent:writeText(cD,cE,eX:rep(aN-1),self.bgColor,self.fgColor)self.parent:writeText(cD+aN-1,cE,aG:rep(eZ),eW,eW)self.parent:writeText(cD+aN+eZ-1,cE,eX:rep(self.width-(aN+eZ-1)),self.bgColor,self.fgColor)end;if eV=="vertical"then for aj=0,self.height-1 do if aN==aj+1 then for f4=0,math.min(eZ-1,self.height)do self.parent:writeText(cD,cE+aj+f4,aG,eW,eW)end else if aj+1aN-1+eZ then self.parent:writeText(cD,cE+aj,eX,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function f5(bL)local cz=bK(bL)local bM="Slider"cz.width=8;cz.height=1;cz.bgColor=colors.lightGray;cz.fgColor=colors.gray;cz:setValue(1)local eV="horizontal"local aG=" "local eW=colors.black;local eX="\140"local eY=cz.width;local aN=1;local eZ=1;local bZ={getType=function(self)return bM end,setSymbol=function(self,e_)aG=e_:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,x)eZ=tonumber(x)or 1;if eV=="vertical"then self:setValue(aN-1*eY/(self.height-(eZ-1))-eY/(self.height-(eZ-1)))elseif eV=="horizontal"then self:setValue(aN-1*eY/(self.width-(eZ-1))-eY/(self.width-(eZ-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,aU)eY=aU;return self end,setBackgroundSymbol=function(self,f0)eX=string.sub(f0,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,f1)eW=f1;self:setVisualChanged()return self end,setBarType=function(self,f2)eV=f2:lower()return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if(aO=="mouse_click"or aO=="mouse_drag")and ch==1 or aO=="monitor_touch"then if eV=="horizontal"then for f3=0,self.width do if cD+f3==as and cE<=at and cE+self.height>at then aN=math.min(f3+1,self.width-(eZ-1))self:setValue(eY/self.width*aN)self:setVisualChanged()end end end;if eV=="vertical"then for f3=0,self.height do if cE+f3==at and cD<=as and cD+self.width>as then aN=math.min(f3+1,self.height-(eZ-1))self:setValue(eY/self.height*aN)self:setVisualChanged()end end end end;if aO=="mouse_scroll"then aN=aN+ch;if aN<1 then aN=1 end;aN=math.min(aN,(eV=="vertical"and self.height or self.width)-(eZ-1))self:setValue(eY/(eV=="vertical"and self.height or self.width)*aN)end;return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if eV=="horizontal"then self.parent:writeText(cD,cE,eX:rep(aN-1),self.bgColor,self.fgColor)self.parent:writeText(cD+aN-1,cE,aG:rep(eZ),eW,eW)self.parent:writeText(cD+aN+eZ-1,cE,eX:rep(self.width-(aN+eZ-1)),self.bgColor,self.fgColor)end;if eV=="vertical"then for aj=0,self.height-1 do if aN==aj+1 then for f4=0,math.min(eZ-1,self.height)do self.parent:writeText(cD,cE+aj+f4,aG,eW,eW)end else if aj+1aN-1+eZ then self.parent:writeText(cD,cE+aj,eX,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function f6(bL)local cz=bK(bL)local bM="Switch"cz.width=2;cz.height=1;cz.bgColor=colors.lightGray;cz.fgColor=colors.gray;cz:setValue(false)cz:setZIndex(5)local eX=colors.black;local f7=colors.red;local f8=colors.green;local bZ={getType=function(self)return bM end,setSymbolColor=function(self,eW)eX=eW;self:setVisualChanged()return self end,setActiveBackground=function(self,ev)f8=ev;self:setVisualChanged()return self end,setInactiveBackground=function(self,ev)f7=ev;self:setVisualChanged()return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and ch==1 or aO=="monitor_touch"then self:setValue(not self:getValue())end;return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)if self:getValue()then self.parent:drawBackgroundBox(cD,cE,1,self.height,f8)self.parent:drawBackgroundBox(cD+1,cE,1,self.height,eX)else self.parent:drawBackgroundBox(cD,cE,1,self.height,eX)self.parent:drawBackgroundBox(cD+1,cE,1,self.height,f7)end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function f9(bL)local cz=bK(bL)local bM="Textfield"local fa,d6,d5,fb=1,1,1,1;local fc={""}local fd={[colors.purple]={"break"}}cz.width=20;cz.height=8;cz.bgColor=k.textfieldBG;cz.fgColor=k.textfieldFG;cz:setZIndex(5)local bZ={getType=function(self)return bM end,getLines=function(self)return fc end,getLine=function(self,aN)return fc[aN]or""end,editLine=function(self,aN,au)fc[aN]=au or fc[aN]return self end,addLine=function(self,au,aN)if aN~=nil then table.insert(fc,aN,au)else table.insert(fc,au)end;return self end,addKeyword=function(self,fe,c6)end,removeLine=function(self,aN)table.remove(fc,aN or#fc)if#fc<=0 then table.insert(fc,"")end;return self end,getTextCursor=function(self)return d5,fb end,getFocusHandler=function(self)cz.getFocusHandler(self)if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,cD+d5-d6,cE+fb-fa,self.fgColor)end end end,loseFocusHandler=function(self)cz.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,aO,bv)if cz.keyHandler(self,aO,bv)then local cD,cE=self:getAnchorPosition()if aO=="key"then if bv==keys.backspace then if fc[fb]==""then if fb>1 then table.remove(fc,fb)d5=fc[fb-1]:len()+1;d6=d5-self.width+1;if d6<1 then d6=1 end;fb=fb-1 end elseif d5<=1 then if fb>1 then d5=fc[fb-1]:len()+1;d6=d5-self.width+1;if d6<1 then d6=1 end;fc[fb-1]=fc[fb-1]..fc[fb]table.remove(fc,fb)fb=fb-1 end else fc[fb]=fc[fb]:sub(1,d5-2)..fc[fb]:sub(d5,fc[fb]:len())if d5>1 then d5=d5-1 end;if d6>1 then if d5fc[fb]:len()then if fc[fb+1]~=nil then fc[fb]=fc[fb]..fc[fb+1]table.remove(fc,fb+1)end else fc[fb]=fc[fb]:sub(1,d5-1)..fc[fb]:sub(d5+1,fc[fb]:len())end end;if bv==keys.enter then table.insert(fc,fb+1,fc[fb]:sub(d5,fc[fb]:len()))fc[fb]=fc[fb]:sub(1,d5-1)fb=fb+1;d5=1;d6=1;if fb-fa>=self.height then fa=fa+1 end;self:setValue("")end;if bv==keys.up then if fb>1 then fb=fb-1;if d5>fc[fb]:len()+1 then d5=fc[fb]:len()+1 end;if d6>1 then if d51 then if fbfc[fb]:len()+1 then d5=fc[fb]:len()+1 end;if fb>=fa+self.height then fa=fa+1 end end end;if bv==keys.right then d5=d5+1;if fb<#fc then if d5>fc[fb]:len()+1 then d5=1;fb=fb+1 end elseif d5>fc[fb]:len()then d5=fc[fb]:len()+1 end;if d5<1 then d5=1 end;if d5=self.width+d6 then d6=d5-self.width+1 end;if d6<1 then d6=1 end end;if bv==keys.left then d5=d5-1;if d5>=1 then if d5=self.width+d6 then d6=d5 end end;if fb>1 then if d5<1 then fb=fb-1;d5=fc[fb]:len()+1;d6=d5-self.width+1 end end;if d5<1 then d5=1 end;if d6<1 then d6=1 end end end;if aO=="char"then fc[fb]=fc[fb]:sub(1,d5-1)..bv..fc[fb]:sub(d5,fc[fb]:len())d5=d5+1;if d5>=self.width+d6 then d6=d6+1 end;self:setValue("")end;local di=(d5<=fc[fb]:len()and d5-1 or fc[fb]:len())-(d6-1)if di>self.x+self.width-1 then di=self.x+self.width-1 end;local ff=fb-fafc[fb]:len()then d5=fc[fb]:len()+1 end;if d5fc[fb]:len()then d5=fc[fb]:len()+1 end;if d5#fc-(self.height-1)then fa=#fc-(self.height-1)end;if fa<1 then fa=1 end;if self.parent~=nil then if cD+d5-d6>=cD and cD+d5-d6<=cD+self.width and(cE+fb-fa>=cE and cE+fb-fa<=cE+self.height)then self.parent:setCursor(true,fg+d5-d6,fh+fb-fa,self.fgColor)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;if self.fgColor~=false then self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end;for aj=1,self.height do local au=""if fc[aj+fa-1]~=nil then au=fc[aj+fa-1]end;au=au:sub(d6,self.width+d6-1)local dj=self.width-au:len()if dj<0 then dj=0 end;au=au..string.rep(" ",dj)self.parent:setText(cD,cE+aj-1,au)end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function fi(bL)local bZ;local bM="Thread"local aQ;local fj;local fk=false;bZ={name=bL,getType=function(self)return bM end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,A)if A==nil then error("Function provided to thread is nil")end;aQ=A;fj=coroutine.create(aQ)fk=true;local b2,b3=coroutine.resume(fj)if not b2 then if b3~="Terminated"then error("Thread Error Occurred - "..b3)end end;return self end,getStatus=function(self,A)if fj~=nil then return coroutine.status(fj)end;return nil end,stop=function(self,A)fk=false;return self end,eventHandler=function(self,aO,cl,cm,cn)if fk then if coroutine.status(fj)~="dead"then local b2,b3=coroutine.resume(fj,aO,cl,cm,cn)if not b2 then if b3~="Terminated"then error("Thread Error Occurred - "..b3)end end else fk=false end end end}bZ.__index=bZ;return bZ end;local function fl(bL)local bM="Timer"local fm=0;local fn=0;local fo=0;local cq;local aV=aL()local fp=false;local bZ={name=bL,getType=function(self)return bM end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,fq,fr)fm=fq or 0;fn=fr or 1;return self end,start=function(self)if fp then os.cancelTimer(cq)end;fo=fn;cq=os.startTimer(fm)fp=true;return self end,isActive=function(self)return fp end,cancel=function(self)if cq~=nil then os.cancelTimer(cq)end;fp=false;return self end,onCall=function(self,aQ)aV:registerEvent("timed_event",aQ)return self end,eventHandler=function(self,aO,cx)if aO=="timer"and cx==cq and fp then aV:sendEvent("timed_event",self)if fo>=1 then fo=fo-1;if fo>=1 then cq=os.startTimer(fm)end elseif fo==-1 then cq=os.startTimer(fm)end end end}bZ.__index=bZ;return bZ end;local function fs(bL,ft)local cz=bK(bL)local bM="Frame"local fu={}local fv={}local bZ={}local fw=h;local fx=""local fy=false;local fz=false;local fA=0;local fB=0;cz:setZIndex(10)local aD=a6(fw)local dM=false;local dJ=1;local dK=1;local fC=colors.white;local fD,cN=0,0;if ft~=nil then cz.parent=ft;cz.width,cz.height=ft:getSize()cz.bgColor=k.FrameBG;cz.fgColor=k.FrameFG else cz.width,cz.height=fw.getSize()cz.bgColor=k.basaltBG;cz.fgColor=k.basaltFG end;local function fE(bL)for aS,aT in pairs(fu)do for aS,bx in pairs(aT)do if bx.name==bL then return aT end end end end;local function fF(fG)local bN=fG:getZIndex()if fE(fG.name)~=nil then return nil end;if fu[bN]==nil then for as=1,#fv+1 do if fv[as]~=nil then if bN==fv[as]then break end;if bN>fv[as]then table.insert(fv,as,bN)break end else table.insert(fv,bN)end end;if#fv<=0 then table.insert(fv,bN)end;fu[bN]={}end;fG.parent=bZ;table.insert(fu[bN],fG)return fG end;local function fH(fG)for bw,bx in pairs(fu)do for bv,aT in pairs(bx)do if aT==fG then table.remove(fu[bw],bv)return true end end end;return false end;bZ={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return bM end,setFocusedObject=function(self,fG)if c~=nil then c:loseFocusHandler()c=nil end;if fG~=nil then c=fG;fG:getFocusHandler()end;return self end,setSize=function(self,fI,b9)cz.setSize(self,fI,b9)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.eventHandler~=nil then aT:sendEvent("basalt_resize",aT,self)end end end end end,setOffset=function(self,cd,ce)fD=cd~=nil and math.floor(cd<0 and math.abs(cd)or-cd)or fD;cN=ce~=nil and math.floor(ce<0 and math.abs(ce)or-ce)or cN;return self end,getFrameOffset=function(self)return fD,cN end,removeFocusedObject=function(self)if c~=nil then c:loseFocusHandler()end;c=nil;return self end,getFocusedObject=function(self)return c end,setCursor=function(self,fJ,fK,fL,c6)if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:setCursor(fJ or false,(fK or 0)+cD-1,(fL or 0)+cE-1,c6 or fC)else local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())dM=fJ or false;if fK~=nil then dJ=cD+fK-1 end;if fL~=nil then dK=cE+fL-1 end;fC=c6 or fC;self:setVisualChanged()end;return self end,setMoveable=function(self,fM)self.isMoveable=fM or not self.isMoveable;self:setVisualChanged()return self end,show=function(self)cz.show(self)if self.parent==nil then e=self;if fy then g[fx]=self else f=self end end;return self end,hide=function(self)cz.hide(self)if self.parent==nil then if e==self then e=nil end;if fy then if g[fx]==self then g[fx]=nil end else if f==self then f=nil end end end;return self end,showBar=function(self,fN)self.barActive=fN or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,au,aE,aF)self.barText=au or""self.barBackground=aE or self.barBackground;self.barTextcolor=aF or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,cM)self.barTextAlign=cM or"left"self:setVisualChanged()return self end,setMonitor=function(self,c9)if c9~=nil and c9~=false then if peripheral.getType(c9)=="monitor"then fw=peripheral.wrap(c9)fz=true end;fy=true else fw=h;fy=false;if g[fx]==self then g[fx]=nil end end;aD=a6(fw)fx=c9 or nil;return self end,getVisualChanged=function(self)local fO=cz.getVisualChanged(self)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.getVisualChanged~=nil and aT:getVisualChanged()then fO=true end end end end;return fO end,loseFocusHandler=function(self)cz.loseFocusHandler(self)end,getFocusHandler=function(self)cz.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,aO,bv)if c~=nil then if c~=self then if c.keyHandler~=nil then if c:keyHandler(aO,bv)then return true end end else cz.keyHandler(self,aO,bv)end end;return false end,backgroundKeyHandler=function(self,aO,bv)cz.backgroundKeyHandler(self,aO,bv)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.backgroundKeyHandler~=nil then aT:backgroundKeyHandler(aO,bv)end end end end end,eventHandler=function(self,aO,cl,cm,cn,co)cz.eventHandler(self,aO,cl,cm,cn,co)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.eventHandler~=nil then aT:eventHandler(aO,cl,cm,cn,co)end end end end;if fy then if aO=="peripheral"and cl==fx then if peripheral.getType(fx)=="monitor"then fz=true;fw=peripheral.wrap(fx)aD=a6(fw)end end;if aO=="peripheral_detach"and cl==fx then fz=false end end;if aO=="terminate"then fw.clear()fw.setCursorPos(1,1)a.stop()end end,mouseHandler=function(self,aO,ch,as,at)local cd,ce=self:getOffset()cd=cd<0 and math.abs(cd)or-cd;ce=ce<0 and math.abs(ce)or-ce;if self.drag then if aO=="mouse_drag"then local fP=1;local fQ=1;if self.parent~=nil then fP,fQ=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(as+fA-(fP-1)+cd,at+fB-(fQ-1)+ce)end;if aO=="mouse_up"then self.drag=false end;return true end;local ci,cj=self:getAbsolutePosition(self:getAnchorPosition())local ck=false;if cj-1==at and self:getBorder("top")then at=at+1;ck=true end;if cz.mouseHandler(self,aO,ch,as,at)then local ca,cb=self:getAbsolutePosition(self:getAnchorPosition())ca=ca+fD;cb=cb+cN;for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in ba(fu[aN])do if aT.mouseHandler~=nil then if aT:mouseHandler(aO,ch,as,at)then return true end end end end end;if self.isMoveable then local ca,cb=self:getAbsolutePosition(self:getAnchorPosition())if as>=ca and as<=ca+self.width-1 and at==cb and aO=="mouse_click"then self.drag=true;fA=ca-as;fB=ck and 1 or 0 end end;if c~=nil then c:loseFocusHandler()c=nil end;return true end;return false end,setText=function(self,as,at,au)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:setText(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(au,math.max(1-as+1,1),math.max(self.width-as+1,1)))else aD.setText(math.max(as+cD-1,cD),cE+at-1,i(au,math.max(1-as+1,1),math.max(self.width-as+1,1)))end end end,setBG=function(self,as,at,aE)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:setBG(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(aE,math.max(1-as+1,1),math.max(self.width-as+1,1)))else aD.setBG(math.max(as+cD-1,cD),cE+at-1,i(aE,math.max(1-as+1,1),math.max(self.width-as+1,1)))end end end,setFG=function(self,as,at,aF)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:setFG(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(aF,math.max(1-as+1,1),math.max(self.width-as+1,1)))else aD.setFG(math.max(as+cD-1,cD),cE+at-1,i(aF,math.max(1-as+1,1),math.max(self.width-as+1,1)))end end end,writeText=function(self,as,at,au,aE,aF)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:writeText(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(au,math.max(1-as+1,1),self.width-as+1),aE,aF)else aD.writeText(math.max(as+cD-1,cD),cE+at-1,i(au,math.max(1-as+1,1),math.max(self.width-as+1,1)),aE,aF)end end end,drawBackgroundBox=function(self,as,at,a9,p,aE)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:drawBackgroundBox(math.max(as+cD-1,cD)-(fP-1),math.max(at+cE-1,cE)-(fQ-1),a9,p,aE)else aD.drawBackgroundBox(math.max(as+cD-1,cD),math.max(at+cE-1,cE),a9,p,aE)end end,drawTextBox=function(self,as,at,a9,p,aG)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:drawTextBox(math.max(as+cD-1,cD)-(fP-1),math.max(at+cE-1,cE)-(fQ-1),a9,p,aG:sub(1,1))else aD.drawTextBox(math.max(as+cD-1,cD),math.max(at+cE-1,cE),a9,p,aG:sub(1,1))end end,drawForegroundBox=function(self,as,at,a9,p,aF)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:drawForegroundBox(math.max(as+cD-1,cD)-(fP-1),math.max(at+cE-1,cE)-(fQ-1),a9,p,aF)else aD.drawForegroundBox(math.max(as+cD-1,cD),math.max(at+cE-1,cE),a9,p,aF)end end,draw=function(self)if fy and not fz then return false end;if self:getVisualChanged()then if cz.draw(self)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())local fg,fh=self:getAnchorPosition()if self.parent~=nil then if self.bgColor~=false then self.parent:drawBackgroundBox(fg,fh,self.width,self.height,self.bgColor)self.parent:drawTextBox(fg,fh,self.width,self.height," ")end;if self.bgColor~=false then self.parent:drawForegroundBox(fg,fh,self.width,self.height,self.fgColor)end else if self.bgColor~=false then aD.drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)aD.drawTextBox(cD,cE,self.width,self.height," ")end;if self.fgColor~=false then aD.drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end end;fw.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(fg,fh,b4(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)else aD.writeText(cD,cE,b4(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)end;if self:getBorder("left")then if self.parent~=nil then self.parent:drawBackgroundBox(fg-1,fh,1,1,self.barBackground)if self.bgColor~=false then self.parent:drawBackgroundBox(fg-1,fh+1,1,self.height-1,self.bgColor)end end end;if self:getBorder("top")then if self.parent~=nil then self.parent:drawBackgroundBox(fg-1,fh-1,self.width+1,1,self.barBackground)end end end;for aS,aN in ba(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.draw~=nil then aT:draw()end end end end;if dM then fw.setTextColor(fC)fw.setCursorPos(dJ,dK)if self.parent~=nil then fw.setCursorBlink(self:isFocused())else fw.setCursorBlink(dM)end end;self:setVisualChanged(false)end end end,drawUpdate=function(self)if fy and not fz then return false end;aD.update()end,addObject=function(self,fG)return fF(fG)end,removeObject=function(self,fG)return fH(fG)end,getObject=function(self,fG)return fE(fG)end,addButton=function(self,bL)local fG=cy(bL)fG.name=bL;return fF(fG)end,addLabel=function(self,bL)local fG=dk(bL)fG.bgColor=self.bgColor;fG.fgColor=self.fgColor;return fF(fG)end,addCheckbox=function(self,bL)local fG=cG(bL)return fF(fG)end,addInput=function(self,bL)local fG=d2(bL)return fF(fG)end,addProgram=function(self,bL)local fG=dH(bL)return fF(fG)end,addTextfield=function(self,bL)local fG=f9(bL)return fF(fG)end,addList=function(self,bL)local fG=dv(bL)fG.name=nam;return fF(fG)end,addDropdown=function(self,bL)local fG=cH(bL)return fF(fG)end,addRadio=function(self,bL)local fG=eP(bL)return fF(fG)end,addTimer=function(self,bL)local fG=fl(bL)return fF(fG)end,addAnimation=function(self,bL)local fG=cp(bL)return fF(fG)end,addSlider=function(self,bL)local fG=f5(bL)return fF(fG)end,addScrollbar=function(self,bL)local fG=eU(bL)return fF(fG)end,addMenubar=function(self,bL)local fG=dy(bL)return fF(fG)end,addThread=function(self,bL)local fG=fi(bL)return fF(fG)end,addPane=function(self,bL)local fG=dG(bL)return fF(fG)end,addImage=function(self,bL)local fG=cV(bL)return fF(fG)end,addProgressbar=function(self,bL)local fG=eG(bL)return fF(fG)end,addSwitch=function(self,bL)local fG=f6(bL)return fF(fG)end,addFrame=function(self,bL)local fG=fs(bL,self)return fF(fG)end}setmetatable(bZ,cz)return bZ end;local function fR()f:draw()f:drawUpdate()for aS,c8 in pairs(g)do c8:draw()c8:drawUpdate()end end;local fS=false;local function fT(aO,cl,cm,cn,co)if aV:sendEvent("basaltEventCycle",aO,cl,cm,cn,co)==false then return end;if f~=nil then if aO=="mouse_click"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="mouse_drag"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="mouse_up"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="mouse_scroll"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="monitor_touch"then if g[cl]~=nil then g[cl]:mouseHandler(aO,cl,cm,cn,co)e=g[cl]end end end;if aO=="key"or aO=="char"then e:keyHandler(aO,cl)e:backgroundKeyHandler(aO,cl)end;if aO=="key"then b[cl]=true end;if aO=="key_up"then b[cl]=false end;for aS,c8 in pairs(d)do c8:eventHandler(aO,cl,cm,cn,co)end;fR()end;function a.autoUpdate(fk)fS=fk;if fk==nil then fS=true end;fR()while fS do local aO,cl,cm,cn,co=os.pullEventRaw()fT(aO,cl,cm,cn,co)end end;function a.update(aO,cl,cm,cn,co)if aO~=nil then fT(aO,cl,cm,cn,co)end end;function a.stop()fS=false end;function a.isKeyDown(bv)if b[bv]==nil then return false end;return b[bv]end;function a.getFrame(bL)for aS,aT in pairs(d)do if aT.name==bL then return aT end end end;function a.getActiveFrame()return e end;function a.setActiveFrame(b_)if b_:getType()=="Frame"then e=b_;return true end;return false end;function a.onEvent(...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then aV:registerEvent("basaltEventCycle",c8)end end end;function a.createFrame(bL)for aS,c8 in pairs(d)do if c8.name==bL then return nil end end;local fU=fs(bL)table.insert(d,fU)return fU end;function a.removeFrame(bL)d[bL]=nil 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("topRight"):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=f;a.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show()end;if a.debugger then function a.debug(...)local b0={...}if f.name~="basaltDebuggingFrame"then if f~=a.debugFrame then a.debugLabel:setParent(f)end end;local fV=""for bv,aT in pairs(b0)do fV=fV..tostring(aT)..(#b0~=bv and", "or"")end;a.debugLabel:setText("[Debug] "..fV)a.debugList:addItem(fV)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/_sidebar.md b/docs/_sidebar.md index b94ca2d..591ce9f 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -3,8 +3,8 @@ - [Quick Start](home/Quick-Start.md) - [Installer](home/installer) - Objects - - [Object](objects/Object) - [Basalt](objects/Basalt) + - [Object](objects/Object) - [Button](objects/Button) - [Checkbox](objects/Checkbox) - [Dropdown](objects/Dropdown) @@ -25,6 +25,8 @@ - [Timer](objects/Timer) - Events - [Mouse Events](events/mouseEvents.md) + - [Keyboard Events](events/keyEvents.md) + - [Other Events](events/otherEvents.md) - Tips & Tricks - [Component Logic](tips/logic) - [Changing Button Color](tips/buttons) diff --git a/docs/events/otherEvents.md b/docs/events/otherEvents.md new file mode 100644 index 0000000..7f48636 --- /dev/null +++ b/docs/events/otherEvents.md @@ -0,0 +1,50 @@ +There are also other useful events you can listen to: + +# onChange +`onChange(self)`
+This is a custom event which gets triggered as soon as the method :setValue() gets called. Not only you can call :setValue(), also input, checkbox, textfield, ... objects call them internally. + +Here is a example on how to add a onChange event to your input, and also another example for your checkbox: + +```lua +local basalt = dofile("basalt.lua") + +local mainFrame = basalt.createFrame("myMainFrame"):show() +local aInput = mainFrame:addInput("specialInput"):setPosition(3,3):show() +local aCheckbox = mainFrame:addCheckbox("specialCheckbox"):setPosition(3,5):show() + +local function checkInput(input) + if(string.lower(input:getValue())=="hello")then + basalt.debug("Hello back!") + end +end + +local function checkCheckbox(checkbox) + if(checkbox:getValue()==true)then -- or if(checkbox:getValue())then + basalt.debug("Checkbox is active, let us do something!") + end +end + +aInput:onChange(checkInput) +aCheckbox:onChange(checkCheckbox) +``` + +# onResize +`onResize(self)`
+This is a custom event which gets triggered as soon as the parent frame gets resized. + +Here is a example on how to add a onResize event to your button: + +```lua +local basalt = dofile("basalt.lua") + +local mainFrame = basalt.createFrame("myMainFrame"):show() +local aButton = mainFrame:addButton("myButton"):setPosition(3,3):show() + +local function onButtonResize(button) + local width = mainFrame:getWidth() + button:setSize() +end + +aButton:onResize(onButtonResize) +``` diff --git a/source/project/Frame.lua b/source/project/Frame.lua index fc0151c..01f880c 100644 --- a/source/project/Frame.lua +++ b/source/project/Frame.lua @@ -10,7 +10,8 @@ local function Frame(name, parent) local monSide = "" local isMonitor = false local monitorAttached = false - local dragOffset = 0 + local dragXOffset = 0 + local dragYOffset = 0 base:setZIndex(10) @@ -109,6 +110,19 @@ local function Frame(name, parent) return self end; + setSize = function(self, w, h) + base.setSize(self, w, h) + for _, index in pairs(objZIndex) do + if (objects[index] ~= nil) then + for _, value in pairs(objects[index]) do + if (value.eventHandler ~= nil) then + value:sendEvent("basalt_resize", value, self) + end + end + end + end + end; + setOffset = function(self, xO, yO) xOffset = xO ~= nil and math.floor(xO < 0 and math.abs(xO) or -xO) or xOffset yOffset = yO ~= nil and math.floor(yO < 0 and math.abs(yO) or -yO) or yOffset @@ -208,7 +222,7 @@ local function Frame(name, parent) end; setMonitor = function(self, side) - if(side~=nil)or(side~=false)then + if(side~=nil)and(side~=false)then if(peripheral.getType(side)=="monitor")then termObject = peripheral.wrap(side) monitorAttached = true @@ -321,7 +335,7 @@ local function Frame(name, parent) if (self.parent ~= nil) then parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) end - self:setPosition(x + dragOffset - (parentX - 1) + xO, y - (parentY - 1) + yO) + self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO) end if (event == "mouse_up") then self.drag = false @@ -329,6 +343,13 @@ local function Frame(name, parent) return true end + local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + local yOff = false + if(objY-1 == y)and(self:getBorder("top"))then + y = y+1 + yOff = true + end + if (base.mouseHandler(self, event, button, x, y)) then local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) fx = fx + xOffset;fy = fy + yOffset; @@ -343,13 +364,14 @@ local function Frame(name, parent) end end end - - if (self.isMoveable) then - if (x >= fx) and (x <= fx + self.width - 1) and (y == fy) and (event == "mouse_click") then - self.drag = true - dragOffset = fx - x + if (self.isMoveable) then + local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) + if (x >= fx) and (x <= fx + self.width - 1) and (y == fy) and (event == "mouse_click") then + self.drag = true + dragXOffset = fx - x + dragYOffset = yOff and 1 or 0 + end end - end if (focusedObject ~= nil) then focusedObject:loseFocusHandler() focusedObject = nil @@ -364,9 +386,9 @@ local function Frame(name, parent) if (y >= 1) and (y <= self.height) then if (self.parent ~= nil) then local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1)) + self.parent:setText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) else - drawHelper.setText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), self.width - x + 1)) + drawHelper.setText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) -- math.max(self.width - x + 1,1) now, before: self.width - x + 1 end end end; @@ -376,9 +398,9 @@ local function Frame(name, parent) if (y >= 1) and (y <= self.height) then if (self.parent ~= nil) then local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setBG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(bgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + self.parent:setBG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) else - drawHelper.setBG(math.max(x + (obx - 1), obx), oby + y - 1, sub(bgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + drawHelper.setBG(math.max(x + (obx - 1), obx), oby + y - 1, sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) end end end; @@ -388,9 +410,9 @@ local function Frame(name, parent) if (y >= 1) and (y <= self.height) then if (self.parent ~= nil) then local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setFG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(fgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + self.parent:setFG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) else - drawHelper.setFG(math.max(x + (obx - 1), obx), oby + y - 1, sub(fgCol, math.max(1 - x + 1, 1), self.width - x + 1)) + drawHelper.setFG(math.max(x + (obx - 1), obx), oby + y - 1, sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) end end end; @@ -402,7 +424,7 @@ local function Frame(name, parent) local parentX, parentY = self.parent:getAnchorPosition() self.parent:writeText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) else - drawHelper.writeText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) + drawHelper.writeText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1)), bgCol, fgCol) end end end; @@ -450,13 +472,17 @@ local function Frame(name, parent) local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) local anchx, anchy = self:getAnchorPosition() if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx, anchy, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(anchx, anchy, self.width, self.height, self.fgColor) - self.parent:drawTextBox(anchx, anchy, self.width, self.height, " ") + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(anchx, anchy, self.width, self.height, self.bgColor) + self.parent:drawTextBox(anchx, anchy, self.width, self.height, " ") + end + if(self.bgColor~=false)then self.parent:drawForegroundBox(anchx, anchy, self.width, self.height, self.fgColor) end else - drawHelper.drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") + if(self.bgColor~=false)then + drawHelper.drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") + end + if(self.fgColor~=false)then drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end end termObject.setCursorBlink(false) if (self.barActive) then @@ -465,6 +491,19 @@ local function Frame(name, parent) else drawHelper.writeText(obx, oby, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) end + if(self:getBorder("left"))then + if (self.parent ~= nil) then + self.parent:drawBackgroundBox(anchx-1, anchy, 1, 1, self.barBackground) + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(anchx-1, anchy+1, 1, self.height-1, self.bgColor) + end + end + end + if(self:getBorder("top"))then + if (self.parent ~= nil) then + self.parent:drawBackgroundBox(anchx-1, anchy-1, self.width+1, 1, self.barBackground) + end + end end for _, index in rpairs(objZIndex) do diff --git a/source/project/Object.lua b/source/project/Object.lua index a72094e..18b43e7 100644 --- a/source/project/Object.lua +++ b/source/project/Object.lua @@ -3,11 +3,19 @@ local function Object(name) local objectType = "Object" -- not changeable local value local zIndex = 1 - local hanchor = "left" - local vanchor = "top" + local anchor = "topLeft" local ignOffset = false local isVisible = false + local shadow = false + local borderLeft = false + local borderTop = false + local borderRight = false + local borderBottom = false + + local shadowColor = colors.black + local borderColor = colors.black + local visualsChanged = true local eventSystem = BasaltEvents() @@ -179,8 +187,104 @@ local function Object(name) return self.fgColor end; + showShadow = function(self, show) + shadow = show or (not shadow) + return self + end; + + setShadow = function(self, color) + shadowColor = color + return self + end; + + isShadowActive = function(self) + return shadow; + end; + + showBorder = function(self, ...) + for _,v in pairs(table.pack(...))do + if(v=="left")then + borderLeft = true + end + if(v=="top")then + borderTop = true + end + if(v=="right")then + borderRight = true + end + if(v=="bottom")then + borderBottom = true + end + end + return self + end; + + setBorder = function(self, color) + shadowColor = color + return self + end; + + getBorder = function(self, side) + if(side=="left")then + return borderLeft; + end + if(side=="top")then + return borderTop; + end + if(side=="right")then + return borderRight; + end + if(side=="bottom")then + return borderBottom; + end + end; + draw = function(self) if (isVisible) then + if(self.parent~=nil)then + local x, y = self:getAnchorPosition() + if(shadow)then + self.parent:drawBackgroundBox(x+1, y+self.height, self.width, 1, shadowColor) + self.parent:drawBackgroundBox(x+self.width, y+1, 1, self.height, shadowColor) + self.parent:drawForegroundBox(x+1, y+self.height, self.width, 1, shadowColor) + self.parent:drawForegroundBox(x+self.width, y+1, 1, self.height, shadowColor) + end + if(borderLeft)then + self.parent:drawTextBox(x-1, y, 1, self.height, "\149") + self.parent:drawForegroundBox(x-1, y, 1, self.height, borderColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y, 1, self.height, self.bgColor) end + end + if(borderLeft)and(borderTop)then + self.parent:drawTextBox(x-1, y-1, 1, 1, "\151") + self.parent:drawForegroundBox(x-1, y-1, 1, 1, borderColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y-1, 1, 1, self.bgColor) end + end + if(borderTop)then + self.parent:drawTextBox(x, y-1, self.width, 1, "\131") + self.parent:drawForegroundBox(x, y-1, self.width, 1, borderColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(x, y-1, self.width, 1, self.bgColor) end + end + if(borderTop)and(borderRight)then + self.parent:drawTextBox(x+self.width, y-1, 1, 1, "\149") + self.parent:drawForegroundBox(x+self.width, y-1, 1, 1, borderColor) + end + if(borderRight)then + self.parent:drawTextBox(x+self.width, y, 1, self.height, "\149") + self.parent:drawForegroundBox(x+self.width, y, 1, self.height, borderColor) + end + if(borderRight)and(borderBottom)then + self.parent:drawTextBox(x+self.width, y+self.height, 1, 1, "\129") + self.parent:drawForegroundBox(x+self.width, y+self.height, 1, 1, borderColor) + end + if(borderBottom)then + self.parent:drawTextBox(x, y+self.height, self.width, 1, "\131") + self.parent:drawForegroundBox(x, y+self.height, self.width, 1, borderColor) + end + if(borderBottom)and(borderLeft)then + self.parent:drawTextBox(x-1, y+self.height, 1, 1, "\131") + self.parent:drawForegroundBox(x-1, y+self.height, 1, 1, borderColor) + end + end return true end return false @@ -208,11 +312,26 @@ local function Object(name) if (y == nil) then y = self.y end - if (hanchor == "right") then - x = self.parent.width - x - self.width + 2 - end - if (vanchor == "bottom") then - y = self.parent.height - y - self.height + 2 + if (anchor == "top") then + x = math.floor(self.parent.width/2) + x - 1 + elseif(anchor == "topRight") then + x = self.parent.width + x - 1 + elseif(anchor == "right") then + x = self.parent.width + x - 1 + y = math.floor(self.parent.height/2) + y - 1 + elseif(anchor == "bottomRight") then + x = self.parent.width + x - 1 + y = self.parent.height + y - 1 + elseif(anchor == "bottom") then + x = math.floor(self.parent.width/2) + x - 1 + y = self.parent.height + y - 1 + elseif(anchor == "bottomLeft") then + y = self.parent.height + y - 1 + elseif(anchor == "left") then + y = math.floor(self.parent.height/2) + y - 1 + elseif(anchor == "center") then + x = math.floor(self.parent.width/2) + x - 1 + y = math.floor(self.parent.height/2) + y - 1 end local xO, yO = self:getOffset() if not(ignOffset or ignOff) then @@ -241,74 +360,116 @@ local function Object(name) return self end; - setAnchor = function(self, ...) - for _, value in pairs(table.pack(...)) do - if (value == "right") or (value == "left") then - hanchor = value - end - if (value == "top") or (value == "bottom") then - vanchor = value - end - end + setAnchor = function(self, newAnchor) + anchor = newAnchor visualsChanged = true return self end; getAnchor = function(self) - return hanchor, vanchor + return anchor end; - onChange = function(self, func) - self:registerEvent("value_changed", func) + onChange = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("value_changed", v) + end + end return self end; - onClick = function(self, func) - self:registerEvent("mouse_click", func) - self:registerEvent("monitor_touch", func) + onClick = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_click", v) + self:registerEvent("monitor_touch", v) + end + end return self end; - onClickUp = function(self, func) - self:registerEvent("mouse_up", func) + onClickUp = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_up", v) + end + end return self end; - onScroll = function(self, func) - self:registerEvent("mouse_scroll", func) + onScroll = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_scroll", v) + end + end return self end; - onDrag = function(self, func) - self:registerEvent("mouse_drag", func) + onDrag = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_drag", v) + end + end return self end; - onEvent = function(self, func) - self:registerEvent("custom_event_handler", func) + onEvent = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("custom_event_handler", v) + end + end return self end; - onKey = function(self, func) - self:registerEvent("key", func) - self:registerEvent("char", func) + onKey = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("key", v) + self:registerEvent("char", v) + end + end return self end; - onKeyUp = function(self, func) - self:registerEvent("key_up", func) + onResize = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("basalt_resize", v) + end + end return self end; - onBackgroundKey = function(self, func) - self:registerEvent("background_key", func) - self:registerEvent("background_char", func) + onKeyUp = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("key_up", v) + end + end return self end; - onBackgroundKeyUp = function(self, func) - self:registerEvent("background_key_up", func) + onBackgroundKey = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("background_key", v) + self:registerEvent("background_char", v) + end + end + return self + end; + + onBackgroundKeyUp = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("background_key_up", v) + end + end return self end; @@ -319,13 +480,21 @@ local function Object(name) return false end; - onGetFocus = function(self, func) - self:registerEvent("get_focus", func) + onGetFocus = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("get_focus", v) + end + end return self end; - onLoseFocus = function(self, func) - self:registerEvent("lose_focus", func) + onLoseFocus = function(self, ...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("lose_focus", v) + end + end return self end; @@ -343,11 +512,18 @@ local function Object(name) mouseHandler = function(self, event, button, x, y) local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + local yOff = false + if(objY-1 == y)and(self:getBorder("top"))then + y = y+1 + yOff = true + end + if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (isVisible) then if (self.parent ~= nil) then self.parent:setFocusedObject(self) end - eventSystem:sendEvent(event, self, event, button, x, y) + local val = eventSystem:sendEvent(event, self, event, button, x, y) + if(val~=nil)then return val end return true end return false @@ -355,14 +531,17 @@ local function Object(name) keyHandler = function(self, event, key) if (self:isFocused()) then - eventSystem:sendEvent(event, self, event, key) + local val = eventSystem:sendEvent(event, self, event, key) + if(val~=nil)then return val end return true end return false end; backgroundKeyHandler = function(self, event, key) - eventSystem:sendEvent("background_" .. event, self, event, key) + local val = eventSystem:sendEvent("background_"..event, self, event, key) + if(val~=nil)then return val end + return true end; valueChangedHandler = function(self) @@ -374,11 +553,15 @@ local function Object(name) end; getFocusHandler = function(self) - eventSystem:sendEvent("get_focus", self) + local val = eventSystem:sendEvent("get_focus", self) + if(val~=nil)then return val end + return true end; loseFocusHandler = function(self) - eventSystem:sendEvent("lose_focus", self) + local val = eventSystem:sendEvent("lose_focus", self) + if(val~=nil)then return val end + return true end; diff --git a/source/project/lib/eventSystem.lua b/source/project/lib/eventSystem.lua index 9a2480e..84f6421 100644 --- a/source/project/lib/eventSystem.lua +++ b/source/project/lib/eventSystem.lua @@ -19,13 +19,19 @@ local function BasaltEvents() end; sendEvent = function(self, _event, ...) + local returnValue if (events[_event] ~= nil) then for _, value in pairs(events[_event]) do - value(...) + local val = value(...) + if(val==false)then + returnValue = val + end end end + return returnValue end; } event.__index = event return event -end \ No newline at end of file +end +local eventSystem = BasaltEvents() \ No newline at end of file diff --git a/source/project/lib/process.lua b/source/project/lib/process.lua index 2b4d0b4..fc9ae9c 100644 --- a/source/project/lib/process.lua +++ b/source/project/lib/process.lua @@ -8,7 +8,7 @@ function process:new(path, window, ...) newP.window = window newP.processId = processId newP.coroutine = coroutine.create(function() - os.run({ basalt = basalt }, path, table.unpack(args)) + os.run({ }, path, table.unpack(args)) end) processes[processId] = newP processId = processId + 1 diff --git a/source/project/lib/utils.lua b/source/project/lib/utils.lua index 7cad2d9..ad2fb7e 100644 --- a/source/project/lib/utils.lua +++ b/source/project/lib/utils.lua @@ -36,9 +36,8 @@ local function rpairs(t) end, t, #t + 1 end +-- shrink system is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ local function shrink(bLittleData, bgColor) - - -- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 }, { 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } } diff --git a/source/project/mainBottom.lua b/source/project/mainBottom.lua index de190ff..ccac3c9 100644 --- a/source/project/mainBottom.lua +++ b/source/project/mainBottom.lua @@ -9,6 +9,7 @@ end local updaterActive = false local function basaltUpdateEvent(event, p1, p2, p3, p4) + if(eventSystem:sendEvent("basaltEventCycle", event, p1, p2, p3, p4)==false)then return end if(mainFrame~=nil)then if (event == "mouse_click") then mainFrame:mouseHandler(event, p1, p2, p3, p4) @@ -46,9 +47,7 @@ local function basaltUpdateEvent(event, p1, p2, p3, p4) for _, v in pairs(frames) do v:eventHandler(event, p1, p2, p3, p4) end - if (updaterActive) then - drawFrames() - end + drawFrames() end function basalt.autoUpdate(isActive) @@ -64,8 +63,6 @@ end function basalt.update(event, p1, p2, p3, p4) if (event ~= nil) then basaltUpdateEvent(event, p1, p2, p3, p4) - else - drawFrames() end end @@ -98,6 +95,14 @@ function basalt.setActiveFrame(frame) return false end +function basalt.onEvent(...) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + eventSystem:registerEvent("basaltEventCycle", v) + end + end +end + function basalt.createFrame(name) for _, v in pairs(frames) do if (v.name == name) then @@ -117,8 +122,8 @@ end if (basalt.debugger) then basalt.debugFrame = basalt.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug", colors.black, colors.gray) basalt.debugList = basalt.debugFrame:addList("debugList"):setSize(basalt.debugFrame.width - 2, basalt.debugFrame.height - 3):setPosition(2, 3):setScrollable(true):show() - basalt.debugFrame:addButton("back"):setAnchor("right"):setSize(1, 1):setText("\22"):onClick(function() basalt.oldFrame:show() end):setBackground(colors.red):show() - basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):ignoreOffset():setZIndex(20):show() + basalt.debugFrame:addButton("back"):setAnchor("topRight"):setSize(1, 1):setText("\22"):onClick(function() basalt.oldFrame:show() end):setBackground(colors.red):show() + basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show() end if (basalt.debugger) then diff --git a/source/project/objects/Button.lua b/source/project/objects/Button.lua index 54cf931..c6ab3f7 100644 --- a/source/project/objects/Button.lua +++ b/source/project/objects/Button.lua @@ -35,9 +35,11 @@ local function Button(name) local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + self.parent:drawTextBox(obx, oby, self.width, self.height, " ") + end + if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end for n = 1, self.height do if (n == verticalAlign) then self.parent:setText(obx, oby + (n - 1), getTextHorizontalAlign(self:getValue(), self.width, textHorizontalAlign)) diff --git a/source/project/objects/Checkbox.lua b/source/project/objects/Checkbox.lua index e22df58..41e9b9d 100644 --- a/source/project/objects/Checkbox.lua +++ b/source/project/objects/Checkbox.lua @@ -37,7 +37,7 @@ local function Checkbox(name) local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, "center") - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end for n = 1, self.height do if (n == verticalAlign) then if (self:getValue() == true) then diff --git a/source/project/objects/Dropdown.lua b/source/project/objects/Dropdown.lua index 1d4e366..1cac811 100644 --- a/source/project/objects/Dropdown.lua +++ b/source/project/objects/Dropdown.lua @@ -140,7 +140,7 @@ local function Dropdown(name) if (base.draw(self)) then local obx, oby = self:getAnchorPosition() if (self.parent ~= nil) then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) 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) diff --git a/source/project/objects/Image.lua b/source/project/objects/Image.lua index 482ce54..2c05f65 100644 --- a/source/project/objects/Image.lua +++ b/source/project/objects/Image.lua @@ -142,7 +142,7 @@ local function Image(name) loadBlittleImage = function(self, path) -- not done yet --image = paintutils.loadImage(path) - imageGotShrinked = true + --imageGotShrinked = true return self end; diff --git a/source/project/objects/Input.lua b/source/project/objects/Input.lua index 10aa372..748d848 100644 --- a/source/project/objects/Input.lua +++ b/source/project/objects/Input.lua @@ -78,7 +78,7 @@ local function Input(name) local obx, oby = self:getAnchorPosition() showingText = "" if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby, self.fgColor) + self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor) end end end; @@ -181,7 +181,7 @@ local function Input(name) cursorX = self.x + self.width - 1 end if (self.parent ~= nil) then - self.parent:setCursor(true, obx + cursorX, oby, self.fgColor) + self.parent:setCursor(true, obx + cursorX, oby+math.floor(self.height/2), self.fgColor) end internalValueChange = false end @@ -203,7 +203,7 @@ local function Input(name) local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, "center") - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end for n = 1, self.height do if (n == verticalAlign) then local val = tostring(base.getValue()) diff --git a/source/project/objects/Label.lua b/source/project/objects/Label.lua index c5524b5..a764fea 100644 --- a/source/project/objects/Label.lua +++ b/source/project/objects/Label.lua @@ -57,9 +57,10 @@ local function Label(name) if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + self.parent:drawTextBox(obx, oby, self.width, self.height, " ") end + if(self.bgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end if(fontsize==0)then for n = 1, self.height do if (n == verticalAlign) then diff --git a/source/project/objects/List.lua b/source/project/objects/List.lua index cbc0f7d..3c13521 100644 --- a/source/project/objects/List.lua +++ b/source/project/objects/List.lua @@ -135,7 +135,9 @@ local function List(name) 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.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end for n = 1, self.height do if (list[n + yOffset] ~= nil) then if (list[n + yOffset] == self:getValue()) then diff --git a/source/project/objects/Menubar.lua b/source/project/objects/Menubar.lua index 1d8836e..464ab97 100644 --- a/source/project/objects/Menubar.lua +++ b/source/project/objects/Menubar.lua @@ -170,7 +170,9 @@ local function Menubar(name) 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.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end local text = "" local textBGCol = "" local textFGCol = "" diff --git a/source/project/objects/Program.lua b/source/project/objects/Program.lua index 12e0e23..d0c5acc 100644 --- a/source/project/objects/Program.lua +++ b/source/project/objects/Program.lua @@ -543,6 +543,7 @@ local function Program(name) if not (paused) then local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true)) curProcess:resume(event, button, x - (absX - 1), y - (absY - 1)) + basalt.debug(event, button, x - (absX - 1), y - (absY - 1)) end end return true @@ -630,7 +631,9 @@ local function Program(name) if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() pWindow.basalt_reposition(obx, oby) - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end pWindow.basalt_update() end self:setVisualChanged(false) diff --git a/source/project/objects/Textfield.lua b/source/project/objects/Textfield.lua index fa7b59c..8225e1e 100644 --- a/source/project/objects/Textfield.lua +++ b/source/project/objects/Textfield.lua @@ -312,8 +312,12 @@ local function Textfield(name) 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) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) + end + if(self.fgColor~=false)then + self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) + end for n = 1, self.height do local text = "" if (lines[n + hIndex - 1] ~= nil) then