diff --git a/BasaltLS.lua b/BasaltLS.lua index 6dd07d8..484a152 100644 --- a/BasaltLS.lua +++ b/BasaltLS.lua @@ -1,778 +1,216 @@ ---@meta ----@class ComboBox : DropDown ----@field cursorPos number Current cursor position in the text input ----@field viewOffset number Horizontal scroll position for viewing long text ----@field manuallyOpened boolean Indicates if dropdown was opened by user action ----@field autoComplete boolean Enables filtering dropdown items while typing ----@field text string The current text value of the input field ----@field editable boolean Enables direct text input in the field -local ComboBox = {} +---@class Menu : List +---@field separatorColor color The color used for separator items in the menu +---@field maxWidth number Maximum width before scrolling is enabled (nil = auto-size to items) +---@field horizontalOffset number Current horizontal scroll offset +---@field spacing number The number of spaces between menu items +local Menu = {} ----Gets the value of the ManuallyOpened property. ----@param self ComboBox self ----@return boolean false Indicates if dropdown was opened by user action -function ComboBox:getManuallyOpened(self) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Menu:mouse_click() end ----Sets the value of the Editable property. ----@param self ComboBox self ----@param Editable boolean Enables direct text input in the field -function ComboBox:setEditable(self, Editable) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Menu:render() end ----Gets the value of the ViewOffset property. ----@param self ComboBox self ----@return number 0 Horizontal scroll position for viewing long text -function ComboBox:getViewOffset(self) end +---Calculates the total width of all menu items with spacing +---@return number totalWidth The total width of all items +function Menu:getTotalWidth() end ----Sets the value of the Text property. ----@param self ComboBox self ----@param Text string The current text value of the input field -function ComboBox:setText(self, Text) end +---Gets the value of the HorizontalOffset property. +---@param self Menu self +---@return number 0 Current horizontal scroll offset +function Menu:getHorizontalOffset(self) end ----Creates a new ComboBox instance ----@return ComboBox self The newly created ComboBox instance -function ComboBox.new() end +---Sets the value of the MaxWidth property. +---@param self Menu self +---@param MaxWidth number Maximum width before scrolling is enabled (nil = auto-size to items) +function Menu:setMaxWidth(self, MaxWidth) end ----Sets the value of the ViewOffset property. ----@param self ComboBox self ----@param ViewOffset number Horizontal scroll position for viewing long text -function ComboBox:setViewOffset(self, ViewOffset) end +---Gets the value of the MaxWidth property. +---@param self Menu self +---@return number nil Maximum width before scrolling is enabled (nil = auto-size to items) +function Menu:getMaxWidth(self) end + +---Gets the value of the Spacing property. +---@param self Menu self +---@return number 0 The number of spaces between menu items +function Menu:getSpacing(self) end + +---Sets the value of the Spacing property. +---@param self Menu self +---@param Spacing number The number of spaces between menu items +function Menu:setSpacing(self, Spacing) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Menu:mouse_scroll() end + +---Gets the value of the SeparatorColor property. +---@param self Menu self +---@return color gray The color used for separator items in the menu +function Menu:getSeparatorColor(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with ---@param basalt table The basalt instance ----@return ComboBox self The initialized instance +---@return Menu self The initialized instance ---@protected -function ComboBox:init(props, basalt) end +function Menu:init(props, basalt) end ----Renders the ComboBox +---Sets the value of the SeparatorColor property. +---@param self Menu self +---@param SeparatorColor color The color used for separator items in the menu +function Menu:setSeparatorColor(self, SeparatorColor) end + +---Sets the value of the HorizontalOffset property. +---@param self Menu self +---@param HorizontalOffset number Current horizontal scroll offset +function Menu:setHorizontalOffset(self, HorizontalOffset) end + +---@class Reactive +local Reactive = {} + +---@class ScrollFrame : Container +---@field showScrollBar boolean Whether to show scrollbars +---@field scrollBarBackgroundSymbol string The symbol used for the scrollbar background +---@field scrollBarSymbol string The symbol used for the scrollbar handle +---@field scrollBarColor color Color of the scrollbar handle +---@field contentWidth number The total width of the content (calculated from children) +---@field contentHeight number The total height of the content (calculated from children) +---@field scrollBarBackgroundColor color Background color of the scrollbar +---@field scrollBarBackgroundColor2 secondary black Background color of the scrollbar +local ScrollFrame = {} + +---Renders the ScrollFrame and its scrollbars ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected -function ComboBox:render() end +function ScrollFrame:render() end ----Sets the value of the CursorPos property. ----@param self ComboBox self ----@param CursorPos number Current cursor position in the text input -function ComboBox:setCursorPos(self, CursorPos) end +---Handles mouse drag events for scrollbar +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button being dragged +---@param x number The x-coordinate of the drag +---@param y number The y-coordinate of the drag +---@return boolean Whether the event was handled +---@protected +function ScrollFrame:mouse_drag(button, x, y) end ----Handles mouse up events for item selection +---Sets the value of the ScrollBarBackgroundSymbol property. +---@param self ScrollFrame self +---@param ScrollBarBackgroundSymbol string The symbol used for the scrollbar background +function ScrollFrame:setScrollBarBackgroundSymbol(self, ScrollBarBackgroundSymbol) end + +---Sets the value of the ScrollBarSymbol property. +---@param self ScrollFrame self +---@param ScrollBarSymbol string The symbol used for the scrollbar handle +function ScrollFrame:setScrollBarSymbol(self, ScrollBarSymbol) end + +---Sets the value of the ContentHeight property. +---@param self ScrollFrame self +---@param ContentHeight number The total height of the content (calculated from children) +function ScrollFrame:setContentHeight(self, ContentHeight) end + +---Handles mouse scroll events +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number 1 for up, -1 for down +---@param x number Mouse x position relative to element +---@param y number Mouse y position relative to element +---@return boolean Whether the event was handled +---@protected +function ScrollFrame:mouse_scroll(direction, x, y) end + +---Handles mouse up events to stop scrollbar dragging ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The mouse button that was released ---@param x number The x-coordinate of the release ---@param y number The y-coordinate of the release ----@return boolean handled Whether the event was handled +---@return boolean Whether the event was handled ---@protected -function ComboBox:mouse_up(button, x, y) end +function ScrollFrame:mouse_up(button, x, y) end ----Handles mouse clicks +---Gets the value of the ScrollBarColor property. +---@param self ScrollFrame self +---@return color lightGray Color of the scrollbar handle +function ScrollFrame:getScrollBarColor(self) end + +---Sets the value of the ScrollBarColor property. +---@param self ScrollFrame self +---@param ScrollBarColor color Color of the scrollbar handle +function ScrollFrame:setScrollBarColor(self, ScrollBarColor) end + +---Sets the value of the ContentWidth property. +---@param self ScrollFrame self +---@param ContentWidth number The total width of the content (calculated from children) +function ScrollFrame:setContentWidth(self, ContentWidth) end + +---Handles mouse click events for scrollbars and content ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button (1 = left, 2 = right, 3 = middle) ----@param x number The x coordinate of the click ----@param y number The y coordinate of the click ----@return boolean handled Whether the event was handled +---@param button number The mouse button (1=left, 2=right, 3=middle) +---@param x number The x-coordinate of the click +---@param y number The y-coordinate of the click +---@return boolean Whether the event was handled ---@protected -function ComboBox:mouse_click(button, x, y) end - ----Handles character input when editable ----@param char string The character that was typed -function ComboBox:char(char) end - ----Handles key input when editable ----@param key number The key code that was pressed ----@param held boolean Whether the key is being held -function ComboBox:key(key, held) end - ----Gets the value of the Text property. ----@param self ComboBox self ----@return string "" The current text value of the input field -function ComboBox:getText(self) end - ----Sets the value of the ManuallyOpened property. ----@param self ComboBox self ----@param ManuallyOpened boolean Indicates if dropdown was opened by user action -function ComboBox:setManuallyOpened(self, ManuallyOpened) end - ----Gets the value of the Editable property. ----@param self ComboBox self ----@return boolean true Enables direct text input in the field -function ComboBox:getEditable(self) end - ----Gets the value of the CursorPos property. ----@param self ComboBox self ----@return number 1 Current cursor position in the text input -function ComboBox:getCursorPos(self) end - ----Gets the value of the AutoComplete property. ----@param self ComboBox self ----@return boolean false Enables filtering dropdown items while typing -function ComboBox:getAutoComplete(self) end - ----Sets the value of the AutoComplete property. ----@param self ComboBox self ----@param AutoComplete boolean Enables filtering dropdown items while typing -function ComboBox:setAutoComplete(self, AutoComplete) end - ----@class Label : VisualElement ----@field autoSize boolean Whether the label should automatically resize its width based on the text content ----@field text string The text content to display. Can be a string or a function that returns a string -local Label = {} - ----Sets the value of the Text property. ----@param self Label self ----@param Text string The text content to display. Can be a string or a function that returns a string -function Label:setText(self, Text) end - ----Gets the value of the AutoSize property. ----@param self Label self ----@return boolean true Whether the label should automatically resize its width based on the text content -function Label:getAutoSize(self) end - ----Gets the wrapped lines of the Label ----@return table wrappedText The wrapped lines of the Label -function Label:getWrappedText() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Label:render() end - ----Gets the value of the Text property. ----@param self Label self ----@return string Label The text content to display. Can be a string or a function that returns a string -function Label:getText(self) end - ----Sets the value of the AutoSize property. ----@param self Label self ----@param AutoSize boolean Whether the label should automatically resize its width based on the text content -function Label:setAutoSize(self, AutoSize) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Label self The initialized instance ----@protected -function Label:init(props, basalt) end - ----@class VisualElement : BaseElement ----@field background color The background color ----@field height number The height of the element ----@field borderColor color Border color ----@field z number The z-index for layering elements ----@field visible boolean Whether the element is visible ----@field borderBottom boolean Draw bottom border ----@field foreground color The text/foreground color ----@field width number The width of the element ----@field borderTop boolean Draw top border ----@field borderLeft boolean Draw left border ----@field x number The horizontal position relative to parent ----@field y number The vertical position relative to parent ----@field backgroundEnabled boolean Whether to render the background ----@field layoutConfig table Configuration for layout systems (grow, shrink, alignSelf, etc.) ----@field ignoreOffset boolean Whether to ignore the parent's offset ----@field borderRight boolean Draw right border -local VisualElement = {} - ----Sets the element's height as a percentage of the target's height ----@param target BaseElement |string The target element or "parent" ----@param percent number Percentage of target's height (0-100) ----@return VisualElement self -function VisualElement:heightPercent(target, percent) end - ----Sets a constraint on a property relative to another element's property ----@param property string The property to constrain (x, y, width, height, left, right, top, bottom, centerX, centerY) ----@param targetElement BaseElement |string The target element or "parent" ----@param targetProperty string The target property to constrain to (left, right, top, bottom, centerX, centerY, width, height) ----@param offset number The offset to apply (negative = inside, positive = outside, fractional = percentage) ----@return VisualElement self The element instance -function VisualElement:setConstraint(property, targetElement, targetProperty, offset) end - ----Registers a function to handle the onLeave event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnLeave(self, func) end - ----Sets the value of the BackgroundEnabled property. ----@param self VisualElement self ----@param BackgroundEnabled boolean Whether to render the background -function VisualElement:setBackgroundEnabled(self, BackgroundEnabled) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:focus() end - ----Sets the value of the BorderColor property. ----@param self VisualElement self ----@param BorderColor color Border color -function VisualElement:setBorderColor(self, BorderColor) end - ----Gets the value of the BackgroundEnabled property. ----@param self VisualElement self ----@return boolean true Whether to render the background -function VisualElement:getBackgroundEnabled(self) end - ----Sets the value of the Y property. ----@param self VisualElement self ----@param Y number The vertical position relative to parent -function VisualElement:setY(self, Y) end - ----Stretches the element to match the target's width with optional margin ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:stretchWidth(target) end - ----Gets the value of the LayoutConfig property. ----@param self VisualElement self ----@return table {} Configuration for layout systems (grow, shrink, alignSelf, etc.) -function VisualElement:getLayoutConfig(self) end - ----Centers the element vertically relative to the target with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:centerVertical(target) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param _ number unknown ----@param x number The x position of the mouse ----@param y number The y position of the mouse ----@return boolean hover Whether the mouse has moved over the element ----@protected -function VisualElement:mouse_move(_, x, y) end - ----Gets the value of the BorderColor property. ----@param self VisualElement self ----@return color white Border color -function VisualElement:getBorderColor(self) end - ----Positions the element below the target with optional gap ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:below(target) end - ----Aligns the element's left edge to the target's left edge with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:alignLeft(target) end - ----Sets the value of the LayoutConfig property. ----@param self VisualElement self ----@param LayoutConfig table Configuration for layout systems (grow, shrink, alignSelf, etc.) -function VisualElement:setLayoutConfig(self, LayoutConfig) end - ----Registers a function to handle the onEnter event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnEnter(self, func) end - ----Positions the element above the target with optional gap ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:above(target) end - ----Aligns the element's right edge to its parent's right edge with optional gap ----@return VisualElement self -function VisualElement:toRight() end - ----Convenience to stop animations from the element -function VisualElement.stopAnimation() end - ----Sets the value of the BorderRight property. ----@param self VisualElement self ----@param BorderRight boolean Draw right border -function VisualElement:setBorderRight(self, BorderRight) end - ----Positions the element to the left of the target with optional gap ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:leftOf(target) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean clicked Whether the element was clicked ----@protected -function VisualElement:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction ----@param x number The x position of the scroll ----@param y number The y position of the scroll ----@return boolean scroll Whether the element was scrolled ----@protected -function VisualElement:mouse_scroll(direction, x, y) end - ----Gets the value of the Visible property. ----@param self VisualElement self ----@return boolean true Whether the element is visible -function VisualElement:getVisible(self) end - ----Gets the value of the Background property. ----@param self VisualElement self ----@return color black The background color -function VisualElement:getBackground(self) end - ----Centers the element within its parent both horizontally and vertically ----@return VisualElement self -function VisualElement:center() end - ----Sets the value of the Background property. ----@param self VisualElement self ----@param Background color The background color -function VisualElement:setBackground(self, Background) end - ----Registers a function to handle the onRelease event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnRelease(self, func) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:render() end - ----Sets or removes focus from this element ----@param focused boolean Whether to focus or blur ----@return VisualElement self -function VisualElement:setFocused(focused) end - ----Gets the value of the Height property. ----@param self VisualElement self ----@return number 1 The height of the element -function VisualElement:getHeight(self) end - ----Registers a function to handle the onChar event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnChar(self, func) end - ----Sets the value of the BorderLeft property. ----@param self VisualElement self ----@param BorderLeft boolean Draw left border -function VisualElement:setBorderLeft(self, BorderLeft) end - ----Gets the value of the BorderTop property. ----@param self VisualElement self ----@return boolean false Draw top border -function VisualElement:getBorderTop(self) end - ----Sets the value of the Foreground property. ----@param self VisualElement self ----@param Foreground color The text/foreground color -function VisualElement:setForeground(self, Foreground) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:postRender() end - ----Updates a single property in the layoutConfig table ----@param key string The layout config property to update (grow, shrink, basis, alignSelf, order, etc.) ----@param value any The value to set for the property ----@return VisualElement self The element instance -function VisualElement:setLayoutConfigProperty(key, value) end - -function VisualElement:drawText() end - ----Registers a function to handle the onDrag event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnDrag(self, func) end - ----Sets the value of the Height property. ----@param self VisualElement self ----@param Height number The height of the element -function VisualElement:setHeight(self, Height) end - ----Registers a function to handle the onKey event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnKey(self, func) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param text string The text char to draw ----@param fg string The foreground color ----@param bg string The background color ----@protected -function VisualElement:blit(x, y, text, fg, bg) end - ----Gets the value of the X property. ----@param self VisualElement self ----@return number 1 The horizontal position relative to parent -function VisualElement:getX(self) end - ----Gets the value of the IgnoreOffset property. ----@param self VisualElement self ----@return boolean false Whether to ignore the parent's offset -function VisualElement:getIgnoreOffset(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was pressed ----@protected -function VisualElement:char(char) end - ----Gets the value of the Width property. ----@param self VisualElement self ----@return number 1 The width of the element -function VisualElement:getWidth(self) end - ----Sets the value of the Z property. ----@param self VisualElement self ----@param Z number The z-index for layering elements -function VisualElement:setZ(self, Z) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position of the cursor ----@param y number The y position of the cursor ----@param blink boolean Whether the cursor should blink ----@param color number The color of the cursor ----@return VisualElement self The VisualElement instance ----@protected -function VisualElement:setCursor(x, y, blink, color) end - ----Gets the value of the Foreground property. ----@param self VisualElement self ----@return color white The text/foreground color -function VisualElement:getForeground(self) end - ----Resolves all constraints for the element ----@return VisualElement self The element instance -function VisualElement:resolveAllConstraints() end - ----Returns the relative position of the element or the given coordinates. ----@return number x The relative x position ----@return number y The relative y position -function VisualElement:getRelativePosition() end - ----Gets the value of the BorderRight property. ----@param self VisualElement self ----@return boolean false Draw right border -function VisualElement:getBorderRight(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@return boolean release Whether the element was released on the element ----@protected -function VisualElement:mouse_up(button, x, y) end - ----Registers a function to handle the onClick event. ----@param button string ----@param x number ----@param y number ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnClick(self, func) end - ----Gets a single property from the layoutConfig table ----@param key string The layout config property to get ----@return any value The value of the property, or nil if not set -function VisualElement:getLayoutConfigProperty(key) end - ----Sets the value of the Visible property. ----@param self VisualElement self ----@param Visible boolean Whether the element is visible -function VisualElement:setVisible(self, Visible) end - ----Centers the element horizontally relative to the target with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:centerHorizontal(target) end - -function VisualElement:destroy() end - ----Gets the value of the Z property. ----@param self VisualElement self ----@return number 1 The z-index for layering elements -function VisualElement:getZ(self) end - ----Sets the value of the X property. ----@param self VisualElement self ----@param X number The horizontal position relative to parent -function VisualElement:setX(self, X) end - -function VisualElement:drawBg() end - ----Registers a function to handle the onClickUp event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnClickUp(self, func) end - ----Gets the value of the BorderBottom property. ----@param self VisualElement self ----@return boolean false Draw bottom border -function VisualElement:getBorderBottom(self) end - ----Returns the absolute position of the element or the given coordinates. ----@return number x The absolute x position ----@return number y The absolute y position -function VisualElement:getAbsolutePosition() end - ----Matches the element's width to the target's width with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:matchWidth(target) end - ----Gets the value of the Y property. ----@param self VisualElement self ----@return number 1 The vertical position relative to parent -function VisualElement:getY(self) end - ----Removes a constraint from the element ----@param property string The property of the constraint to remove ----@return VisualElement self The element instance -function VisualElement:removeConstraint(property) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param text string The text char to draw ----@param bg color The background color ----@protected -function VisualElement:textBg(x, y, text, bg) end - ----Sets the value of the BorderBottom property. ----@param self VisualElement self ----@param BorderBottom boolean Draw bottom border -function VisualElement:setBorderBottom(self, BorderBottom) end - ----Aligns the element's right edge to the target's right edge with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:alignRight(target) end - ----Registers a function to handle the onScroll event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnScroll(self, func) end - ----Positions the element to the right of the target with optional gap ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:rightOf(target) end - ----Aligns the element's bottom edge to the target's bottom edge with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:alignBottom(target) end - ----Updates all constraints, recalculating positions and sizes ----@return VisualElement self The element instance -function VisualElement:updateConstraints() end - ----Removes the previously added border (if any) ----@return VisualElement self -function VisualElement:removeBorder() end - ----Aligns the element's bottom edge to its parent's bottom edge with optional gap ----@return VisualElement self -function VisualElement:toBottom() end - ----Aligns the element's top edge to its parent's top edge with optional gap ----@return VisualElement self -function VisualElement:toTop() end - ----Sets the element's width as a percentage of the target's width ----@param target BaseElement |string The target element or "parent" ----@param percent number Percentage of target's width (0-100) ----@return VisualElement self -function VisualElement:widthPercent(target, percent) end - ----Sets the value of the Width property. ----@param self VisualElement self ----@param Width number The width of the element -function VisualElement:setWidth(self, Width) end - ----Stretches the element to match the target's width and height with optional margin ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:stretch(target) end - ----Creates a new Animation Object ----@return Animation animation The new animation -function VisualElement:animate() end - ----This function is used to prioritize the element by moving it to the top of its parent's children. It removes the element from its parent and adds it back, effectively changing its order. ----@return VisualElement self The VisualElement instance -function VisualElement:prioritize() end - ----Sets the value of the IgnoreOffset property. ----@param self VisualElement self ----@param IgnoreOffset boolean Whether to ignore the parent's offset -function VisualElement:setIgnoreOffset(self, IgnoreOffset) end - ----Stretches the element to fill its parent's width with optional margin ----@return VisualElement self -function VisualElement:fillWidth() end - ----Sets the value of the BorderTop property. ----@param self VisualElement self ----@param BorderTop boolean Draw top border -function VisualElement:setBorderTop(self, BorderTop) end - ----Aligns the element's left edge to its parent's left edge with optional gap ----@return VisualElement self -function VisualElement:toLeft() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param text string The text char to draw ----@param fg color The foreground color ----@protected -function VisualElement:textFg(x, y, text, fg) end - ----Stretches the element to fill its parent's height with optional margin ----@return VisualElement self -function VisualElement:fillHeight() end - ----Stretches the element to match the target's height with optional margin ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:stretchHeight(target) end - ----Gets the value of the BorderLeft property. ----@param self VisualElement self ----@return boolean false Draw left border -function VisualElement:getBorderLeft(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:blur() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function VisualElement:init(props, basalt) end - ----Calculates the position of the element relative to its parent ----@return number x The x position ----@return number y The y position -function VisualElement:calculatePosition() end - ----Aligns the element's top edge to the target's top edge with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:alignTop(target) end - ----Registers a function to handle the onFocus event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnFocus(self, func) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param width number The width of the area to draw ----@param height number The height of the area to draw ----@param text string The text to draw ----@param fg string The foreground color ----@param bg string The background color ----@protected -function VisualElement:multiBlit(x, y, width, height, text, fg, bg) end - ----Registers a function to handle the onKeyUp event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnKeyUp(self, func) end - ----Gets whether this element is focused ----@return boolean isFocused -function VisualElement:isFocused() end - -function VisualElement:drawFg() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@protected -function VisualElement:key(key) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was released ----@protected -function VisualElement:key_up(key) end - ----Adds or updates a drawable character border around the element. The border will automatically adapt to size/background changes because the command reads current properties each render. ----@param colorOrOptions any Border color or options table ----@return VisualElement self -function VisualElement:addBorder(colorOrOptions) end - ----Stretches the element to fill its parent's width and height with optional margin ----@return VisualElement self -function VisualElement:fillParent() end - ----Matches the element's height to the target's height with optional offset ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:matchHeight(target) end - ----Registers a function to handle the onBlur event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnBlur(self, func) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked while dragging ----@param x number The x position of the drag ----@param y number The y position of the drag ----@return boolean drag Whether the element was dragged ----@protected -function VisualElement:mouse_drag(button, x, y) end - ----Checks if the specified coordinates are within the bounds of the element ----@param x number The x position to check ----@param y number The y position to check ----@return boolean isInBounds Whether the coordinates are within the bounds of the element -function VisualElement:isInBounds(x, y) end - ----Centers the element both horizontally and vertically relative to the target ----@param target BaseElement |string The target element or "parent" ----@return VisualElement self -function VisualElement:centerIn(target) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@protected -function VisualElement:mouse_release(button, x, y) end - ----@class ThemeAPI -local ThemeAPI = {} - ----Sets the current theme ----@param newTheme table The theme configuration to set -function ThemeAPI.setTheme(newTheme) end - ----Gets the current theme configuration ----@return table theme The current theme configuration -function ThemeAPI.getTheme() end - ----Loads a theme from a JSON file ----@param path string Path to the theme JSON file -function ThemeAPI.loadTheme(path) end +function ScrollFrame:mouse_click(button, x, y) end + +---Sets the value of the ScrollBarBackgroundColor2 property. +---@param self ScrollFrame self +---@param ScrollBarBackgroundColor2 secondary black Background color of the scrollbar +function ScrollFrame:setScrollBarBackgroundColor2(self, ScrollBarBackgroundColor2) end + +---Gets the value of the ScrollBarBackgroundSymbol property. +---@param self ScrollFrame self +---@return string "\127" The symbol used for the scrollbar background +function ScrollFrame:getScrollBarBackgroundSymbol(self) end + +---Gets the value of the ContentHeight property. +---@param self ScrollFrame self +---@return number 0 The total height of the content (calculated from children) +function ScrollFrame:getContentHeight(self) end + +---Sets the value of the ScrollBarBackgroundColor property. +---@param self ScrollFrame self +---@param ScrollBarBackgroundColor color Background color of the scrollbar +function ScrollFrame:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end + +---Gets the value of the ContentWidth property. +---@param self ScrollFrame self +---@return number 0 The total width of the content (calculated from children) +function ScrollFrame:getContentWidth(self) end + +---Gets the value of the ScrollBarSymbol property. +---@param self ScrollFrame self +---@return string "_" The symbol used for the scrollbar handle +function ScrollFrame:getScrollBarSymbol(self) end + +---Gets the value of the ScrollBarBackgroundColor property. +---@param self ScrollFrame self +---@return color gray Background color of the scrollbar +function ScrollFrame:getScrollBarBackgroundColor(self) end + +---Gets the value of the ScrollBarBackgroundColor2 property. +---@param self ScrollFrame self +---@return secondary color black Background color of the scrollbar +function ScrollFrame:getScrollBarBackgroundColor2(self) end + +---Gets the value of the ShowScrollBar property. +---@param self ScrollFrame self +---@return boolean true Whether to show scrollbars +function ScrollFrame:getShowScrollBar(self) end + +---Sets the value of the ShowScrollBar property. +---@param self ScrollFrame self +---@param ShowScrollBar boolean Whether to show scrollbars +function ScrollFrame:setShowScrollBar(self, ShowScrollBar) end ---@class Frame : Container ----@field draggingMap table The map of dragging positions ---@field draggable boolean Whether the frame is draggable ---@field scrollable boolean Whether the frame is scrollable +---@field draggingMap table The map of dragging positions local Frame = {} ----Sets the value of the Scrollable property. ----@param self Frame self ----@param Scrollable boolean Whether the frame is scrollable -function Frame:setScrollable(self, Scrollable) end - ----Gets the value of the DraggingMap property. ----@param self Frame self ----@return table {} The map of dragging positions -function Frame:getDraggingMap(self) end - ----Gets the value of the Draggable property. ----@param self Frame self ----@return boolean false Whether the frame is draggable -function Frame:getDraggable(self) end - ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param direction number The scroll direction ---@param x number The x position of the scroll @@ -781,10 +219,23 @@ function Frame:getDraggable(self) end ---@protected function Frame:mouse_scroll(direction, x, y) end +---Gets the value of the DraggingMap property. +---@param self Frame self +---@return table {} The map of dragging positions +function Frame:getDraggingMap(self) end + +---Gets the value of the Scrollable property. +---@param self Frame self +---@return boolean false Whether the frame is scrollable +function Frame:getScrollable(self) end + ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return number height The total height needed for all children +---@param button number The button that was clicked +---@param x number The x position of the drag position +---@param y number The y position of the drag position +---@return boolean handled Whether the event was handled ---@protected -function Frame:getChildrenHeight() end +function Frame:mouse_drag(button, x, y) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The button that was clicked @@ -795,17 +246,32 @@ function Frame:getChildrenHeight() end function Frame:mouse_click(button, x, y) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the drag position ----@param y number The y position of the drag position +---@param button number The button that was released +---@param x number The x position of the release +---@param y number The y position of the release ---@return boolean handled Whether the event was handled ---@protected -function Frame:mouse_drag(button, x, y) end +function Frame:mouse_up(button, x, y) end ----Gets the value of the Scrollable property. +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return number height The total height needed for all children +---@protected +function Frame:getChildrenHeight() end + +---Sets the value of the Draggable property. ---@param self Frame self ----@return boolean false Whether the frame is scrollable -function Frame:getScrollable(self) end +---@param Draggable boolean Whether the frame is draggable +function Frame:setDraggable(self, Draggable) end + +---Sets the value of the Scrollable property. +---@param self Frame self +---@param Scrollable boolean Whether the frame is scrollable +function Frame:setScrollable(self, Scrollable) end + +---Gets the value of the Draggable property. +---@param self Frame self +---@return boolean false Whether the frame is draggable +function Frame:getDraggable(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with @@ -814,2519 +280,33 @@ function Frame:getScrollable(self) end ---@protected function Frame:init(props, basalt) end ----Sets the value of the Draggable property. ----@param self Frame self ----@param Draggable boolean Whether the frame is draggable -function Frame:setDraggable(self, Draggable) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@return boolean handled Whether the event was handled ----@protected -function Frame:mouse_up(button, x, y) end - ---Sets the value of the DraggingMap property. ---@param self Frame self ---@param DraggingMap table The map of dragging positions function Frame:setDraggingMap(self, DraggingMap) end ----@class TabControl : Container ----@field tabScrollOffset number Current scroll offset for tabs in scrollable mode ----@field tabs table List of tab definitions ----@field activeTabTextColor color Foreground color for the active tab text ----@field tabHeight number Height of the tab header area ----@field scrollableTab boolean Enables scroll mode for tabs if they exceed width ----@field activeTabBackground color Background color for the active tab ----@field headerBackground color Background color for the tab header area ----@field activeTab number The currently active tab ID -local TabControl = {} - -function TabControl:mouse_up() end - ----Gets the value of the ActiveTab property. ----@param self TabControl self ----@return number nil The currently active tab ID -function TabControl:getActiveTab(self) end - -function TabControl:setCursor() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TabControl:sortChildrenEvents() end - ----Sets the value of the TabHeight property. ----@param self TabControl self ----@param TabHeight number Height of the tab header area -function TabControl:setTabHeight(self, TabHeight) end - -function TabControl:multiBlit() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click (global) ----@param y number The y position of the click (global) ----@return boolean Whether the event was handled ----@protected -function TabControl:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param child table The child element to add ----@return Container self For method chaining ----@protected -function TabControl:addChild(child) end - ----returns a proxy for adding elements to the tab ----@param title string The title of the tab ----@return table tabHandler The tab handler proxy for adding elements to the new tab -function TabControl:newTab(title) end - ----@param element table The element to assign to a tab ----@param tabId number The ID of the tab to assign the element to ----@return TabControl self For method chaining -function TabControl:setTab(element, tabId) end - -function TabControl:drawBg() end - -function TabControl:blit() end - ----Gets the value of the ActiveTabTextColor property. ----@param self TabControl self ----@return color black Foreground color for the active tab text -function TabControl:getActiveTabTextColor(self) end - ----Sets the value of the Tabs property. ----@param self TabControl self ----@param Tabs table List of tab definitions -function TabControl:setTabs(self, Tabs) end - -function TabControl:textFg() end - ----Gets the value of the ActiveTabBackground property. ----@param self TabControl self ----@return color white Background color for the active tab -function TabControl:getActiveTabBackground(self) end - ----Gets the value of the TabHeight property. ----@param self TabControl self ----@return number 1 Height of the tab header area -function TabControl:getTabHeight(self) end - -function TabControl:textBg() end - -function TabControl:mouse_move() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param child table The child element to check ----@return boolean Whether the child should be visible ----@protected -function TabControl:isChildVisible(child) end - ----Sets the value of the ActiveTabTextColor property. ----@param self TabControl self ----@param ActiveTabTextColor color Foreground color for the active tab text -function TabControl:setActiveTabTextColor(self, ActiveTabTextColor) end - ----Gets the value of the Tabs property. ----@param self TabControl self ----@return table {} List of tab definitions -function TabControl:getTabs(self) end - -function TabControl:drawText() end - ----@param tabId number The ID of the tab to activate -function TabControl:setActiveTab(tabId) end - ----Gets the value of the HeaderBackground property. ----@param self TabControl self ----@return color gray Background color for the tab header area -function TabControl:getHeaderBackground(self) end - -function TabControl:mouse_drag() end - ----Gets the value of the TabScrollOffset property. ----@param self TabControl self ----@return number 0 Current scroll offset for tabs in scrollable mode -function TabControl:getTabScrollOffset(self) end - ----Sets the value of the TabScrollOffset property. ----@param self TabControl self ----@param TabScrollOffset number Current scroll offset for tabs in scrollable mode -function TabControl:setTabScrollOffset(self, TabScrollOffset) end - -function TabControl:mouse_scroll() end - ----Sets the value of the HeaderBackground property. ----@param self TabControl self ----@param HeaderBackground color Background color for the tab header area -function TabControl:setHeaderBackground(self, HeaderBackground) end - ----Sets the value of the ScrollableTab property. ----@param self TabControl self ----@param ScrollableTab boolean Enables scroll mode for tabs if they exceed width -function TabControl:setScrollableTab(self, ScrollableTab) end - ----Gets the value of the ScrollableTab property. ----@param self TabControl self ----@return boolean false Enables scroll mode for tabs if they exceed width -function TabControl:getScrollableTab(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TabControl:render() end - -function TabControl:getRelativePosition() end - ----Scrolls the tab header left or right if scrollableTab is enabled ----@param direction number -1 to scroll left, 1 to scroll right ----@return TabControl self For method chaining -function TabControl:scrollTabs(direction) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return number yOffset The Y offset for content ----@protected -function TabControl:getContentYOffset() end - ----Sets the value of the ActiveTabBackground property. ----@param self TabControl self ----@param ActiveTabBackground color Background color for the active tab -function TabControl:setActiveTabBackground(self, ActiveTabBackground) end - -function TabControl:drawFg() end - ----@param elementType string The type of element to add ----@param tabId number Optional tab ID, defaults to active tab ----@return table element The created element -function TabControl:addElement(elementType, tabId) end - -function TabControl:mouse_release() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function TabControl:init(props, basalt) end - -function TabControl:_getHeaderMetrics() end - ----@class Tree : VisualElement ----@field selectedBackgroundColor color background color of selected node ----@field offset number Current vertical scroll position ----@field selectedNode table nil Currently selected node ----@field scrollBarColor color Color of the scrollbar handle ----@field horizontalOffset number Current horizontal scroll position ----@field selectedForegroundColor color foreground color of selected node ----@field expandedNodes table Table of nodes that are currently expanded ----@field scrollBarBackgroundColor color Background color of the scrollbar ----@field nodes table The tree structure containing node objects with {text, children} properties ----@field scrollBarBackground string Symbol used for the scrollbar background ----@field showScrollBar boolean Whether to show the scrollbar when nodes exceed height ----@field scrollBarSymbol string " Symbol used for the scrollbar handle -local Tree = {} - ----Gets the value of the ScrollBarBackgroundColor property. ----@param self Tree self ----@return color gray Background color of the scrollbar -function Tree:getScrollBarBackgroundColor(self) end - ----Sets the value of the ScrollBarBackgroundColor property. ----@param self Tree self ----@param ScrollBarBackgroundColor color Background color of the scrollbar -function Tree:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end - ----Sets the value of the HorizontalOffset property. ----@param self Tree self ----@param HorizontalOffset number Current horizontal scroll position -function Tree:setHorizontalOffset(self, HorizontalOffset) end - ----Sets the value of the ScrollBarSymbol property. ----@param self Tree self ----@param ScrollBarSymbol string " Symbol used for the scrollbar handle -function Tree:setScrollBarSymbol(self, ScrollBarSymbol) end - ----Sets the value of the ExpandedNodes property. ----@param self Tree self ----@param ExpandedNodes table Table of nodes that are currently expanded -function Tree:setExpandedNodes(self, ExpandedNodes) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction (1 for up, -1 for down) ----@param x number The x position of the scroll ----@param y number The y position of the scroll ----@return boolean handled Whether the event was handled ----@protected -function Tree:mouse_scroll(direction, x, y) end - ----Gets the value of the HorizontalOffset property. ----@param self Tree self ----@return number 0 Current horizontal scroll position -function Tree:getHorizontalOffset(self) end - ----Initializes the Tree instance ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Tree self The initialized instance ----@protected -function Tree:init(props, basalt) end - ----Gets the value of the ShowScrollBar property. ----@param self Tree self ----@return boolean true Whether to show the scrollbar when nodes exceed height -function Tree:getShowScrollBar(self) end - ----Gets the value of the ScrollBarColor property. ----@param self Tree self ----@return color lightGray Color of the scrollbar handle -function Tree:getScrollBarColor(self) end - ----Expands a node ----@param node table The node to expand ----@return Tree self The Tree instance -function Tree:expandNode(node) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button being dragged ----@param x number The x-coordinate of the drag ----@param y number The y-coordinate of the drag ----@return boolean Whether the event was handled ----@protected -function Tree:mouse_drag(button, x, y) end - ----Gets the value of the SelectedNode property. ----@param self Tree self ----@return table ? nil Currently selected node -function Tree:getSelectedNode(self) end - ----Registers a callback for when a node is selected ----@param callback function The callback function ----@return Tree self The Tree instance -function Tree:onSelect(callback) end - ----Toggles a node's expanded state ----@param node table The node to toggle ----@return Tree self The Tree instance -function Tree:toggleNode(node) end - ----Gets the value of the SelectedBackgroundColor property. ----@param self Tree self ----@return color lightBlue background color of selected node -function Tree:getSelectedBackgroundColor(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was released ----@param x number The x-coordinate of the release ----@param y number The y-coordinate of the release ----@return boolean Whether the event was handled ----@protected -function Tree:mouse_up(button, x, y) end - ----Sets the value of the SelectedForegroundColor property. ----@param self Tree self ----@param SelectedForegroundColor color foreground color of selected node -function Tree:setSelectedForegroundColor(self, SelectedForegroundColor) end - ----Collapses a node ----@param node table The node to collapse ----@return Tree self The Tree instance -function Tree:collapseNode(node) end - ----Sets the value of the ShowScrollBar property. ----@param self Tree self ----@param ShowScrollBar boolean Whether to show the scrollbar when nodes exceed height -function Tree:setShowScrollBar(self, ShowScrollBar) end - ----Gets the value of the Nodes property. ----@param self Tree self ----@return table {} The tree structure containing node objects with {text, children} properties -function Tree:getNodes(self) end - ----Gets the value of the ExpandedNodes property. ----@param self Tree self ----@return table {} Table of nodes that are currently expanded -function Tree:getExpandedNodes(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Tree:render() end - ----Gets the value of the ScrollBarSymbol property. ----@param self Tree self ----@return string " " Symbol used for the scrollbar handle -function Tree:getScrollBarSymbol(self) end - ----Sets the value of the SelectedBackgroundColor property. ----@param self Tree self ----@param SelectedBackgroundColor color background color of selected node -function Tree:setSelectedBackgroundColor(self, SelectedBackgroundColor) end - ----Sets the value of the SelectedNode property. ----@param self Tree self ----@param SelectedNode table nil Currently selected node -function Tree:setSelectedNode(self, SelectedNode) end - ----Gets the value of the SelectedForegroundColor property. ----@param self Tree self ----@return color white foreground color of selected node -function Tree:getSelectedForegroundColor(self) end - ----Sets the value of the Nodes property. ----@param self Tree self ----@param Nodes table The tree structure containing node objects with {text, children} properties -function Tree:setNodes(self, Nodes) end - ----Sets the value of the Offset property. ----@param self Tree self ----@param Offset number Current vertical scroll position -function Tree:setOffset(self, Offset) end - ----Sets the value of the ScrollBarBackground property. ----@param self Tree self ----@param ScrollBarBackground string Symbol used for the scrollbar background -function Tree:setScrollBarBackground(self, ScrollBarBackground) end - ----Gets the size of the tree ----@return number width The width of the tree ----@return number height The height of the tree -function Tree:getNodeSize() end - ----Gets the value of the ScrollBarBackground property. ----@param self Tree self ----@return string "\127" Symbol used for the scrollbar background -function Tree:getScrollBarBackground(self) end - ----Sets the value of the ScrollBarColor property. ----@param self Tree self ----@param ScrollBarColor color Color of the scrollbar handle -function Tree:setScrollBarColor(self, ScrollBarColor) end - ----Gets the value of the Offset property. ----@param self Tree self ----@return number 0 Current vertical scroll position -function Tree:getOffset(self) end - ----Handles mouse click events ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Tree:mouse_click(button, x, y) end - ----@class ElementManager -local ElementManager = {} - ----Gets cache statistics ----@return table stats Cache statistics with size and element names -function ElementManager.getCacheStats() end - ----Gets an Plugin API by name ----@param name string The name of the API to get ----@return table API The API -function ElementManager.getAPI(name) end - ----Gets an element by name. If the element is not loaded, it will try to load it first. ----@param name string The name of the element to get ----@return table Element The element class -function ElementManager.getElement(name) end - ----Checks if an element is loaded ----@param name string The element name ----@return boolean loaded Whether the element is loaded -function ElementManager.isElementLoaded(name) end - ----Gets a list of all elements ----@return table ElementList A list of all elements -function ElementManager.getElementList() end - ----Configures the ElementManager ----@param config table Configuration options -function ElementManager.configure(config) end - ----Registers a disk mount point for loading elements ----@param mountPath string The path to the disk mount -function ElementManager.registerDiskMount(mountPath) end - ----Preloads elements into the global cache ----@param elementNames table List of element names to preload -function ElementManager.preloadElements(elementNames) end - ----Loads an element by name. This will load the element and apply any plugins to it. ----@param name string The name of the element to load -function ElementManager.loadElement(name) end - ----Registers a remote source for an element ----@param elementName string The name of the element ----@param url string The URL to load the element from -function ElementManager.registerRemoteSource(elementName, url) end - ----Checks if an element exists (is registered) ----@param name string The element name ----@return boolean exists Whether the element exists -function ElementManager.hasElement(name) end - ----Tries to load an element from any available source ----@param name string The element name ----@return boolean success Whether the element was loaded -function ElementManager.tryAutoLoad(name) end - ----Clears the global cache (_G) -function ElementManager.clearGlobalCache() end - ----@class Breadcrumb : VisualElement ----@field autoSize false Whether to resize the element width automatically based on text ----@field path table Array of strings representing the breadcrumb segments ----@field clickable true Whether the segments are clickable -local Breadcrumb = {} - ----Sets the value of the Path property. ----@param self Breadcrumb self ----@param Path table Array of strings representing the breadcrumb segments -function Breadcrumb:setPath(self, Path) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Breadcrumb:render() end - ----@param button number ----@param x number ----@param y number ----@return boolean handled -function Breadcrumb:mouse_click(button, x, y) end - ----Gets the value of the Path property. ----@param self Breadcrumb self ----@return table {} Array of strings representing the breadcrumb segments -function Breadcrumb:getPath(self) end - ----Gets the value of the AutoSize property. ----@param self Breadcrumb self ----@return false boolean Whether to resize the element width automatically based on text -function Breadcrumb:getAutoSize(self) end - ----Sets the value of the Clickable property. ----@param self Breadcrumb self ----@param Clickable true Whether the segments are clickable -function Breadcrumb:setClickable(self, Clickable) end - ----Registers a callback for the select event ----@param callback function The callback function to register ----@return Breadcrumb self The Breadcrumb instance -function Breadcrumb:onSelect(callback) end - ----Sets the value of the AutoSize property. ----@param self Breadcrumb self ----@param AutoSize false Whether to resize the element width automatically based on text -function Breadcrumb:setAutoSize(self, AutoSize) end - ----@param props table ----@param basalt table -function Breadcrumb:init(props, basalt) end - ----Gets the value of the Clickable property. ----@param self Breadcrumb self ----@return true boolean Whether the segments are clickable -function Breadcrumb:getClickable(self) end - ----@return table self -function Breadcrumb.new() end - ----@class Input : VisualElement ----@field placeholder string Text to display when input is empty ----@field maxLength number nil Maximum length of input text (optional) ----@field viewOffset number The horizontal scroll offset for viewing long text ----@field cursorColor number Color of the cursor ----@field pattern string nil Regular expression pattern for input validation ----@field replaceChar string Character to replace the input with (for password fields) ----@field cursorPos number The current cursor position in the text ----@field text string The current text content of the input ----@field placeholderColor color Color of the placeholder text -local Input = {} - ----Gets the value of the CursorPos property. ----@param self Input self ----@return number 1 The current cursor position in the text -function Input:getCursorPos(self) end - ----Gets the value of the CursorColor property. ----@param self Input self ----@return number nil Color of the cursor -function Input:getCursorColor(self) end - ----Sets the value of the ViewOffset property. ----@param self Input self ----@param ViewOffset number The horizontal scroll offset for viewing long text -function Input:setViewOffset(self, ViewOffset) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:paste() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:render() end - ----Sets the value of the ReplaceChar property. ----@param self Input self ----@param ReplaceChar string Character to replace the input with (for password fields) -function Input:setReplaceChar(self, ReplaceChar) end - ----Sets the value of the CursorPos property. ----@param self Input self ----@param CursorPos number The current cursor position in the text -function Input:setCursorPos(self, CursorPos) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:blur() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:focus() end - ----Updates the input's viewport ----@return Input self The updated instance -function Input:updateViewport() end - ----Gets the value of the ReplaceChar property. ----@param self Input self ----@return string nil Character to replace the input with (for password fields) -function Input:getReplaceChar(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Input:mouse_click(button, x, y) end - ----Gets the value of the MaxLength property. ----@param self Input self ----@return number ? nil Maximum length of input text (optional) -function Input:getMaxLength(self) end - ----Gets the value of the Placeholder property. ----@param self Input self ----@return string ... Text to display when input is empty -function Input:getPlaceholder(self) end - ----Sets the value of the Pattern property. ----@param self Input self ----@param Pattern string nil Regular expression pattern for input validation -function Input:setPattern(self, Pattern) end - ----Sets the value of the MaxLength property. ----@param self Input self ----@param MaxLength number nil Maximum length of input text (optional) -function Input:setMaxLength(self, MaxLength) end - ----Gets the value of the ViewOffset property. ----@param self Input self ----@return number 0 The horizontal scroll offset for viewing long text -function Input:getViewOffset(self) end - ----Sets the value of the CursorColor property. ----@param self Input self ----@param CursorColor number Color of the cursor -function Input:setCursorColor(self, CursorColor) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@return boolean handled Whether the event was handled ----@protected -function Input:key(key) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Input self The initialized instance ----@protected -function Input:init(props, basalt) end - ----Gets the value of the Pattern property. ----@param self Input self ----@return string ? nil Regular expression pattern for input validation -function Input:getPattern(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was typed ----@return boolean handled Whether the event was handled ----@protected -function Input:char(char) end - ----Sets the value of the PlaceholderColor property. ----@param self Input self ----@param PlaceholderColor color Color of the placeholder text -function Input:setPlaceholderColor(self, PlaceholderColor) end - ----Gets the value of the PlaceholderColor property. ----@param self Input self ----@return color gray Color of the placeholder text -function Input:getPlaceholderColor(self) end - ----Gets the value of the Text property. ----@param self Input self ----@return string - The current text content of the input -function Input:getText(self) end - ----Sets the value of the Placeholder property. ----@param self Input self ----@param Placeholder string Text to display when input is empty -function Input:setPlaceholder(self, Placeholder) end - ----Sets the value of the Text property. ----@param self Input self ----@param Text string The current text content of the input -function Input:setText(self, Text) end - ----Sets the cursor position and color ----@param x number The x position of the cursor ----@param y number The y position of the cursor ----@param blink boolean Whether the cursor should blink ----@param color number The color of the cursor -function Input:setCursor(x, y, blink, color) end - ----@class Display : VisualElement -local Display = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Display:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Display:init(props, basalt) end - ----Retrieves the underlying ComputerCraft window object ----@return table window A CC window object with all standard terminal methods -function Display:getWindow() end - ----Writes text directly to the display with optional colors ----@param x number X position (1-based) ----@param y number Y position (1-based) ----@param text string Text to write ----@return Display self For method chaining -function Display:write(x, y, text) end - ----@class DropDown : List ----@field selectedText string Text shown when no selection made ----@field dropSymbol string Indicator for dropdown state ----@field dropdownHeight number Maximum visible items when expanded -local DropDown = {} - ----Gets the value of the DropdownHeight property. ----@param self DropDown self ----@return number 5 Maximum visible items when expanded -function DropDown:getDropdownHeight(self) end - ----Gets the value of the SelectedText property. ----@param self DropDown self ----@return string "" Text shown when no selection made -function DropDown:getSelectedText(self) end - ----Called when the DropDown gains focus ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function DropDown:focus() end - ----Sets the value of the SelectedText property. ----@param self DropDown self ----@param SelectedText string Text shown when no selection made -function DropDown:setSelectedText(self, SelectedText) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was released ----@param x number The x-coordinate of the release ----@param y number The y-coordinate of the release ----@return boolean Whether the event was handled ----@protected -function DropDown:mouse_up(button, x, y) end - ----Called when the DropDown loses focus ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function DropDown:blur() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function DropDown:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function DropDown:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button being dragged ----@param x number The x-coordinate of the drag ----@param y number The y-coordinate of the drag ----@return boolean Whether the event was handled ----@protected -function DropDown:mouse_drag(button, x, y) end - ----Gets the value of the DropSymbol property. ----@param self DropDown self ----@return string "\31" Indicator for dropdown state -function DropDown:getDropSymbol(self) end - ----Sets the value of the DropSymbol property. ----@param self DropDown self ----@param DropSymbol string Indicator for dropdown state -function DropDown:setDropSymbol(self, DropSymbol) end - ----Sets the value of the DropdownHeight property. ----@param self DropDown self ----@param DropdownHeight number Maximum visible items when expanded -function DropDown:setDropdownHeight(self, DropdownHeight) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return DropDown self The initialized instance ----@protected -function DropDown:init(props, basalt) end - ----@class Render -local Render = {} - ----Checks if two rectangles overlap ----@param r1 table The first rectangle ----@param r2 table The second rectangle ----@return boolean -function Render:rectOverlaps(r1, r2) end - ----Gets the size of the render ----@return number , number -function Render:getSize() end - ----Clears an area of the screen ----@param x number The x position of the area ----@param y number The y position of the area ----@param width number The width of the area ----@param height number The height of the area ----@param bg colors The background color to clear the area with ----@return Render -function Render:clearArea(x, y, width, height, bg) end - ----Merges two rectangles ----@param target table The target rectangle ----@param source table The source rectangle ----@return Render -function Render:mergeRects(target, source) end - ----Blits text to the screen with multiple lines ----@param x number The x position to blit to ----@param y number The y position to blit to ----@param width number The width of the text ----@param height number The height of the text ----@param text string The text to blit ----@param fg colors The foreground color of the text ----@param bg colors The background color of the text ----@return Render -function Render:multiBlit(x, y, width, height, text, fg, bg) end - ----Blits text to the screen ----@param x number The x position to blit to ----@param y number The y position to blit to ----@param text string The text to blit ----@param fg string The foreground color of the text ----@param bg string The background color of the text ----@return Render -function Render:blit(x, y, text, fg, bg) end - ----Sets the size of the render ----@param width number The width of the render ----@param height number The height of the render ----@return Render -function Render:setSize(width, height) end - ----Adds a dirty rectangle to the buffer ----@param x number The x position of the rectangle ----@param y number The y position of the rectangle ----@param width number The width of the rectangle ----@param height number The height of the rectangle ----@return Render -function Render:addDirtyRect(x, y, width, height) end - ----Creates a new Render object ----@param terminal table The terminal object to render to ----@return Render -function Render.new(terminal) end - ----Blits a foreground color to the screen ----@param x number The x position ----@param y number The y position ----@param fg string The foreground color to blit ----@return Render -function Render:fg(x, y, fg) end - ----Blits text to the screen with a background color ----@param x number The x position to blit to ----@param y number The y position to blit to ----@param text string The text to blit ----@param bg colors The background color of the text ----@return Render -function Render:textBg(x, y, text, bg) end - ----Blits text to the screen ----@param x number The x position to blit to ----@param y number The y position to blit to ----@param text string The text to blit ----@return Render -function Render:text(x, y, text) end - ----Blits a background color to the screen ----@param x number The x position ----@param y number The y position ----@param bg string The background color to blit ----@return Render -function Render:bg(x, y, bg) end - ----Blits text to the screen with a foreground color ----@param x number The x position to blit to ----@param y number The y position to blit to ----@param text string The text to blit ----@param fg colors The foreground color of the text ----@return Render -function Render:textFg(x, y, text, fg) end - ----Renders the buffer to the screen ----@return Render -function Render:render() end - ----Sets the cursor position ----@param x number The x position of the cursor ----@param y number The y position of the cursor ----@param blink boolean Whether the cursor should blink ----@return Render -function Render:setCursor(x, y, blink) end - ----Clears the screen ----@param bg colors The background color to clear the screen with ----@return Render -function Render:clear(bg) end - ----@class BigFont : VisualElement ----@field fontSize number Scale factor for text size (1-3, where 1 is 3x3 pixels per character) ----@field text string The text string to display in enlarged format -local BigFont = {} - ----Gets the value of the Text property. ----@param self BigFont self ----@return string BigFont The text string to display in enlarged format -function BigFont:getText(self) end - ----Sets the value of the FontSize property. ----@param self BigFont self ----@param FontSize number Scale factor for text size (1-3, where 1 is 3x3 pixels per character) -function BigFont:setFontSize(self, FontSize) end - ----Sets the value of the Text property. ----@param self BigFont self ----@param Text string The text string to display in enlarged format -function BigFont:setText(self, Text) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BigFont:render() end - ----Gets the value of the FontSize property. ----@param self BigFont self ----@return number 1 Scale factor for text size (1-3, where 1 is 3x3 pixels per character) -function BigFont:getFontSize(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function BigFont:init(props, basalt) end - ----@class TextBox : VisualElement ----@field autoCompleteEnabled boolean Whether autocomplete suggestions are enabled ----@field autoPairEnabled boolean Whether automatic bracket/quote pairing is enabled ----@field cursorColor number Color of the cursor ----@field autoCompleteAcceptOnEnter boolean Whether pressing Enter accepts the current suggestion ----@field lines table Array of text lines ----@field autoCompleteProvider function Optional suggestion provider returning a list for the current prefix ----@field autoCompleteForeground color Foreground color of the suggestion popup ----@field autoCompleteSelectedBackground color Background color for the selected suggestion ----@field autoCompleteCaseInsensitive boolean Whether suggestions should match case-insensitively ----@field autoCompleteCloseOnEscape boolean Whether pressing Escape closes the popup ----@field autoCompleteAcceptOnClick boolean Whether clicking a suggestion accepts it immediately ----@field autoCompleteMaxItems number Maximum number of visible suggestions ----@field syntaxPatterns table Syntax highlighting patterns ----@field autoCompleteItems table List of suggestions used when no provider is supplied ----@field autoCompleteZOffset number Z-index offset applied to the popup frame ----@field cursorY number Cursor Y position (line number) ----@field autoCompleteOffsetY number Vertical offset applied to the popup frame relative to the TextBox bottom edge ----@field autoCompleteShowBorder boolean Whether to render a character border around the popup ----@field scrollX number Horizontal scroll offset ----@field editable boolean Whether text can be edited ----@field autoCompleteMaxWidth number Maximum width of the autocomplete popup (0 uses the textbox width) ----@field cursorX number Cursor X position ----@field autoCompleteTokenPattern string Pattern used to extract the current token for suggestions ----@field autoCompleteSelectedForeground color Foreground color for the selected suggestion ----@field autoCompleteBorderColor color Color of the popup border when enabled ----@field autoCompleteMinChars number Minimum characters required before showing suggestions ----@field autoPairOverType boolean When pressing a closing char that matches the next char, move over it instead of inserting ----@field autoPairSkipClosing boolean Skip inserting a closing char if the same one is already at cursor ----@field autoCompleteBackground color Background color of the suggestion popup ----@field scrollY number Vertical scroll offset ----@field autoPairNewlineIndent boolean On Enter between matching braces, create blank line and keep closing aligned ----@field autoCompleteOffsetX number Horizontal offset applied to the popup frame relative to the TextBox ----@field autoPairCharacters table ["("]=")", ["["]="]", ["{"]="}", ['"']='"', ['\'']='\'', ['`']='`'} Mapping of opening to closing characters for auto pairing -local TextBox = {} - ----Gets the text of the TextBox ----@return string text The text of the TextBox -function TextBox:getText() end - ----Gets the value of the SyntaxPatterns property. ----@param self TextBox self ----@return table {} Syntax highlighting patterns -function TextBox:getSyntaxPatterns(self) end - ----Gets the value of the AutoPairSkipClosing property. ----@param self TextBox self ----@return boolean true Skip inserting a closing char if the same one is already at cursor -function TextBox:getAutoPairSkipClosing(self) end - ----Clears all syntax highlighting patterns ----@return TextBox self -function TextBox:clearSyntaxPatterns() end - ----Sets the value of the AutoCompleteMinChars property. ----@param self TextBox self ----@param AutoCompleteMinChars number Minimum characters required before showing suggestions -function TextBox:setAutoCompleteMinChars(self, AutoCompleteMinChars) end - ----Sets the value of the AutoCompleteMaxWidth property. ----@param self TextBox self ----@param AutoCompleteMaxWidth number Maximum width of the autocomplete popup (0 uses the textbox width) -function TextBox:setAutoCompleteMaxWidth(self, AutoCompleteMaxWidth) end - ----Sets the value of the AutoCompleteBorderColor property. ----@param self TextBox self ----@param AutoCompleteBorderColor color Color of the popup border when enabled -function TextBox:setAutoCompleteBorderColor(self, AutoCompleteBorderColor) end - ----Removes a syntax pattern by index (1-based) ----@param index number The index of the pattern to remove ----@return TextBox self -function TextBox:removeSyntaxPattern(index) end - ----Sets the value of the Lines property. ----@param self TextBox self ----@param Lines table Array of text lines -function TextBox:setLines(self, Lines) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TextBox:paste() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function TextBox:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return TextBox self The initialized instance ----@protected -function TextBox:init(props, basalt) end - ----Gets the value of the Lines property. ----@param self TextBox self ----@return table {} Array of text lines -function TextBox:getLines(self) end - ----Sets the value of the CursorX property. ----@param self TextBox self ----@param CursorX number Cursor X position -function TextBox:setCursorX(self, CursorX) end - ----Gets the value of the CursorY property. ----@param self TextBox self ----@return number 1 Cursor Y position (line number) -function TextBox:getCursorY(self) end - ----Sets the value of the AutoCompleteAcceptOnEnter property. ----@param self TextBox self ----@param AutoCompleteAcceptOnEnter boolean Whether pressing Enter accepts the current suggestion -function TextBox:setAutoCompleteAcceptOnEnter(self, AutoCompleteAcceptOnEnter) end - ----Sets the value of the AutoCompleteAcceptOnClick property. ----@param self TextBox self ----@param AutoCompleteAcceptOnClick boolean Whether clicking a suggestion accepts it immediately -function TextBox:setAutoCompleteAcceptOnClick(self, AutoCompleteAcceptOnClick) end - ----Sets the value of the AutoCompleteItems property. ----@param self TextBox self ----@param AutoCompleteItems table List of suggestions used when no provider is supplied -function TextBox:setAutoCompleteItems(self, AutoCompleteItems) end - ----Gets the value of the AutoCompleteAcceptOnClick property. ----@param self TextBox self ----@return boolean true Whether clicking a suggestion accepts it immediately -function TextBox:getAutoCompleteAcceptOnClick(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@return boolean handled Whether the event was handled ----@protected -function TextBox:key(key) end - ----Gets the value of the CursorColor property. ----@param self TextBox self ----@return number nil Color of the cursor -function TextBox:getCursorColor(self) end - ----Updates the viewport to keep the cursor in view ----@return TextBox self The TextBox instance -function TextBox:updateViewport() end - ----Sets the value of the CursorY property. ----@param self TextBox self ----@param CursorY number Cursor Y position (line number) -function TextBox:setCursorY(self, CursorY) end - ----Adds a new syntax highlighting pattern ----@param pattern string The regex pattern to match ----@param color number The color to apply ----@return TextBox self The TextBox instance -function TextBox:addSyntaxPattern(pattern, color) end - ----Gets the value of the AutoCompleteCloseOnEscape property. ----@param self TextBox self ----@return boolean true Whether pressing Escape closes the popup -function TextBox:getAutoCompleteCloseOnEscape(self) end - ----Gets the value of the AutoCompleteSelectedBackground property. ----@param self TextBox self ----@return color gray Background color for the selected suggestion -function TextBox:getAutoCompleteSelectedBackground(self) end - ----Sets the value of the AutoCompleteSelectedBackground property. ----@param self TextBox self ----@param AutoCompleteSelectedBackground color Background color for the selected suggestion -function TextBox:setAutoCompleteSelectedBackground(self, AutoCompleteSelectedBackground) end - ----Sets the value of the AutoCompleteOffsetY property. ----@param self TextBox self ----@param AutoCompleteOffsetY number Vertical offset applied to the popup frame relative to the TextBox bottom edge -function TextBox:setAutoCompleteOffsetY(self, AutoCompleteOffsetY) end - ----Sets the value of the ScrollX property. ----@param self TextBox self ----@param ScrollX number Horizontal scroll offset -function TextBox:setScrollX(self, ScrollX) end - ----Sets the value of the AutoCompleteMaxItems property. ----@param self TextBox self ----@param AutoCompleteMaxItems number Maximum number of visible suggestions -function TextBox:setAutoCompleteMaxItems(self, AutoCompleteMaxItems) end - ----Gets the value of the CursorX property. ----@param self TextBox self ----@return number 1 Cursor X position -function TextBox:getCursorX(self) end - ----Gets the value of the AutoCompleteOffsetX property. ----@param self TextBox self ----@return number 0 Horizontal offset applied to the popup frame relative to the TextBox -function TextBox:getAutoCompleteOffsetX(self) end - ----Sets the value of the CursorColor property. ----@param self TextBox self ----@param CursorColor number Color of the cursor -function TextBox:setCursorColor(self, CursorColor) end - ----Sets the value of the SyntaxPatterns property. ----@param self TextBox self ----@param SyntaxPatterns table Syntax highlighting patterns -function TextBox:setSyntaxPatterns(self, SyntaxPatterns) end - ----Gets the value of the AutoCompleteCaseInsensitive property. ----@param self TextBox self ----@return boolean true Whether suggestions should match case-insensitively -function TextBox:getAutoCompleteCaseInsensitive(self) end - ----Gets the value of the ScrollX property. ----@param self TextBox self ----@return number 0 Horizontal scroll offset -function TextBox:getScrollX(self) end - ----Gets the value of the AutoPairNewlineIndent property. ----@param self TextBox self ----@return boolean true On Enter between matching braces, create blank line and keep closing aligned -function TextBox:getAutoPairNewlineIndent(self) end - ----Gets the value of the AutoCompleteProvider property. ----@param self TextBox self ----@return function nil Optional suggestion provider returning a list for the current prefix -function TextBox:getAutoCompleteProvider(self) end - ----Sets the value of the AutoCompleteCaseInsensitive property. ----@param self TextBox self ----@param AutoCompleteCaseInsensitive boolean Whether suggestions should match case-insensitively -function TextBox:setAutoCompleteCaseInsensitive(self, AutoCompleteCaseInsensitive) end - ----Gets the value of the AutoCompleteZOffset property. ----@param self TextBox self ----@return number 1 Z-index offset applied to the popup frame -function TextBox:getAutoCompleteZOffset(self) end - ----Sets the value of the AutoCompleteForeground property. ----@param self TextBox self ----@param AutoCompleteForeground color Foreground color of the suggestion popup -function TextBox:setAutoCompleteForeground(self, AutoCompleteForeground) end - -function TextBox:destroy() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction ----@param x number The x position of the scroll ----@param y number The y position of the scroll ----@return boolean handled Whether the event was handled ----@protected -function TextBox:mouse_scroll(direction, x, y) end - ----Gets the value of the AutoPairCharacters property. ----@param self TextBox self ----@return table { ["("]=")", ["["]="]", ["{"]="}", ['"']='"', ['\'']='\'', ['`']='`'} Mapping of opening to closing characters for auto pairing -function TextBox:getAutoPairCharacters(self) end - ----Sets the text of the TextBox ----@param text string The text to set ----@return TextBox self The TextBox instance -function TextBox:setText(text) end - ----Gets the value of the AutoCompleteBackground property. ----@param self TextBox self ----@return color lightGray Background color of the suggestion popup -function TextBox:getAutoCompleteBackground(self) end - ----Sets the value of the AutoCompleteShowBorder property. ----@param self TextBox self ----@param AutoCompleteShowBorder boolean Whether to render a character border around the popup -function TextBox:setAutoCompleteShowBorder(self, AutoCompleteShowBorder) end - ----Sets the value of the Editable property. ----@param self TextBox self ----@param Editable boolean Whether text can be edited -function TextBox:setEditable(self, Editable) end - ----Gets the value of the AutoCompleteMaxWidth property. ----@param self TextBox self ----@return number 0 Maximum width of the autocomplete popup (0 uses the textbox width) -function TextBox:getAutoCompleteMaxWidth(self) end - ----Gets the value of the AutoCompleteOffsetY property. ----@param self TextBox self ----@return number 1 Vertical offset applied to the popup frame relative to the TextBox bottom edge -function TextBox:getAutoCompleteOffsetY(self) end - ----Gets the value of the AutoCompleteBorderColor property. ----@param self TextBox self ----@return color black Color of the popup border when enabled -function TextBox:getAutoCompleteBorderColor(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was typed ----@return boolean handled Whether the event was handled ----@protected -function TextBox:char(char) end - ----Sets the value of the AutoCompleteOffsetX property. ----@param self TextBox self ----@param AutoCompleteOffsetX number Horizontal offset applied to the popup frame relative to the TextBox -function TextBox:setAutoCompleteOffsetX(self, AutoCompleteOffsetX) end - ----Gets the value of the AutoCompleteForeground property. ----@param self TextBox self ----@return color black Foreground color of the suggestion popup -function TextBox:getAutoCompleteForeground(self) end - ----Gets the value of the AutoCompleteItems property. ----@param self TextBox self ----@return table {} List of suggestions used when no provider is supplied -function TextBox:getAutoCompleteItems(self) end - ----Sets the value of the AutoPairSkipClosing property. ----@param self TextBox self ----@param AutoPairSkipClosing boolean Skip inserting a closing char if the same one is already at cursor -function TextBox:setAutoPairSkipClosing(self, AutoPairSkipClosing) end - ----Sets the value of the AutoPairNewlineIndent property. ----@param self TextBox self ----@param AutoPairNewlineIndent boolean On Enter between matching braces, create blank line and keep closing aligned -function TextBox:setAutoPairNewlineIndent(self, AutoPairNewlineIndent) end - ----Gets the value of the AutoCompleteSelectedForeground property. ----@param self TextBox self ----@return color white Foreground color for the selected suggestion -function TextBox:getAutoCompleteSelectedForeground(self) end - ----Sets the value of the AutoPairCharacters property. ----@param self TextBox self ----@param AutoPairCharacters table ["("]=")", ["["]="]", ["{"]="}", ['"']='"', ['\'']='\'', ['`']='`'} Mapping of opening to closing characters for auto pairing -function TextBox:setAutoPairCharacters(self, AutoPairCharacters) end - ----Sets the value of the AutoPairOverType property. ----@param self TextBox self ----@param AutoPairOverType boolean When pressing a closing char that matches the next char, move over it instead of inserting -function TextBox:setAutoPairOverType(self, AutoPairOverType) end - ----Sets the value of the AutoPairEnabled property. ----@param self TextBox self ----@param AutoPairEnabled boolean Whether automatic bracket/quote pairing is enabled -function TextBox:setAutoPairEnabled(self, AutoPairEnabled) end - ----Gets the value of the AutoPairEnabled property. ----@param self TextBox self ----@return boolean true Whether automatic bracket/quote pairing is enabled -function TextBox:getAutoPairEnabled(self) end - ----Sets the value of the AutoCompleteEnabled property. ----@param self TextBox self ----@param AutoCompleteEnabled boolean Whether autocomplete suggestions are enabled -function TextBox:setAutoCompleteEnabled(self, AutoCompleteEnabled) end - ----Gets the value of the Editable property. ----@param self TextBox self ----@return boolean true Whether text can be edited -function TextBox:getEditable(self) end - ----Gets the value of the AutoPairOverType property. ----@param self TextBox self ----@return boolean true When pressing a closing char that matches the next char, move over it instead of inserting -function TextBox:getAutoPairOverType(self) end - ----Gets the value of the AutoCompleteMinChars property. ----@param self TextBox self ----@return number 1 Minimum characters required before showing suggestions -function TextBox:getAutoCompleteMinChars(self) end - ----Sets the value of the AutoCompleteProvider property. ----@param self TextBox self ----@param AutoCompleteProvider function Optional suggestion provider returning a list for the current prefix -function TextBox:setAutoCompleteProvider(self, AutoCompleteProvider) end - ----Sets the value of the ScrollY property. ----@param self TextBox self ----@param ScrollY number Vertical scroll offset -function TextBox:setScrollY(self, ScrollY) end - ----Gets the value of the AutoCompleteTokenPattern property. ----@param self TextBox self ----@return string "[%w_]+" Pattern used to extract the current token for suggestions -function TextBox:getAutoCompleteTokenPattern(self) end - ----Gets the value of the AutoCompleteAcceptOnEnter property. ----@param self TextBox self ----@return boolean true Whether pressing Enter accepts the current suggestion -function TextBox:getAutoCompleteAcceptOnEnter(self) end - ----Gets the value of the AutoCompleteMaxItems property. ----@param self TextBox self ----@return number 6 Maximum number of visible suggestions -function TextBox:getAutoCompleteMaxItems(self) end - ----Sets the value of the AutoCompleteCloseOnEscape property. ----@param self TextBox self ----@param AutoCompleteCloseOnEscape boolean Whether pressing Escape closes the popup -function TextBox:setAutoCompleteCloseOnEscape(self, AutoCompleteCloseOnEscape) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TextBox:render() end - ----Gets the value of the ScrollY property. ----@param self TextBox self ----@return number 0 Vertical scroll offset -function TextBox:getScrollY(self) end - ----Sets the value of the AutoCompleteZOffset property. ----@param self TextBox self ----@param AutoCompleteZOffset number Z-index offset applied to the popup frame -function TextBox:setAutoCompleteZOffset(self, AutoCompleteZOffset) end - ----Gets the value of the AutoCompleteShowBorder property. ----@param self TextBox self ----@return boolean true Whether to render a character border around the popup -function TextBox:getAutoCompleteShowBorder(self) end - ----Gets the value of the AutoCompleteEnabled property. ----@param self TextBox self ----@return boolean false Whether autocomplete suggestions are enabled -function TextBox:getAutoCompleteEnabled(self) end - ----Sets the value of the AutoCompleteTokenPattern property. ----@param self TextBox self ----@param AutoCompleteTokenPattern string Pattern used to extract the current token for suggestions -function TextBox:setAutoCompleteTokenPattern(self, AutoCompleteTokenPattern) end - ----Sets the value of the AutoCompleteSelectedForeground property. ----@param self TextBox self ----@param AutoCompleteSelectedForeground color Foreground color for the selected suggestion -function TextBox:setAutoCompleteSelectedForeground(self, AutoCompleteSelectedForeground) end - ----Sets the value of the AutoCompleteBackground property. ----@param self TextBox self ----@param AutoCompleteBackground color Background color of the suggestion popup -function TextBox:setAutoCompleteBackground(self, AutoCompleteBackground) end - ----@class Table : Collection ----@field offset number Scroll offset for vertical scrolling ----@field scrollBarColor color Color of the scrollbar handle ----@field scrollBarBackgroundColor color Background color of the scrollbar ----@field scrollBarBackground string Symbol used for the scrollbar background ----@field headerColor color Color of the column headers ----@field sortDirection string Sort direction ("asc" or "desc") ----@field showScrollBar boolean Whether to show the scrollbar when items exceed height ----@field columns table List of column definitions with {name, width} properties ----@field sortColumn number nil Currently sorted column index ----@field gridColor color Color of grid lines ----@field customSortFunction table Custom sort functions for columns ----@field scrollBarSymbol string " Symbol used for the scrollbar handle -local Table = {} - ----Gets the value of the GridColor property. ----@param self Table self ----@return color gray Color of grid lines -function Table:getGridColor(self) end - ----Gets the value of the SortDirection property. ----@param self Table self ----@return string "asc" Sort direction ("asc" or "desc") -function Table:getSortDirection(self) end - ----Sets the value of the ScrollBarSymbol property. ----@param self Table self ----@param ScrollBarSymbol string " Symbol used for the scrollbar handle -function Table:setScrollBarSymbol(self, ScrollBarSymbol) end - ----Gets the value of the HeaderColor property. ----@param self Table self ----@return color blue Color of the column headers -function Table:getHeaderColor(self) end - ----Adds a new row to the table ----@return Table self The Table instance -function Table:addRow() end - ----Registers a function to handle the onRowSelect event. ----@param rowIndex number ----@param row table ----@param self Table self ----@param func function The function to be called when the event fires -function Table:onOnRowSelect(self, func) end - ----Gets the value of the CustomSortFunction property. ----@param self Table self ----@return table {} Custom sort functions for columns -function Table:getCustomSortFunction(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Table:mouse_scroll() end - ----Sets the value of the CustomSortFunction property. ----@param self Table self ----@param CustomSortFunction table Custom sort functions for columns -function Table:setCustomSortFunction(self, CustomSortFunction) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Table self The initialized instance ----@protected -function Table:init(props, basalt) end - ----Sets the value of the ShowScrollBar property. ----@param self Table self ----@param ShowScrollBar boolean Whether to show the scrollbar when items exceed height -function Table:setShowScrollBar(self, ShowScrollBar) end - ----Sets a custom sort function for a specific column ----@param columnIndex number The index of the column ----@param sortFn function Function that takes (rowA, rowB) and returns comparison result ----@return Table self The Table instance -function Table:setColumnSortFunction(columnIndex, sortFn) end - ----Gets the value of the Offset property. ----@param self Table self ----@return number 0 Scroll offset for vertical scrolling -function Table:getOffset(self) end - ----Gets the currently selected row ----@return table ? row The selected row or nil -function Table:getSelectedRow() end - ----Gets the value of the ScrollBarSymbol property. ----@param self Table self ----@return string " " Symbol used for the scrollbar handle -function Table:getScrollBarSymbol(self) end - ----Registers callback for row selection ----@param callback function The callback function(rowIndex, row) ----@return Table self The Table instance -function Table:onRowSelect(callback) end - ----Gets the value of the ShowScrollBar property. ----@param self Table self ----@return boolean true Whether to show the scrollbar when items exceed height -function Table:getShowScrollBar(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Table:mouse_up() end - ----Sets the value of the SortColumn property. ----@param self Table self ----@param SortColumn number nil Currently sorted column index -function Table:setSortColumn(self, SortColumn) end - ----Sets the value of the ScrollBarBackground property. ----@param self Table self ----@param ScrollBarBackground string Symbol used for the scrollbar background -function Table:setScrollBarBackground(self, ScrollBarBackground) end - ----Sets the value of the GridColor property. ----@param self Table self ----@param GridColor color Color of grid lines -function Table:setGridColor(self, GridColor) end - ----Set data with automatic formatting ----@param rawData table The raw data array (array of row arrays) ----@param formatters table ? Optional formatter functions for columns {[2] = function(value) return value end} ----@return Table self The Table instance -function Table:setData(rawData, formatters) end - ----Gets the value of the SortColumn property. ----@param self Table self ----@return number ? nil Currently sorted column index -function Table:getSortColumn(self) end - ----Gets a row by index ----@param rowIndex number The index of the row ----@return table ? row The row data or nil -function Table:getRow(rowIndex) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Table:render() end - ----Gets the value of the ScrollBarBackgroundColor property. ----@param self Table self ----@return color gray Background color of the scrollbar -function Table:getScrollBarBackgroundColor(self) end - ----Gets the value of the ScrollBarBackground property. ----@param self Table self ----@return string "\127" Symbol used for the scrollbar background -function Table:getScrollBarBackground(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Table:mouse_drag() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Table:mouse_click() end - ----Sorts the table data by column ----@param columnIndex number The index of the column to sort by ----@param fn function ? Optional custom sorting function ----@return Table self The Table instance -function Table:sortByColumn(columnIndex, fn) end - ----Sets the value of the Offset property. ----@param self Table self ----@param Offset number Scroll offset for vertical scrolling -function Table:setOffset(self, Offset) end - ----Gets the value of the Columns property. ----@param self Table self ----@return table {} List of column definitions with {name, width} properties -function Table:getColumns(self) end - ----Gets all table data ----@return table data Array of row cell arrays -function Table:getData() end - ----Adds a new column to the table ----@param name string The name of the column ----@param width number |string The width of the column (number, "auto", or "30%") ----@return Table self The Table instance -function Table:addColumn(name, width) end - ----Sets the value of the ScrollBarColor property. ----@param self Table self ----@param ScrollBarColor color Color of the scrollbar handle -function Table:setScrollBarColor(self, ScrollBarColor) end - ----Gets the value of the ScrollBarColor property. ----@param self Table self ----@return color lightGray Color of the scrollbar handle -function Table:getScrollBarColor(self) end - ----Removes a row by index ----@param rowIndex number The index of the row to remove ----@return Table self The Table instance -function Table:removeRow(rowIndex) end - ----Clears all table data ----@return Table self The Table instance -function Table:clearData() end - ----Sets the value of the HeaderColor property. ----@param self Table self ----@param HeaderColor color Color of the column headers -function Table:setHeaderColor(self, HeaderColor) end - ----Updates a specific cell value ----@param rowIndex number The row index ----@param colIndex number The column index ----@param value any The new value ----@return Table self The Table instance -function Table:updateCell(rowIndex, colIndex, value) end - ----Sets the value of the SortDirection property. ----@param self Table self ----@param SortDirection string Sort direction ("asc" or "desc") -function Table:setSortDirection(self, SortDirection) end - ----Sets the value of the Columns property. ----@param self Table self ----@param Columns table List of column definitions with {name, width} properties -function Table:setColumns(self, Columns) end - ----Sets the value of the ScrollBarBackgroundColor property. ----@param self Table self ----@param ScrollBarBackgroundColor color Background color of the scrollbar -function Table:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end - ----@class ErrorHandler -local ErrorHandler = {} - ----Handles an error ----@param errMsg string The error message -function errorHandler.error(errMsg) end - ----@class Container : VisualElement ----@field childrenEvents table Registered event handlers for all children ----@field offsetY number Vertical scroll/content offset ----@field visibleChildrenEvents table Event handlers for currently visible children ----@field childrenEventsSorted boolean Indicates if event handlers are properly sorted ----@field offsetX number Horizontal scroll/content offset ----@field children table Collection of all child elements ----@field visibleChildren table Currently visible child elements (calculated based on viewport) ----@field childrenSorted boolean Indicates if children are sorted by z-index ----@field focusedChild table Currently focused child element (receives keyboard events) ----@field eventListenerCount table Number of listeners per event type -local Container = {} - ----Creates a new ProgressBar element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ProgressBar element A new ProgressBar element. -function Container:addProgressBar(self, props) end - ----Creates a new Collection element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Collection element A new Collection element. -function Container:addCollection(self, props) end - ----Creates a new Menu element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Menu element A new Menu element. -function Container:addMenu(self, props) end - ----Creates a new TextBox element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return TextBox element A new TextBox element. -function Container:addTextBox(self, props) end - ----Creates a new BaseFrame element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BaseFrame element A new BaseFrame element. -function Container:addBaseFrame(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_drag(button, x, y) end - ----Creates a new Container element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Container element A new Container element. -function Container:addContainer(self, props) end - -function Container:drawFg() end - ----Creates a new Timer element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Timer element A new Timer element. -function Container:addTimer(self, props) end - ----Removes the current layout ----@return Container self For method chaining -function Container:clearLayout() end - ----Sets the value of the FocusedChild property. ----@param self Container self ----@param FocusedChild table Currently focused child element (receives keyboard events) -function Container:setFocusedChild(self, FocusedChild) end - ----Creates a new ScrollFrame element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ScrollFrame element A new ScrollFrame element. -function Container:addScrollFrame(self, props) end - ----Creates a new Slider element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Slider element A new Slider element. -function Container:addSlider(self, props) end - ----Creates a new BigFont element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BigFont element A new BigFont element. -function Container:addBigFont(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param text string The text to draw ----@param fg string The foreground color of the text ----@param bg string The background color of the text ----@return Container self The container instance ----@protected -function Container:blit(x, y, text, fg, bg) end - ----Sets the value of the VisibleChildrenEvents property. ----@param self Container self ----@param VisibleChildrenEvents table Event handlers for currently visible children -function Container:setVisibleChildrenEvents(self, VisibleChildrenEvents) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Container:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was pressed ----@return boolean handled Whether the event was handled ----@protected -function Container:char(char) end - ----Applies a layout from a file to this container ----@param layoutPath string Path to the layout file (e.g. "layouts/grid") ----@return Container self For method chaining -function Container:applyLayout(layoutPath) end - ----Sets the value of the OffsetY property. ----@param self Container self ----@param OffsetY number Vertical scroll/content offset -function Container:setOffsetY(self, OffsetY) end - ----Sets the value of the EventListenerCount property. ----@param self Container self ----@param EventListenerCount table Number of listeners per event type -function Container:setEventListenerCount(self, EventListenerCount) end - ----Gets the value of the OffsetX property. ----@param self Container self ----@return number 0 Horizontal scroll/content offset -function Container:getOffsetX(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@return boolean handled Whether the event was handled ----@protected -function Container:key(key) end - ----Creates a new List element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return List element A new List element. -function Container:addList(self, props) end - ----Creates a new Display element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Display element A new Display element. -function Container:addDisplay(self, props) end - ----Creates a new TabControl element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return TabControl element A new TabControl element. -function Container:addTabControl(self, props) end - ----Creates a new BarChart element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BarChart element A new BarChart element. -function Container:addBarChart(self, props) end - ----Gets the value of the VisibleChildren property. ----@param self Container self ----@return table {} Currently visible child elements (calculated based on viewport) -function Container:getVisibleChildren(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_click(button, x, y) end - ----Sets the value of the ChildrenEvents property. ----@param self Container self ----@param ChildrenEvents table Registered event handlers for all children -function Container:setChildrenEvents(self, ChildrenEvents) end - ----Creates a new ScrollBar element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ScrollBar element A new ScrollBar element. -function Container:addScrollBar(self, props) end - ----Creates a new ContextMenu element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ContextMenu element A new ContextMenu element. -function Container:addContextMenu(self, props) end - ----Gets the value of the FocusedChild property. ----@param self Container self ----@return table nil Currently focused child element (receives keyboard events) -function Container:getFocusedChild(self) end - ----Creates a new LineChart element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return LineChart element A new LineChart element. -function Container:addLineChart(self, props) end - -function Container:drawBg() end - ----Enables benchmarking for a container and all its children ----@param methodName string The method to benchmark ----@return Container self The container instance -function Container:benchmarkContainer(methodName) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param text string The text to draw ----@param fg color The foreground color of the text ----@return Container self The container instance ----@protected -function Container:textFg(x, y, text, fg) end - ----Gets the value of the EventListenerCount property. ----@param self Container self ----@return table {} Number of listeners per event type -function Container:getEventListenerCount(self) end - ----Creates a new Graph element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Graph element A new Graph element. -function Container:addGraph(self, props) end - ----Creates a new DropDown element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return DropDown element A new DropDown element. -function Container:addDropDown(self, props) end - ----Gets the value of the Children property. ----@param self Container self ----@return table {} Collection of all child elements -function Container:getChildren(self) end - ----Logs benchmark statistics for a container and all its children ----@param methodName string The method to log ----@return Container self The container instance -function Container:logContainerBenchmarks(methodName) end - ----Sets the value of the VisibleChildren property. ----@param self Container self ----@param VisibleChildren table Currently visible child elements (calculated based on viewport) -function Container:setVisibleChildren(self, VisibleChildren) end - ----Creates a new Image element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Image element A new Image element. -function Container:addImage(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return boolean handled Whether the event was handled ----@protected -function Container:handleEvent(event) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param _ number unknown ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_move(_, x, y) end - ----Creates a new VisualElement element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return VisualElement element A new VisualElement element. -function Container:addVisualElement(self, props) end - ----Stops benchmarking for a container and all its children ----@param methodName string The method to stop benchmarking ----@return Container self The container instance -function Container:stopContainerBenchmark(methodName) end - ----Gets the value of the ChildrenEventsSorted property. ----@param self Container self ----@return boolean true Indicates if event handlers are properly sorted -function Container:getChildrenEventsSorted(self) end - ----Removes an element from this container's hierarchy and cleans up its events ----@param child table The element to remove ----@return Container self For method chaining -function Container:removeChild(child) end - ----Gets the value of the ChildrenSorted property. ----@param self Container self ----@return boolean true Indicates if children are sorted by z-index -function Container:getChildrenSorted(self) end - ----Creates a new Breadcrumb element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Breadcrumb element A new Breadcrumb element. -function Container:addBreadcrumb(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param width number The width of the text ----@param height number The height of the text ----@param text string The text to draw ----@param fg string The foreground color of the text ----@param bg string The background color of the text ----@return Container self The container instance ----@protected -function Container:multiBlit(x, y, width, height, text, fg, bg) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@protected -function Container:mouse_release(button, x, y) end - ----Sets the value of the ChildrenEventsSorted property. ----@param self Container self ----@param ChildrenEventsSorted boolean Indicates if event handlers are properly sorted -function Container:setChildrenEventsSorted(self, ChildrenEventsSorted) end - ----Unregisters the children events of the container ----@param child table The child to unregister events for ----@param eventName string The event name to unregister ----@return Container self The container instance -function Container:unregisterChildEvent(child, eventName) end - ----Creates a new Program element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Program element A new Program element. -function Container:addProgram(self, props) end - ----Registers the children events of the container ----@param child table The child to register events for ----@return Container self The container instance -function Container:registerChildrenEvents(child) end - ----Creates a new SideNav element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return SideNav element A new SideNav element. -function Container:addSideNav(self, props) end - ----Gets the value of the OffsetY property. ----@param self Container self ----@return number 0 Vertical scroll/content offset -function Container:getOffsetY(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The direction of the scroll ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_scroll(direction, x, y) end - ----Creates a new CheckBox element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return CheckBox element A new CheckBox element. -function Container:addCheckBox(self, props) end - ----Sorts the children events of the container ----@param eventName string The event name to sort ----@return Container self The container instance -function Container:sortChildrenEvents(eventName) end - ----Creates a new Input element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Input element A new Input element. -function Container:addInput(self, props) end - ----Updates the current layout (recalculates positions) ----@return Container self For method chaining -function Container:updateLayout() end - ----Gets the value of the ChildrenEvents property. ----@param self Container self ----@return table {} Registered event handlers for all children -function Container:getChildrenEvents(self) end - ----Creates a new Accordion element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Accordion element A new Accordion element. -function Container:addAccordion(self, props) end - ----Adds a new element to this container's hierarchy ----@param child table The element to add as a child ----@return Container self For method chaining -function Container:addChild(child) end - ----Unregisters the children events of the container ----@param child table The child to unregister events for ----@return Container self The container instance -function Container:removeChildrenEvents(child) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was released ----@return boolean handled Whether the event was handled ----@protected -function Container:key_up(key) end - ----Creates a new Dialog element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Dialog element A new Dialog element. -function Container:addDialog(self, props) end - ----Sets the value of the OffsetX property. ----@param self Container self ----@param OffsetX number Horizontal scroll/content offset -function Container:setOffsetX(self, OffsetX) end - ----Calls a event on all children ----@param visibleOnly boolean Whether to only call the event on visible children ----@param event string The event to call ----@return boolean handled Whether the event was handled ----@return table ? child The child that handled the event -function Container:callChildrenEvent(visibleOnly, event) end - ----Tests whether a child element is currently visible within the container's viewport ----@param child table The child element to check ----@return boolean isVisible Whether the child is within view bounds -function Container:isChildVisible(child) end - ----Creates a new Button element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Button element A new Button element. -function Container:addButton(self, props) end - ----Gets the value of the VisibleChildrenEvents property. ----@param self Container self ----@return table {} Event handlers for currently visible children -function Container:getVisibleChildrenEvents(self) end - ----Creates a new Frame element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Frame element A new Frame element. -function Container:addFrame(self, props) end - ----Creates a new Switch element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Switch element A new Switch element. -function Container:addSwitch(self, props) end - ----Sets the value of the ChildrenSorted property. ----@param self Container self ----@param ChildrenSorted boolean Indicates if children are sorted by z-index -function Container:setChildrenSorted(self, ChildrenSorted) end - ----Creates a new BaseElement element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BaseElement element A new BaseElement element. -function Container:addBaseElement(self, props) end - ----Creates a new ComboBox element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ComboBox element A new ComboBox element. -function Container:addComboBox(self, props) end - -function Container:drawText() end - ----Creates a new Table element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Table element A new Table element. -function Container:addTable(self, props) end - ----Creates a new Label element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Label element A new Label element. -function Container:addLabel(self, props) end - ----Removes all child elements and resets the container's state ----@return Container self For method chaining -function Container:clear() end - ----Registers an event handler for a specific child element ----@param child table The child element to register events for ----@param eventName string The name of the event to register ----@return Container self For method chaining -function Container:registerChildEvent(child, eventName) end - ----Creates a new Tree element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Tree element A new Tree element. -function Container:addTree(self, props) end - ----Re-sorts children by their z-index and updates visibility ----@return Container self For method chaining -function Container:sortChildren() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_up(button, x, y) end - ----Enables debugging for this container and all its children ----@param self Container The container to debug ----@param level number The debug level -function Container.debugChildren(self, level) end - ----Creates a new Toast element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Toast element A new Toast element. -function Container:addToast(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Container:init(props, basalt) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param text string The text to draw ----@param bg color The background color of the text ----@return Container self The container instance ----@protected -function Container:textBg(x, y, text, bg) end - ----Sets the value of the Children property. ----@param self Container self ----@param Children table Collection of all child elements -function Container:setChildren(self, Children) end - ----Locates a child element using a path-like syntax (e.g. "panel/button1") ----@param path string Path to the child (e.g. "panel/button1", "header/title") ----@return Element ? child The found element or nil if not found -function Container:getChild(path) end - ----@class Image : VisualElement ----@field bimg table The bimg image data ----@field offsetX number Horizontal offset for viewing larger images ----@field currentFrame number Current animation frame ----@field autoResize boolean Whether to automatically resize the image when content exceeds bounds ----@field offsetY number Vertical offset for viewing larger images -local Image = {} - ----Gets the value of the Bimg property. ----@param self Image self ----@return table {} The bimg image data -function Image:getBimg(self) end - ----Gets pixel information at position ----@param x number X position ----@param y number Y position ----@return number ? fg Foreground color ----@return number ? bg Background color ----@return string ? char Character at position -function Image:getPixelData(x, y) end - ----Sets the value of the AutoResize property. ----@param self Image self ----@param AutoResize boolean Whether to automatically resize the image when content exceeds bounds -function Image:setAutoResize(self, AutoResize) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Image:render() end - ----Gets the background color at the specified position ----@param x number The x position ----@param y number The y position ----@param length number The length of the background color pattern to get ----@return string bg The background color pattern -function Image:getBg(x, y, length) end - ----Sets the value of the Bimg property. ----@param self Image self ----@param Bimg table The bimg image data -function Image:setBimg(self, Bimg) end - ----Sets the value of the OffsetX property. ----@param self Image self ----@param OffsetX number Horizontal offset for viewing larger images -function Image:setOffsetX(self, OffsetX) end - ----Gets the text at the specified position ----@param x number The x position ----@param y number The y position ----@param length number The length of the text to get ----@return string text The text at the specified position -function Image:getText(x, y, length) end - ----Sets the text at the specified position ----@param x number The x position ----@param y number The y position ----@param text string The text to set ----@return Image self The Image instance -function Image:setText(x, y, text) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Image self The initialized instance ----@protected -function Image:init(props, basalt) end - ----Gets the size of the image ----@return number width The width of the image ----@return number height The height of the image -function Image:getImageSize() end - ----Gets the value of the OffsetY property. ----@param self Image self ----@return number 0 Vertical offset for viewing larger images -function Image:getOffsetY(self) end - ----Sets the metadata of the image ----@param key string The key of the metadata to set ----@param value string The value of the metadata to set ----@return Image self The Image instance -function Image:setMetadata(key, value) end - ----Sets the foreground color at the specified position ----@param x number The x position ----@param y number The y position ----@param pattern string The foreground color pattern ----@return Image self The Image instance -function Image:setFg(x, y, pattern) end - ----Gets the value of the CurrentFrame property. ----@param self Image self ----@return number 1 Current animation frame -function Image:getCurrentFrame(self) end - ----Gets the value of the OffsetX property. ----@param self Image self ----@return number 0 Horizontal offset for viewing larger images -function Image:getOffsetX(self) end - ----Updates the specified frame with the provided data ----@param frameIndex number The index of the frame to update ----@param frame table The new frame data ----@return Image self The Image instance -function Image:updateFrame(frameIndex, frame) end - ----Adds a new frame to the image ----@return Image self The Image instance -function Image:addFrame() end - ----Gets the value of the AutoResize property. ----@param self Image self ----@return boolean false Whether to automatically resize the image when content exceeds bounds -function Image:getAutoResize(self) end - ----Sets the pixel at the specified position ----@param x number The x position ----@param y number The y position ----@param char string The character to set ----@param fg string The foreground color pattern ----@param bg string The background color pattern ----@return Image self The Image instance -function Image:setPixel(x, y, char, fg, bg) end - ----Sets the background color at the specified position ----@param x number The x position ----@param y number The y position ----@param pattern string The background color pattern ----@return Image self The Image instance -function Image:setBg(x, y, pattern) end - ----Sets the value of the CurrentFrame property. ----@param self Image self ----@param CurrentFrame number Current animation frame -function Image:setCurrentFrame(self, CurrentFrame) end - ----Gets the foreground color at the specified position ----@param x number The x position ----@param y number The y position ----@param length number The length of the foreground color pattern to get ----@return string fg The foreground color pattern -function Image:getFg(x, y, length) end - ----Sets the value of the OffsetY property. ----@param self Image self ----@param OffsetY number Vertical offset for viewing larger images -function Image:setOffsetY(self, OffsetY) end - ----Gets the metadata of the image ----@return table metadata The metadata of the image -function Image:getMetadata() end - ----Gets the specified frame ----@param frameIndex number The index of the frame to get ----@return table frame The frame data -function Image:getFrame(frameIndex) end - ----Advances to the next frame in the animation ----@return Image self The Image instance -function Image:nextFrame() end - ----Resizes the image to the specified width and height ----@param width number The new width of the image ----@param height number The new height of the image ----@return Image self The Image instance -function Image:resizeImage(width, height) end - ----@class Animation -local Animation = {} - ----Adds a new animation to the sequence ----@param type string The type of animation ----@param args table The animation arguments ----@param duration number The duration in seconds ----@param easing string The easing function name -function Animation:addAnimation(type, args, duration, easing) end - ----Registers a new easing function ----@param name string The name of the easing function ----@param func function The easing function (takes progress 0-1, returns modified progress) -function Animation.registerEasing(name, func) end - ----Creates a new sequence ----@return Animation self The animation instance -function Animation:sequence() end - ----The event handler for the animation (listens to timer events) ----@param event string The event type ----@param timerId number The timer ID -function Animation:event(event, timerId) end - ----Registers a callback for the update event ----@param callback function The callback function to register ----@return Animation self The animation instance -function Animation:onUpdate(callback) end - ----Registers a new animation type ----@param name string The name of the animation ----@param handlers table Table containing start, update and complete handlers -function Animation.registerAnimation(name, handlers) end - ----Creates a new Animation ----@param element VisualElement The element to animate ----@return Animation The new animation -function Animation.new(element) end - ----Stops the animation immediately: cancels timers, completes running anim instances and clears the element property -function Animation:stop() end - ----Starts the animation ----@return Animation self The animation instance -function Animation:start() end - ----Registers a callback for the start event ----@param callback function The callback function to register -function Animation:onStart(callback) end - ----Registers a callback for the complete event ----@param callback function The callback function to register ----@return Animation self The animation instance -function Animation:onComplete(callback) end - ---@class ScrollBar : VisualElement ----@field max number Maximum scroll value +---@field symbolBackgroundColor color Background color of the ScrollBar handle ---@field handleSize number Size of the ScrollBar handle in characters ---@field orientation string Orientation of the ScrollBar ("vertical" or "horizontal") ----@field attachedProperty string nil The property being controlled ----@field symbolBackgroundColor color Background color of the ScrollBar handle +---@field max number Maximum scroll value ---@field minValue number 0 Minimum value or function that returns it +---@field value number Current scroll value +---@field attachedProperty string nil The property being controlled +---@field min number Minimum scroll value +---@field dragMultiplier number How fast the ScrollBar moves when dragging ---@field backgroundSymbol string Symbol used for the ScrollBar background ----@field maxValue number 100 Maximum value or function that returns it ---@field attachedElement table nil The element this ScrollBar is attached to ---@field step number Step size for scroll operations ----@field dragMultiplier number How fast the ScrollBar moves when dragging ---@field symbol string " Symbol used for the ScrollBar handle ----@field value number Current scroll value ----@field min number Minimum scroll value +---@field maxValue number 100 Maximum value or function that returns it local ScrollBar = {} ----Gets the value of the MinValue property. ----@param self ScrollBar self ----@return number |function 0 Minimum value or function that returns it -function ScrollBar:getMinValue(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return ScrollBar self The initialized instance ----@protected -function ScrollBar:init(props, basalt) end - ----Sets the value of the Value property. ----@param self ScrollBar self ----@param Value number Current scroll value -function ScrollBar:setValue(self, Value) end - ----Sets the value of the Symbol property. ----@param self ScrollBar self ----@param Symbol string " Symbol used for the ScrollBar handle -function ScrollBar:setSymbol(self, Symbol) end - ----Sets the value of the AttachedProperty property. ----@param self ScrollBar self ----@param AttachedProperty string nil The property being controlled -function ScrollBar:setAttachedProperty(self, AttachedProperty) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button being dragged ----@param x number The x position of the drag ----@param y number The y position of the drag ----@return boolean Whether the event was handled ----@protected -function ScrollBar:mouse_drag(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean Whether the event was handled ----@protected -function ScrollBar:mouse_click(button, x, y) end - ----Gets the value of the BackgroundSymbol property. ----@param self ScrollBar self ----@return string "\127" Symbol used for the ScrollBar background -function ScrollBar:getBackgroundSymbol(self) end - ----Gets the value of the MaxValue property. ----@param self ScrollBar self ----@return number |function 100 Maximum value or function that returns it -function ScrollBar:getMaxValue(self) end - ----Gets the value of the Orientation property. ----@param self ScrollBar self ----@return string vertical Orientation of the ScrollBar ("vertical" or "horizontal") -function ScrollBar:getOrientation(self) end - ----Sets the value of the DragMultiplier property. ----@param self ScrollBar self ----@param DragMultiplier number How fast the ScrollBar moves when dragging -function ScrollBar:setDragMultiplier(self, DragMultiplier) end - ----Sets the value of the BackgroundSymbol property. ----@param self ScrollBar self ----@param BackgroundSymbol string Symbol used for the ScrollBar background -function ScrollBar:setBackgroundSymbol(self, BackgroundSymbol) end - ----Gets the value of the Max property. ----@param self ScrollBar self ----@return number 100 Maximum scroll value -function ScrollBar:getMax(self) end - ----Gets the value of the Symbol property. ----@param self ScrollBar self ----@return string " " Symbol used for the ScrollBar handle -function ScrollBar:getSymbol(self) end - ---Gets the value of the Value property. ---@param self ScrollBar self ---@return number 0 Current scroll value function ScrollBar:getValue(self) end ----Sets the value of the HandleSize property. ----@param self ScrollBar self ----@param HandleSize number Size of the ScrollBar handle in characters -function ScrollBar:setHandleSize(self, HandleSize) end - ----Gets the value of the Min property. ----@param self ScrollBar self ----@return number 0 Minimum scroll value -function ScrollBar:getMin(self) end - ----Attaches the ScrollBar to an element's property ----@param element BaseElement The element to attach to ----@param config table Configuration {property = "propertyName", min = number|function, max = number|function} ----@return ScrollBar self The ScrollBar instance -function ScrollBar:attach(element, config) end - ----Sets the value of the AttachedElement property. ----@param self ScrollBar self ----@param AttachedElement table nil The element this ScrollBar is attached to -function ScrollBar:setAttachedElement(self, AttachedElement) end - ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param direction number The scroll direction (1 for up, -1 for down) ---@param x number The x position of the scroll @@ -3335,596 +315,550 @@ function ScrollBar:setAttachedElement(self, AttachedElement) end ---@protected function ScrollBar:mouse_scroll(direction, x, y) end ----Updates the attached element's property based on the ScrollBar value ----@return ScrollBar self The ScrollBar instance -function ScrollBar:updateAttachedElement() end - ----Gets the value of the DragMultiplier property. ----@param self ScrollBar self ----@return number 1 How fast the ScrollBar moves when dragging -function ScrollBar:getDragMultiplier(self) end - ----Sets the value of the MinValue property. ----@param self ScrollBar self ----@param MinValue number 0 Minimum value or function that returns it -function ScrollBar:setMinValue(self, MinValue) end - ----Gets the value of the HandleSize property. ----@param self ScrollBar self ----@return number 2 Size of the ScrollBar handle in characters -function ScrollBar:getHandleSize(self) end - ----Sets the value of the Min property. ----@param self ScrollBar self ----@param Min number Minimum scroll value -function ScrollBar:setMin(self, Min) end - ----Sets the value of the Step property. ----@param self ScrollBar self ----@param Step number Step size for scroll operations -function ScrollBar:setStep(self, Step) end - ----Gets the value of the Step property. ----@param self ScrollBar self ----@return number 1 Step size for scroll operations -function ScrollBar:getStep(self) end - ----Sets the value of the Orientation property. ----@param self ScrollBar self ----@param Orientation string Orientation of the ScrollBar ("vertical" or "horizontal") -function ScrollBar:setOrientation(self, Orientation) end - ----Sets the value of the MaxValue property. ----@param self ScrollBar self ----@param MaxValue number 100 Maximum value or function that returns it -function ScrollBar:setMaxValue(self, MaxValue) end - ----Gets the value of the AttachedElement property. ----@param self ScrollBar self ----@return table ? nil The element this ScrollBar is attached to -function ScrollBar:getAttachedElement(self) end - ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean Whether the event was handled ---@protected -function ScrollBar:render() end - ----Gets the value of the SymbolBackgroundColor property. ----@param self ScrollBar self ----@return color black Background color of the ScrollBar handle -function ScrollBar:getSymbolBackgroundColor(self) end - ----Sets the value of the Max property. ----@param self ScrollBar self ----@param Max number Maximum scroll value -function ScrollBar:setMax(self, Max) end - ----Sets the value of the SymbolBackgroundColor property. ----@param self ScrollBar self ----@param SymbolBackgroundColor color Background color of the ScrollBar handle -function ScrollBar:setSymbolBackgroundColor(self, SymbolBackgroundColor) end +function ScrollBar:mouse_click(button, x, y) end ---Gets the value of the AttachedProperty property. ---@param self ScrollBar self ---@return string ? nil The property being controlled function ScrollBar:getAttachedProperty(self) end ----@class ContextMenu : Container ----@field items table List of menu items ----@field itemHeight number Height of each menu item ----@field isOpen boolean Whether the menu is currently open ----@field openSubmenu table Currently open submenu data -local ContextMenu = {} +---Gets the value of the Max property. +---@param self ScrollBar self +---@return number 100 Maximum scroll value +function ScrollBar:getMax(self) end ----Gets the value of the IsOpen property. ----@param self ContextMenu self ----@return boolean false Whether the menu is currently open -function ContextMenu:getIsOpen(self) end +---Sets the value of the BackgroundSymbol property. +---@param self ScrollBar self +---@param BackgroundSymbol string Symbol used for the ScrollBar background +function ScrollBar:setBackgroundSymbol(self, BackgroundSymbol) end + +---Gets the value of the BackgroundSymbol property. +---@param self ScrollBar self +---@return string "\127" Symbol used for the ScrollBar background +function ScrollBar:getBackgroundSymbol(self) end + +---Gets the value of the HandleSize property. +---@param self ScrollBar self +---@return number 2 Size of the ScrollBar handle in characters +function ScrollBar:getHandleSize(self) end + +---Gets the value of the Min property. +---@param self ScrollBar self +---@return number 0 Minimum scroll value +function ScrollBar:getMin(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function ContextMenu:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function ContextMenu:mouse_click() end - ----Gets the value of the ItemHeight property. ----@param self ContextMenu self ----@return number 1 Height of each menu item -function ContextMenu:getItemHeight(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function ContextMenu:init(props, basalt) end - ----Gets the value of the OpenSubmenu property. ----@param self ContextMenu self ----@return table nil Currently open submenu data -function ContextMenu:getOpenSubmenu(self) end - ----Sets the value of the ItemHeight property. ----@param self ContextMenu self ----@param ItemHeight number Height of each menu item -function ContextMenu:setItemHeight(self, ItemHeight) end - ----Closes the entire menu chain (parent and all submenus) ----@return ContextMenu self For method chaining -function ContextMenu:closeAll() end - ----Sets the value of the IsOpen property. ----@param self ContextMenu self ----@param IsOpen boolean Whether the menu is currently open -function ContextMenu:setIsOpen(self, IsOpen) end - ----Closes the menu and any submenus ----@return ContextMenu self For method chaining -function ContextMenu:close() end - ----Opens the menu ----@return ContextMenu self For method chaining -function ContextMenu:open() end - ----Sets the menu items ----@param items table Array of item definitions ----@return ContextMenu self For method chaining -function ContextMenu:setItems(items) end - ----Gets the value of the Items property. ----@param self ContextMenu self ----@return table {} List of menu items -function ContextMenu:getItems(self) end - ----Sets the value of the OpenSubmenu property. ----@param self ContextMenu self ----@param OpenSubmenu table Currently open submenu data -function ContextMenu:setOpenSubmenu(self, OpenSubmenu) end - ----@class Accordion : Container ----@field panels table List of panel definitions ----@field expandedHeaderBackground color Background color for expanded panel headers ----@field expandedHeaderTextColor color Text color for expanded panel headers ----@field panelHeaderHeight number Height of each panel header ----@field allowMultiple boolean Allow multiple panels to be open at once ----@field headerBackground color Background color for panel headers ----@field headerTextColor color Text color for panel headers -local Accordion = {} - ----Sets the value of the HeaderBackground property. ----@param self Accordion self ----@param HeaderBackground color Background color for panel headers -function Accordion:setHeaderBackground(self, HeaderBackground) end - ----Gets the value of the Panels property. ----@param self Accordion self ----@return table {} List of panel definitions -function Accordion:getPanels(self) end - ----Gets the value of the HeaderBackground property. ----@param self Accordion self ----@return color gray Background color for panel headers -function Accordion:getHeaderBackground(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Accordion:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Accordion:init(props, basalt) end - ----Sets the value of the ExpandedHeaderTextColor property. ----@param self Accordion self ----@param ExpandedHeaderTextColor color Text color for expanded panel headers -function Accordion:setExpandedHeaderTextColor(self, ExpandedHeaderTextColor) end - ----@param panelId number The ID of the panel ----@return table ? container The panel's container or nil -function Accordion:getPanel(panelId) end - ----Gets the value of the ExpandedHeaderBackground property. ----@param self Accordion self ----@return color lightGray Background color for expanded panel headers -function Accordion:getExpandedHeaderBackground(self) end - -function Accordion:mouse_scroll() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click (global) ----@param y number The y position of the click (global) +---@param button number The mouse button being dragged +---@param x number The x position of the drag +---@param y number The y position of the drag ---@return boolean Whether the event was handled ---@protected -function Accordion:mouse_click(button, x, y) end +function ScrollBar:mouse_drag(button, x, y) end ----Gets the value of the PanelHeaderHeight property. ----@param self Accordion self ----@return number 1 Height of each panel header -function Accordion:getPanelHeaderHeight(self) end +---Sets the value of the Symbol property. +---@param self ScrollBar self +---@param Symbol string " Symbol used for the ScrollBar handle +function ScrollBar:setSymbol(self, Symbol) end ----Sets the value of the Panels property. ----@param self Accordion self ----@param Panels table List of panel definitions -function Accordion:setPanels(self, Panels) end +---Sets the value of the MaxValue property. +---@param self ScrollBar self +---@param MaxValue number 100 Maximum value or function that returns it +function ScrollBar:setMaxValue(self, MaxValue) end ----Creates a new panel and returns the panel's container ----@param title string The title of the panel ----@param expanded boolean Whether the panel starts expanded (default: false) ----@return table panelContainer The container for this panel -function Accordion:newPanel(title, expanded) end +---Gets the value of the Orientation property. +---@param self ScrollBar self +---@return string vertical Orientation of the ScrollBar ("vertical" or "horizontal") +function ScrollBar:getOrientation(self) end ----Sets the value of the ExpandedHeaderBackground property. ----@param self Accordion self ----@param ExpandedHeaderBackground color Background color for expanded panel headers -function Accordion:setExpandedHeaderBackground(self, ExpandedHeaderBackground) end +---Sets the value of the Max property. +---@param self ScrollBar self +---@param Max number Maximum scroll value +function ScrollBar:setMax(self, Max) end ----@param panelId number The ID of the panel to collapse ----@return Accordion self For method chaining -function Accordion:collapsePanel(panelId) end +---Sets the value of the Min property. +---@param self ScrollBar self +---@param Min number Minimum scroll value +function ScrollBar:setMin(self, Min) end ----Gets the value of the AllowMultiple property. ----@param self Accordion self ----@return boolean false Allow multiple panels to be open at once -function Accordion:getAllowMultiple(self) end +---Sets the value of the MinValue property. +---@param self ScrollBar self +---@param MinValue number 0 Minimum value or function that returns it +function ScrollBar:setMinValue(self, MinValue) end ----Sets the value of the AllowMultiple property. ----@param self Accordion self ----@param AllowMultiple boolean Allow multiple panels to be open at once -function Accordion:setAllowMultiple(self, AllowMultiple) end +---Attaches the ScrollBar to an element's property +---@param element BaseElement The element to attach to +---@param config table Configuration {property = "propertyName", min = number|function, max = number|function} +---@return ScrollBar self The ScrollBar instance +function ScrollBar:attach(element, config) end ----Gets the value of the ExpandedHeaderTextColor property. ----@param self Accordion self ----@return color black Text color for expanded panel headers -function Accordion:getExpandedHeaderTextColor(self) end - ----@param panelId number The ID of the panel to expand ----@return Accordion self For method chaining -function Accordion:expandPanel(panelId) end - ----Sets the value of the PanelHeaderHeight property. ----@param self Accordion self ----@param PanelHeaderHeight number Height of each panel header -function Accordion:setPanelHeaderHeight(self, PanelHeaderHeight) end - ----Gets the value of the HeaderTextColor property. ----@param self Accordion self ----@return color white Text color for panel headers -function Accordion:getHeaderTextColor(self) end - ----Sets the value of the HeaderTextColor property. ----@param self Accordion self ----@param HeaderTextColor color Text color for panel headers -function Accordion:setHeaderTextColor(self, HeaderTextColor) end - ----@param panelId number The ID of the panel to toggle ----@return Accordion self For method chaining -function Accordion:togglePanel(panelId) end - ----@class basalt -local basalt = {} - ----Loads a manifest file that describes element requirements and configuration ----@param path string The path to the manifest file ----@return table manifest The loaded manifest data -function basalt.loadManifest(path) end - ----Creates and returns a new UI element of the specified type. ----@param type string The type of element to create (e.g. "Button", "Label", "BaseFrame") ----@return table element The created element instance -function basalt.create(type) end - ----Runs basalt once, can be used to update the UI manually, but you have to feed it the events -function basalt.update() end - ----Creates and returns a new BaseFrame ----@return BaseFrame BaseFrame The created frame instance -function basalt.createFrame() end - ----Starts the Basalt runtime -function basalt.run() end - ----Requires specific elements and validates they are available ----@param elements table |string List of element names or single element name -function basalt.requireElements(elements) end - ----Sets the active frame ----@param frame BaseFrame The frame to set as active -function basalt.setActiveFrame(frame) end - ----Schedules a function to run in a coroutine ----@param func function The function to schedule ----@return thread func The scheduled function -function basalt.schedule(func) end - ----Registers a callback function for a specific event ----@param eventName string The name of the event to listen for (e.g. "mouse_click", "key", "timer") ----@param callback function The callback function to execute when the event occurs -function basalt.onEvent(eventName, callback) end - ----Removes a scheduled update ----@param func thread The scheduled function to remove ----@return boolean success Whether the scheduled function was removed -function basalt.removeSchedule(func) end - ----Returns the element manager instance ----@return table ElementManager The element manager -function basalt.getElementManager() end - ----Configures the ElementManager (shortcut to elementManager.configure) ----@param config table Configuration options -function basalt.configure(config) end - ----Stops the Basalt runtime -function basalt.stop() end - ----Installs an element interactively or from a specified source ----@param elementName string The name of the element to install -function basalt.install(elementName) end - ----Returns the error manager instance ----@return table ErrorManager The error manager -function basalt.getErrorManager() end - ----Removes a callback function for a specific event ----@param eventName string The name of the event ----@param callback function The callback function to remove ----@return boolean success Whether the callback was found and removed -function basalt.removeEvent(eventName, callback) end - ----Returns a Plugin API ----@param name string The name of the plugin ----@return table Plugin The plugin API -function basalt.getAPI(name) end - ----Returns the active frame ----@return BaseFrame ? BaseFrame The frame to set as active -function basalt.getActiveFrame() end - ----Sets a frame as focused ----@param frame BaseFrame The frame to set as focused -function basalt.setFocus(frame) end - ----Triggers a custom event and calls all registered callbacks ----@param eventName string The name of the event to trigger -function basalt.triggerEvent(eventName) end - ----Gets or creates the main frame ----@return BaseFrame BaseFrame The main frame instance -function basalt.getMainFrame() end - ----Returns the focused frame ----@return BaseFrame ? BaseFrame The focused frame -function basalt.getFocus() end - ----Returns an element's class without creating a instance ----@param name string The name of the element ----@return table Element The element class -function basalt.getElementClass(name) end - ----@class Log -local Log = {} - ----Sends a debug message to the logger. -function Log.debug() end - ----Sets if the logger should log to a file. -function Log.setLogToFile() end - ----Sends an error message to the logger. -function Log.error() end - ----Sets if the logger should log -function Log.setEnabled() end - ----Sends an info message to the logger. -function Log.info() end - ----Sends a warning message to the logger. -function Log.warn() end - ----@class Slider : VisualElement ----@field max number Maximum value for value conversion (maps slider position to this range) ----@field sliderColor color Color of the slider handle ----@field step number Current position of the slider handle (1 to width/height) ----@field horizontal boolean Whether the slider is horizontal (false for vertical) ----@field barColor color Color of the slider track -local Slider = {} +---Gets the value of the SymbolBackgroundColor property. +---@param self ScrollBar self +---@return color black Background color of the ScrollBar handle +function ScrollBar:getSymbolBackgroundColor(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected -function Slider:render() end - ----Gets the value of the Step property. ----@param self Slider self ----@return number 1 Current position of the slider handle (1 to width/height) -function Slider:getStep(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@return boolean handled Whether the event was handled ----@protected -function Slider:mouse_scroll(button, x, y) end - ----Gets the current value of the slider ----@return number value The current value (0 to max) -function Slider:getValue() end +function ScrollBar:render() end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with ---@param basalt table The basalt instance ----@return Slider self The initialized instance +---@return ScrollBar self The initialized instance ---@protected -function Slider:init(props, basalt) end +function ScrollBar:init(props, basalt) end ----Registers a function to handle the onChange event. ----@param value number ----@param self Slider self +---Sets the value of the HandleSize property. +---@param self ScrollBar self +---@param HandleSize number Size of the ScrollBar handle in characters +function ScrollBar:setHandleSize(self, HandleSize) end + +---Sets the value of the SymbolBackgroundColor property. +---@param self ScrollBar self +---@param SymbolBackgroundColor color Background color of the ScrollBar handle +function ScrollBar:setSymbolBackgroundColor(self, SymbolBackgroundColor) end + +---Gets the value of the Symbol property. +---@param self ScrollBar self +---@return string " " Symbol used for the ScrollBar handle +function ScrollBar:getSymbol(self) end + +---Sets the value of the AttachedElement property. +---@param self ScrollBar self +---@param AttachedElement table nil The element this ScrollBar is attached to +function ScrollBar:setAttachedElement(self, AttachedElement) end + +---Sets the value of the Step property. +---@param self ScrollBar self +---@param Step number Step size for scroll operations +function ScrollBar:setStep(self, Step) end + +---Updates the attached element's property based on the ScrollBar value +---@return ScrollBar self The ScrollBar instance +function ScrollBar:updateAttachedElement() end + +---Sets the value of the DragMultiplier property. +---@param self ScrollBar self +---@param DragMultiplier number How fast the ScrollBar moves when dragging +function ScrollBar:setDragMultiplier(self, DragMultiplier) end + +---Gets the value of the MinValue property. +---@param self ScrollBar self +---@return number |function 0 Minimum value or function that returns it +function ScrollBar:getMinValue(self) end + +---Sets the value of the AttachedProperty property. +---@param self ScrollBar self +---@param AttachedProperty string nil The property being controlled +function ScrollBar:setAttachedProperty(self, AttachedProperty) end + +---Gets the value of the AttachedElement property. +---@param self ScrollBar self +---@return table ? nil The element this ScrollBar is attached to +function ScrollBar:getAttachedElement(self) end + +---Gets the value of the MaxValue property. +---@param self ScrollBar self +---@return number |function 100 Maximum value or function that returns it +function ScrollBar:getMaxValue(self) end + +---Sets the value of the Orientation property. +---@param self ScrollBar self +---@param Orientation string Orientation of the ScrollBar ("vertical" or "horizontal") +function ScrollBar:setOrientation(self, Orientation) end + +---Sets the value of the Value property. +---@param self ScrollBar self +---@param Value number Current scroll value +function ScrollBar:setValue(self, Value) end + +---Gets the value of the Step property. +---@param self ScrollBar self +---@return number 1 Step size for scroll operations +function ScrollBar:getStep(self) end + +---Gets the value of the DragMultiplier property. +---@param self ScrollBar self +---@return number 1 How fast the ScrollBar moves when dragging +function ScrollBar:getDragMultiplier(self) end + +---@class List : Collection +---@field showScrollBar boolean Whether to show the scrollbar when items exceed height +---@field scrollBarSymbol string " Symbol used for the scrollbar handle +---@field emptyText string items" Text to display when the list is empty +---@field scrollBarBackground string Symbol used for the scrollbar background +---@field scrollBarColor color Color of the scrollbar handle +---@field scrollBarBackgroundColor color Background color of the scrollbar +---@field offset number Current scroll offset for viewing long lists +local List = {} + +---Registers a function to handle the onSelect event. +---@param List self +---@param index number +---@param item table +---@param self List self ---@param func function The function to be called when the event fires -function Slider:onOnChange(self, func) end +function List:onOnSelect(self, func) end ----Sets the value of the Horizontal property. ----@param self Slider self ----@param Horizontal boolean Whether the slider is horizontal (false for vertical) -function Slider:setHorizontal(self, Horizontal) end +---Gets the value of the ScrollBarBackgroundColor property. +---@param self List self +---@return color gray Background color of the scrollbar +function List:getScrollBarBackgroundColor(self) end ----Sets the value of the SliderColor property. ----@param self Slider self ----@param SliderColor color Color of the slider handle -function Slider:setSliderColor(self, SliderColor) end +---Sets the value of the ScrollBarBackground property. +---@param self List self +---@param ScrollBarBackground string Symbol used for the scrollbar background +function List:setScrollBarBackground(self, ScrollBarBackground) end ----Gets the value of the BarColor property. ----@param self Slider self ----@return color gray Color of the slider track -function Slider:getBarColor(self) end +---Gets the value of the EmptyText property. +---@param self List self +---@return string "No items" Text to display when the list is empty +function List:getEmptyText(self) end ----Sets the value of the Max property. ----@param self Slider self ----@param Max number Maximum value for value conversion (maps slider position to this range) -function Slider:setMax(self, Max) end +---Gets the value of the ShowScrollBar property. +---@param self List self +---@return boolean true Whether to show the scrollbar when items exceed height +function List:getShowScrollBar(self) end ----Gets the value of the Horizontal property. ----@param self Slider self ----@return boolean true Whether the slider is horizontal (false for vertical) -function Slider:getHorizontal(self) end +---Gets the value of the ScrollBarColor property. +---@param self List self +---@return color lightGray Color of the scrollbar handle +function List:getScrollBarColor(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function List:render() end + +---Sets the value of the ScrollBarColor property. +---@param self List self +---@param ScrollBarColor color Color of the scrollbar handle +function List:setScrollBarColor(self, ScrollBarColor) end + +---Scrolls to make a specific item visible +---@param index number The index of the item to scroll to +---@return List self The List instance +function List:scrollToItem(index) end + +---Sets the value of the Offset property. +---@param self List self +---@param Offset number Current scroll offset for viewing long lists +function List:setOffset(self, Offset) end + +---Handles key events for keyboard navigation +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param keyCode number The key code +---@return boolean Whether the event was handled +---@protected +function List:key(keyCode) end + +---Scrolls the list to the top +---@return List self The List instance +function List:scrollToTop() end + +---Sets the value of the EmptyText property. +---@param self List self +---@param EmptyText string items" Text to display when the list is empty +function List:setEmptyText(self, EmptyText) end + +---Gets the value of the ScrollBarSymbol property. +---@param self List self +---@return string " " Symbol used for the scrollbar handle +function List:getScrollBarSymbol(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button being dragged +---@param x number The x-coordinate of the drag +---@param y number The y-coordinate of the drag +---@return boolean Whether the event was handled +---@protected +function List:mouse_drag(button, x, y) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The mouse button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled +---@param x number The x-coordinate of the click +---@param y number The y-coordinate of the click +---@return boolean Whether the event was handled ---@protected -function Slider:mouse_click(button, x, y) end +function List:mouse_click(button, x, y) end ----Gets the value of the Max property. ----@param self Slider self ----@return number 100 Maximum value for value conversion (maps slider position to this range) -function Slider:getMax(self) end +---Gets the value of the Offset property. +---@param self List self +---@return number 0 Current scroll offset for viewing long lists +function List:getOffset(self) end ----Sets the value of the Step property. ----@param self Slider self ----@param Step number Current position of the slider handle (1 to width/height) -function Slider:setStep(self, Step) end +---Registers a callback for the select event +---@param callback function The callback function to register +---@return List self The List instance +function List:onSelect(callback) end ----Sets the value of the BarColor property. ----@param self Slider self ----@param BarColor color Color of the slider track -function Slider:setBarColor(self, BarColor) end - ----Gets the value of the SliderColor property. ----@param self Slider self ----@return color blue Color of the slider handle -function Slider:getSliderColor(self) end - ----@class ProgressBar : VisualElement ----@field progress number Current progress value (0-100) ----@field showPercentage boolean Whether to show the percentage text in the center ----@field progressColor color The color used for the filled portion of the progress bar ----@field direction string The direction of the progress bar ("up", "down", "left", "right") -local ProgressBar = {} +---Gets the value of the ScrollBarBackground property. +---@param self List self +---@return string "\127" Symbol used for the scrollbar background +function List:getScrollBarBackground(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The direction of the scroll (1 for down, -1 for up) +---@param x number The x-coordinate of the scroll +---@param y number The y-coordinate of the scroll +---@return boolean Whether the event was handled ---@protected -function ProgressBar:render() end +function List:mouse_scroll(direction, x, y) end ----Gets the value of the Progress property. ----@param self ProgressBar self ----@return number 0 Current progress value (0-100) -function ProgressBar:getProgress(self) end +---Sets the value of the ScrollBarBackgroundColor property. +---@param self List self +---@param ScrollBarBackgroundColor color Background color of the scrollbar +function List:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end ----Gets the value of the ProgressColor property. ----@param self ProgressBar self ----@return color lime The color used for the filled portion of the progress bar -function ProgressBar:getProgressColor(self) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was released +---@param x number The x-coordinate of the release +---@param y number The y-coordinate of the release +---@return boolean Whether the event was handled +---@protected +function List:mouse_up(button, x, y) end ----Sets the value of the Progress property. ----@param self ProgressBar self ----@param Progress number Current progress value (0-100) -function ProgressBar:setProgress(self, Progress) end +---Sets the value of the ShowScrollBar property. +---@param self List self +---@param ShowScrollBar boolean Whether to show the scrollbar when items exceed height +function List:setShowScrollBar(self, ShowScrollBar) end ----Gets the value of the ShowPercentage property. ----@param self ProgressBar self ----@return boolean false Whether to show the percentage text in the center -function ProgressBar:getShowPercentage(self) end +---Scrolls the list to the bottom +---@return List self The List instance +function List:scrollToBottom() end ----Sets the value of the ShowPercentage property. ----@param self ProgressBar self ----@param ShowPercentage boolean Whether to show the percentage text in the center -function ProgressBar:setShowPercentage(self, ShowPercentage) end - ----Gets the value of the Direction property. ----@param self ProgressBar self ----@return string right The direction of the progress bar ("up", "down", "left", "right") -function ProgressBar:getDirection(self) end +---Sets the value of the ScrollBarSymbol property. +---@param self List self +---@param ScrollBarSymbol string " Symbol used for the scrollbar handle +function List:setScrollBarSymbol(self, ScrollBarSymbol) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with ---@param basalt table The basalt instance ----@return ProgressBar self The initialized instance +---@return List self The initialized instance ---@protected -function ProgressBar:init(props, basalt) end +function List:init(props, basalt) end ----Sets the value of the ProgressColor property. ----@param self ProgressBar self ----@param ProgressColor color The color used for the filled portion of the progress bar -function ProgressBar:setProgressColor(self, ProgressColor) end +---@class ElementManager +local ElementManager = {} ----Sets the value of the Direction property. ----@param self ProgressBar self ----@param Direction string The direction of the progress bar ("up", "down", "left", "right") -function ProgressBar:setDirection(self, Direction) end +---Loads an element by name. This will load the element and apply any plugins to it. +---@param name string The name of the element to load +function ElementManager.loadElement(name) end ----@class Timer : BaseElement ----@field amount number The amount of time the timer should run. ----@field interval number The interval in seconds at which the timer will trigger its action. ----@field action function The action to be performed when the timer triggers. ----@field running boolean Indicates whether the timer is currently running or not. -local Timer = {} +---Tries to load an element from any available source +---@param name string The element name +---@return boolean success Whether the element was loaded +function ElementManager.tryAutoLoad(name) end ----Stops the timer if it is currently running. ----@param self Timer The Timer instance to stop ----@return Timer self The Timer instance -function Timer:stop(self) end +---Checks if an element exists (is registered) +---@param name string The element name +---@return boolean exists Whether the element exists +function ElementManager.hasElement(name) end + +---Checks if an element is loaded +---@param name string The element name +---@return boolean loaded Whether the element is loaded +function ElementManager.isElementLoaded(name) end + +---Clears the global cache (_G) +function ElementManager.clearGlobalCache() end + +---Configures the ElementManager +---@param config table Configuration options +function ElementManager.configure(config) end + +---Preloads elements into the global cache +---@param elementNames table List of element names to preload +function ElementManager.preloadElements(elementNames) end + +---Gets an element by name. If the element is not loaded, it will try to load it first. +---@param name string The name of the element to get +---@return table Element The element class +function ElementManager.getElement(name) end + +---Gets an Plugin API by name +---@param name string The name of the API to get +---@return table API The API +function ElementManager.getAPI(name) end + +---Gets cache statistics +---@return table stats Cache statistics with size and element names +function ElementManager.getCacheStats() end + +---Gets a list of all elements +---@return table ElementList A list of all elements +function ElementManager.getElementList() end + +---Registers a remote source for an element +---@param elementName string The name of the element +---@param url string The URL to load the element from +function ElementManager.registerRemoteSource(elementName, url) end + +---Registers a disk mount point for loading elements +---@param mountPath string The path to the disk mount +function ElementManager.registerDiskMount(mountPath) end + +---@class Program : VisualElement +---@field program table The program instance +---@field running boolean Whether the program is running +---@field path string The path to the program +---@field doneCallback function The done callback function +---@field errorCallback function The error callback function +local Program = {} + +---Sets the value of the DoneCallback property. +---@param self Program self +---@param DoneCallback function The done callback function +function Program:setDoneCallback(self, DoneCallback) end + +function BasaltProgram:setArgs() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Program self The initialized instance +---@protected +function Program:init(props, basalt) end + +---Executes a program +---@param path string The path to the program +---@return Program self The Program instance +function Program:execute(path) end + +---Sets the value of the ErrorCallback property. +---@param self Program self +---@param ErrorCallback function The error callback function +function Program:setErrorCallback(self, ErrorCallback) end + +---Sets the value of the Program property. +---@param self Program self +---@param Program table The program instance +function Program:setProgram(self, Program) end + +---Registers a callback for the program's done event +---@param fn function The callback function to register +---@return Program self The Program instance +function Program:onDone(fn) end + +---Registers a callback for the program's error event, if the function returns false, the program won't stop +---@param fn function The callback function to register +---@return Program self The Program instance +function Program:onError(fn) end + +---Sends an event to the program +---@param event string The event to send +---@return Program self The Program instance +function Program:sendEvent(event) end + +---Gets the value of the Program property. +---@param self Program self +---@return table nil The program instance +function Program:getProgram(self) end + +---Gets the value of the Path property. +---@param self Program self +---@return string "" The path to the program +function Program:getPath(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Program:focus() end + +---Gets the value of the ErrorCallback property. +---@param self Program self +---@return function nil The error callback function +function Program:getErrorCallback(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Program:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return any result The event result +---@protected +function Program:dispatchEvent(event) end + +---Stops the program +---@return Program self The Program instance +function Program:stop() end + +---Sets the value of the Path property. +---@param self Program self +---@param Path string The path to the program +function Program:setPath(self, Path) end + +---Sets the value of the Running property. +---@param self Program self +---@param Running boolean Whether the program is running +function Program:setRunning(self, Running) end ---Gets the value of the Running property. ----@param self Timer self ----@return boolean false Indicates whether the timer is currently running or not. -function Timer:getRunning(self) end +---@param self Program self +---@return boolean false Whether the program is running +function Program:getRunning(self) end ----Gets the value of the Interval property. ----@param self Timer self ----@return number 1 The interval in seconds at which the timer will trigger its action. -function Timer:getInterval(self) end +---Gets the value of the DoneCallback property. +---@param self Program self +---@return function nil The done callback function +function Program:getDoneCallback(self) end ----Starts the timer with the specified interval. ----@param self Timer The Timer instance to start ----@return Timer self The Timer instance -function Timer:start(self) end +---@class Timer : BaseElement +---@field action function The action to be performed when the timer triggers. +---@field interval number The interval in seconds at which the timer will trigger its action. +---@field running boolean Indicates whether the timer is currently running or not. +---@field amount number The amount of time the timer should run. +local Timer = {} ---Sets the value of the Action property. ---@param self Timer self ---@param Action function The action to be performed when the timer triggers. function Timer:setAction(self, Action) end ----Gets the value of the Action property. ----@param self Timer self ----@return function function The action to be performed when the timer triggers. -function Timer:getAction(self) end +---Stops the timer if it is currently running. +---@param self Timer The Timer instance to stop +---@return Timer self The Timer instance +function Timer:stop(self) end ---Gets the value of the Amount property. ---@param self Timer self ---@return number -1 The amount of time the timer should run. function Timer:getAmount(self) end +---Gets the value of the Running property. +---@param self Timer self +---@return boolean false Indicates whether the timer is currently running or not. +function Timer:getRunning(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Timer:dispatchEvent() end + +---Gets the value of the Action property. +---@param self Timer self +---@return function function The action to be performed when the timer triggers. +function Timer:getAction(self) end + +---Starts the timer with the specified interval. +---@param self Timer The Timer instance to start +---@return Timer self The Timer instance +function Timer:start(self) end + ---Sets the value of the Running property. ---@param self Timer self ---@param Running boolean Indicates whether the timer is currently running or not. function Timer:setRunning(self, Running) end +---Gets the value of the Interval property. +---@param self Timer self +---@return number 1 The interval in seconds at which the timer will trigger its action. +function Timer:getInterval(self) end + ---Sets the value of the Interval property. ---@param self Timer self ---@param Interval number The interval in seconds at which the timer will trigger its action. @@ -3941,119 +875,209 @@ function Timer:init(props, basalt) end ---@param Amount number The amount of time the timer should run. function Timer:setAmount(self, Amount) end +---@class BaseFrame : Container +---@field term term term.current() The terminal or (monitor) peripheral object to render to +local BaseFrame = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was released +---@protected +function BaseFrame:key_up(key) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param fg colors The foreground color +---@protected +function BaseFrame:drawFg(x, y, fg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@param bg colors The background color +---@protected +function BaseFrame:textBg(x, y, text, bg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param width number The width of the text +---@param height number The height of the text +---@param text string The text to render +---@param fg string The foreground color +---@param bg string The background color +---@protected +function BaseFrame:multiBlit(x, y, width, height, text, fg, bg) end + ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected -function Timer:dispatchEvent() end +function BaseFrame:term_resize() end ----@class Dialog : Frame ----@field modal boolean If true, blocks all events outside the dialog ----@field secondaryColor color Secondary button color (Cancel, dismiss actions) ----@field buttonForeground color Foreground color for buttons ----@field primaryColor color Primary button color (OK, confirm actions) ----@field title string The dialog title -local Dialog = {} +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return table self The initialized instance +---@protected +function BaseFrame:init(props, basalt) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@protected +function BaseFrame:drawText(x, y, text) end + +---Gets the value of the Term property. +---@param self BaseFrame self +---@return term |peripheral term.current() The terminal or (monitor) peripheral object to render to +function BaseFrame:getTerm(self) end ----Handles mouse drag events ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected -function Dialog:mouse_drag() end +function BaseFrame:render() end ----Gets the value of the SecondaryColor property. ----@param self Dialog self ----@return color lightGray Secondary button color (Cancel, dismiss actions) -function Dialog:getSecondaryColor(self) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was released +---@param x number The x position of the mouse +---@param y number The y position of the mouse +---@protected +function BaseFrame:mouse_up(button, x, y) end ----Sets the value of the PrimaryColor property. ----@param self Dialog self ----@param PrimaryColor color Primary button color (OK, confirm actions) -function Dialog:setPrimaryColor(self, PrimaryColor) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was pressed +---@protected +function BaseFrame:key(key) end ----Closes the dialog ----@return Dialog self The Dialog instance -function Dialog:close() end +---Sets the cursor position +---@param x number The x position to set the cursor to +---@param y number The y position to set the cursor to +---@param blink boolean Whether the cursor should blink +function BaseFrame:setCursor(x, y, blink) end ----Gets the value of the Modal property. ----@param self Dialog self ----@return boolean true If true, blocks all events outside the dialog -function Dialog:getModal(self) end +---Hides the debug log frame +---@param self BaseFrame The frame to hide debug log for +function BaseFrame.closeConsole(self) end ----Creates a prompt dialog with input ----@param title string The dialog title ----@param message string The prompt message ----@return Dialog self The Dialog instance -function Dialog:prompt(title, message) end +function BaseFrame:dispatchEvent() end ----Sets the value of the ButtonForeground property. ----@param self Dialog self ----@param ButtonForeground color Foreground color for buttons -function Dialog:setButtonForeground(self, ButtonForeground) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param bg colors The background color +---@protected +function BaseFrame:drawBg(x, y, bg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@param fg string The foreground color +---@param bg string The background color +---@protected +function BaseFrame:blit(x, y, text, fg, bg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param name string The name of the monitor that was touched +---@param x number The x position of the mouse +---@param y number The y position of the mouse +---@protected +function BaseFrame:monitor_touch(name, x, y) end + +---Sets the value of the Term property. +---@param self BaseFrame self +---@param Term term term.current() The terminal or (monitor) peripheral object to render to +function BaseFrame:setTerm(self, Term) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was pressed +---@protected +function BaseFrame:char(char) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the mouse +---@param y number The y position of the mouse +---@protected +function BaseFrame:mouse_click(button, x, y) end + +---Toggles the debug log frame +---@param self BaseFrame The frame to toggle debug log for +function BaseFrame.toggleConsole(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@param fg colors The foreground color +---@protected +function BaseFrame:textFg(x, y, text, fg) end + +---Shows the debug log frame +---@param self BaseFrame The frame to show debug log in +function BaseFrame.openConsole(self) end + +---@class BigFontText +local BigFontText = {} + +---@class BigFont : VisualElement +---@field fontSize number Scale factor for text size (1-3, where 1 is 3x3 pixels per character) +---@field text string The text string to display in enlarged format +local BigFont = {} ----Handles mouse scroll events ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected -function Dialog:mouse_scroll() end +function BigFont:render() end ----Gets the value of the PrimaryColor property. ----@param self Dialog self ----@return color lime Primary button color (OK, confirm actions) -function Dialog:getPrimaryColor(self) end +---Gets the value of the Text property. +---@param self BigFont self +---@return string BigFont The text string to display in enlarged format +function BigFont:getText(self) end ----Sets the value of the Title property. ----@param self Dialog self ----@param Title string The dialog title -function Dialog:setTitle(self, Title) end - ----Gets the value of the ButtonForeground property. ----@param self Dialog self ----@return color black Foreground color for buttons -function Dialog:getButtonForeground(self) end - ----Shows the dialog ----@return Dialog self The Dialog instance -function Dialog:show() end - ----Handles mouse up events ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance ---@protected -function Dialog:mouse_up() end +function BigFont:init(props, basalt) end ----Creates a confirm dialog ----@param title string The dialog title ----@param message string The confirmation message ----@param callback function Callback (receives boolean result) ----@return Dialog self The Dialog instance -function Dialog:confirm(title, message, callback) end +---Sets the value of the FontSize property. +---@param self BigFont self +---@param FontSize number Scale factor for text size (1-3, where 1 is 3x3 pixels per character) +function BigFont:setFontSize(self, FontSize) end ----Sets the value of the SecondaryColor property. ----@param self Dialog self ----@param SecondaryColor color Secondary button color (Cancel, dismiss actions) -function Dialog:setSecondaryColor(self, SecondaryColor) end +---Gets the value of the FontSize property. +---@param self BigFont self +---@return number 1 Scale factor for text size (1-3, where 1 is 3x3 pixels per character) +function BigFont:getFontSize(self) end ----Gets the value of the Title property. ----@param self Dialog self ----@return string "" The dialog title -function Dialog:getTitle(self) end +---Sets the value of the Text property. +---@param self BigFont self +---@param Text string The text string to display in enlarged format +function BigFont:setText(self, Text) end ----Sets the value of the Modal property. ----@param self Dialog self ----@param Modal boolean If true, blocks all events outside the dialog -function Dialog:setModal(self, Modal) end +---@class AnimationInstance +local AnimationInstance = {} ----Creates a simple alert dialog ----@param title string The alert title ----@param message string The alert message ----@return Dialog self The Dialog instance -function Dialog:alert(title, message) end +---Gets called when the animation is completed +function AnimationInstance:complete() end ----Handles mouse click events ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Dialog:mouse_click() end +---Updates the animation +---@param elapsed number The elapsed time in seconds +---@return boolean Whether the animation is finished +function AnimationInstance:update(elapsed) end ----Renders the dialog ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Dialog:render() end +---Creates a new AnimationInstance +---@param element VisualElement The element to animate +---@param animType string The type of animation +---@param args table The animation arguments +---@param duration number Duration in seconds +---@param easing string The easing function name +---@return AnimationInstance The new animation instance +function AnimationInstance.new(element, animType, args, duration, easing) end + +---Starts the animation +---@return AnimationInstance self The animation instance +function AnimationInstance:start() end ---@class LineChart : Graph local LineChart = {} @@ -4069,16 +1093,1811 @@ function LineChart:init(props, basalt) end ---@protected function LineChart:render() end +---@class PropertySystem +local PropertySystem = {} + +---Creates an element from a blueprint +---@param elementClass table The element class to create from the blueprint +---@param blueprint table The blueprint to create the element from +---@return table element The created element +function PropertySystem.createFromBlueprint(elementClass, blueprint) end + +---Removes an observer from a property +---@param name string The name of the property +---@param callback function The callback function to remove +---@return table self The PropertySystem +function PropertySystem:removeObserver(name, callback) end + +---Defines a property for an element class +---@param class table The element class to define the property for +---@param name string The name of the property +---@param config table The configuration of the property +function PropertySystem.defineProperty(class, name, config) end + +---Creates a blueprint of an element class with all its properties +---@param elementClass table The element class to create a blueprint from +---@return table blueprint A table containing all property definitions +function PropertySystem.blueprint(elementClass) end + +---Combines multiple properties into a single getter and setter +---@param class table The element class to combine the properties for +---@param name string The name of the combined property +function PropertySystem.combineProperties(class, name) end + +---Update call for a property IS USED INTERNALLY +---@param name string The name of the property +---@param value any The value of the property +---@return table self The PropertySystem +function PropertySystem:_updateProperty(name, value) end + +---Adds a property to the PropertySystem on instance level +---@param name string The name of the property +---@param config table The configuration of the property +---@return table self The PropertySystem +function PropertySystem:instanceProperty(name, config) end + +---Adds a setter hook to the PropertySystem. Setter hooks are functions that are called before a property is set. +---@param hook function The hook function to add +function PropertySystem.addSetterHook(hook) end + +---Initializes the PropertySystem IS USED INTERNALLY +---@return table self The PropertySystem +function PropertySystem:__init() end + +---Removes a property from the PropertySystem on instance level +---@param name string The name of the property +---@return table self The PropertySystem +function PropertySystem:removeProperty(name) end + +---Gets a property configuration +---@param name string The name of the property +---@return table config The configuration of the property +function PropertySystem:getPropertyConfig(name) end + +---Observers a property +---@param name string The name of the property +---@param callback function The callback function to call when the property changes +---@return table self The PropertySystem +function PropertySystem:observe(name, callback) end + +---Removes all observers from a property +---@return table self The PropertySystem +function PropertySystem:removeAllObservers() end + +---@class ComboBox : DropDown +---@field viewOffset number Horizontal scroll position for viewing long text +---@field manuallyOpened boolean Indicates if dropdown was opened by user action +---@field autoComplete boolean Enables filtering dropdown items while typing +---@field editable boolean Enables direct text input in the field +---@field text string The current text value of the input field +---@field cursorPos number Current cursor position in the text input +local ComboBox = {} + +---Handles mouse clicks +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button (1 = left, 2 = right, 3 = middle) +---@param x number The x coordinate of the click +---@param y number The y coordinate of the click +---@return boolean handled Whether the event was handled +---@protected +function ComboBox:mouse_click(button, x, y) end + +---Gets the value of the CursorPos property. +---@param self ComboBox self +---@return number 1 Current cursor position in the text input +function ComboBox:getCursorPos(self) end + +---Gets the value of the ViewOffset property. +---@param self ComboBox self +---@return number 0 Horizontal scroll position for viewing long text +function ComboBox:getViewOffset(self) end + +---Creates a new ComboBox instance +---@return ComboBox self The newly created ComboBox instance +function ComboBox.new() end + +---Gets the value of the Editable property. +---@param self ComboBox self +---@return boolean true Enables direct text input in the field +function ComboBox:getEditable(self) end + +---Handles character input when editable +---@param char string The character that was typed +function ComboBox:char(char) end + +---Handles key input when editable +---@param key number The key code that was pressed +---@param held boolean Whether the key is being held +function ComboBox:key(key, held) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return ComboBox self The initialized instance +---@protected +function ComboBox:init(props, basalt) end + +---Handles mouse up events for item selection +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was released +---@param x number The x-coordinate of the release +---@param y number The y-coordinate of the release +---@return boolean handled Whether the event was handled +---@protected +function ComboBox:mouse_up(button, x, y) end + +---Renders the ComboBox +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function ComboBox:render() end + +---Gets the value of the AutoComplete property. +---@param self ComboBox self +---@return boolean false Enables filtering dropdown items while typing +function ComboBox:getAutoComplete(self) end + +---Gets the value of the ManuallyOpened property. +---@param self ComboBox self +---@return boolean false Indicates if dropdown was opened by user action +function ComboBox:getManuallyOpened(self) end + +---Gets the value of the Text property. +---@param self ComboBox self +---@return string "" The current text value of the input field +function ComboBox:getText(self) end + +---Sets the value of the ViewOffset property. +---@param self ComboBox self +---@param ViewOffset number Horizontal scroll position for viewing long text +function ComboBox:setViewOffset(self, ViewOffset) end + +---Sets the value of the Text property. +---@param self ComboBox self +---@param Text string The current text value of the input field +function ComboBox:setText(self, Text) end + +---Sets the value of the CursorPos property. +---@param self ComboBox self +---@param CursorPos number Current cursor position in the text input +function ComboBox:setCursorPos(self, CursorPos) end + +---Sets the value of the AutoComplete property. +---@param self ComboBox self +---@param AutoComplete boolean Enables filtering dropdown items while typing +function ComboBox:setAutoComplete(self, AutoComplete) end + +---Sets the value of the ManuallyOpened property. +---@param self ComboBox self +---@param ManuallyOpened boolean Indicates if dropdown was opened by user action +function ComboBox:setManuallyOpened(self, ManuallyOpened) end + +---Sets the value of the Editable property. +---@param self ComboBox self +---@param Editable boolean Enables direct text input in the field +function ComboBox:setEditable(self, Editable) end + +---@class Collection : VisualElement +---@field selectedBackground color Background color for selected items +---@field multiSelection boolean Whether multiple items can be selected at once +---@field selectedForeground color Text color for selected items +---@field selectable boolean Whether items can be selected +local Collection = {} + +---Gets the currently selected items +---@return table selected Collection of selected items +function Collection:getSelectedItems() end + +---Gets the value of the MultiSelection property. +---@param self Collection self +---@return boolean false Whether multiple items can be selected at once +function Collection:getMultiSelection(self) end + +---Adds an item to the Collection +---@param text string |table The item to add (string or item table) +---@return Collection self The Collection instance +function Collection:addItem(text) end + +function Collection:selectItem() end + +---Sets the value of the SelectedForeground property. +---@param self Collection self +---@param SelectedForeground color Text color for selected items +function Collection:setSelectedForeground(self, SelectedForeground) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Collection self The initialized instance +---@protected +function Collection:init(props, basalt) end + +---Sets the value of the SelectedBackground property. +---@param self Collection self +---@param SelectedBackground color Background color for selected items +function Collection:setSelectedBackground(self, SelectedBackground) end + +---Sets the value of the Selectable property. +---@param self Collection self +---@param Selectable boolean Whether items can be selected +function Collection:setSelectable(self, Selectable) end + +---Gets first selected item +---@return table ? selected The first item +function Collection:getSelectedItem() end + +---Gets the value of the SelectedBackground property. +---@param self Collection self +---@return color blue Background color for selected items +function Collection:getSelectedBackground(self) end + +---Registers a callback for the select event +---@param callback function The callback function to register +---@return Collection self The Collection instance +function Collection:onSelect(callback) end + +---Clears all items from the Collection +---@return Collection self The Collection instance +function Collection:clear() end + +---Selects the previous item in the collection +---@return Collection self The Collection instance +function Collection:selectPrevious() end + +function Collection:unselectItem() end + +---Gets the value of the SelectedForeground property. +---@param self Collection self +---@return color white Text color for selected items +function Collection:getSelectedForeground(self) end + +---Gets the index of the first selected item +---@return number ? index The index of the first selected item, or nil if none selected +function Collection:getSelectedIndex() end + +function Collection:clearItemSelection() end + +---Selects the next item in the collection +---@return Collection self The Collection instance +function Collection:selectNext() end + +---Removes an item from the Collection +---@param index number The index of the item to remove +---@return Collection self The Collection instance +function Collection:removeItem(index) end + +---Registers a function to handle the onSelect event. +---@param index number +---@param item table +---@param self Collection self +---@param func function The function to be called when the event fires +function Collection:onOnSelect(self, func) end + +---Sets the value of the MultiSelection property. +---@param self Collection self +---@param MultiSelection boolean Whether multiple items can be selected at once +function Collection:setMultiSelection(self, MultiSelection) end + +---Gets the value of the Selectable property. +---@param self Collection self +---@return boolean true Whether items can be selected +function Collection:getSelectable(self) end + +---@class Input : VisualElement +---@field viewOffset number The horizontal scroll offset for viewing long text +---@field placeholderColor color Color of the placeholder text +---@field maxLength number nil Maximum length of input text (optional) +---@field pattern string nil Regular expression pattern for input validation +---@field placeholder string Text to display when input is empty +---@field cursorPos number The current cursor position in the text +---@field text string The current text content of the input +---@field cursorColor number Color of the cursor +---@field replaceChar string Character to replace the input with (for password fields) +local Input = {} + +---Sets the value of the PlaceholderColor property. +---@param self Input self +---@param PlaceholderColor color Color of the placeholder text +function Input:setPlaceholderColor(self, PlaceholderColor) end + +---Updates the input's viewport +---@return Input self The updated instance +function Input:updateViewport() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:render() end + +---Sets the value of the CursorPos property. +---@param self Input self +---@param CursorPos number The current cursor position in the text +function Input:setCursorPos(self, CursorPos) end + +---Sets the value of the MaxLength property. +---@param self Input self +---@param MaxLength number nil Maximum length of input text (optional) +function Input:setMaxLength(self, MaxLength) end + +---Sets the cursor position and color +---@param x number The x position of the cursor +---@param y number The y position of the cursor +---@param blink boolean Whether the cursor should blink +---@param color number The color of the cursor +function Input:setCursor(x, y, blink, color) end + +---Gets the value of the CursorPos property. +---@param self Input self +---@return number 1 The current cursor position in the text +function Input:getCursorPos(self) end + +---Sets the value of the Text property. +---@param self Input self +---@param Text string The current text content of the input +function Input:setText(self, Text) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was typed +---@return boolean handled Whether the event was handled +---@protected +function Input:char(char) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:paste() end + +---Sets the value of the CursorColor property. +---@param self Input self +---@param CursorColor number Color of the cursor +function Input:setCursorColor(self, CursorColor) end + +---Sets the value of the Pattern property. +---@param self Input self +---@param Pattern string nil Regular expression pattern for input validation +function Input:setPattern(self, Pattern) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:blur() end + +---Sets the value of the ViewOffset property. +---@param self Input self +---@param ViewOffset number The horizontal scroll offset for viewing long text +function Input:setViewOffset(self, ViewOffset) end + +---Gets the value of the CursorColor property. +---@param self Input self +---@return number nil Color of the cursor +function Input:getCursorColor(self) end + +---Gets the value of the Placeholder property. +---@param self Input self +---@return string ... Text to display when input is empty +function Input:getPlaceholder(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:focus() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Input:mouse_click(button, x, y) end + +---Gets the value of the ReplaceChar property. +---@param self Input self +---@return string nil Character to replace the input with (for password fields) +function Input:getReplaceChar(self) end + +---Gets the value of the ViewOffset property. +---@param self Input self +---@return number 0 The horizontal scroll offset for viewing long text +function Input:getViewOffset(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was pressed +---@return boolean handled Whether the event was handled +---@protected +function Input:key(key) end + +---Sets the value of the ReplaceChar property. +---@param self Input self +---@param ReplaceChar string Character to replace the input with (for password fields) +function Input:setReplaceChar(self, ReplaceChar) end + +---Gets the value of the PlaceholderColor property. +---@param self Input self +---@return color gray Color of the placeholder text +function Input:getPlaceholderColor(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Input self The initialized instance +---@protected +function Input:init(props, basalt) end + +---Gets the value of the Pattern property. +---@param self Input self +---@return string ? nil Regular expression pattern for input validation +function Input:getPattern(self) end + +---Gets the value of the Text property. +---@param self Input self +---@return string - The current text content of the input +function Input:getText(self) end + +---Gets the value of the MaxLength property. +---@param self Input self +---@return number ? nil Maximum length of input text (optional) +function Input:getMaxLength(self) end + +---Sets the value of the Placeholder property. +---@param self Input self +---@param Placeholder string Text to display when input is empty +function Input:setPlaceholder(self, Placeholder) end + +---@class Image : VisualElement +---@field currentFrame number Current animation frame +---@field offsetX number Horizontal offset for viewing larger images +---@field offsetY number Vertical offset for viewing larger images +---@field bimg table The bimg image data +---@field autoResize boolean Whether to automatically resize the image when content exceeds bounds +local Image = {} + +---Adds a new frame to the image +---@return Image self The Image instance +function Image:addFrame() end + +---Gets the value of the Bimg property. +---@param self Image self +---@return table {} The bimg image data +function Image:getBimg(self) end + +---Updates the specified frame with the provided data +---@param frameIndex number The index of the frame to update +---@param frame table The new frame data +---@return Image self The Image instance +function Image:updateFrame(frameIndex, frame) end + +---Sets the foreground color at the specified position +---@param x number The x position +---@param y number The y position +---@param pattern string The foreground color pattern +---@return Image self The Image instance +function Image:setFg(x, y, pattern) end + +---Gets pixel information at position +---@param x number X position +---@param y number Y position +---@return number ? fg Foreground color +---@return number ? bg Background color +---@return string ? char Character at position +function Image:getPixelData(x, y) end + +---Gets the value of the OffsetY property. +---@param self Image self +---@return number 0 Vertical offset for viewing larger images +function Image:getOffsetY(self) end + +---Gets the foreground color at the specified position +---@param x number The x position +---@param y number The y position +---@param length number The length of the foreground color pattern to get +---@return string fg The foreground color pattern +function Image:getFg(x, y, length) end + +---Gets the value of the AutoResize property. +---@param self Image self +---@return boolean false Whether to automatically resize the image when content exceeds bounds +function Image:getAutoResize(self) end + +---Gets the size of the image +---@return number width The width of the image +---@return number height The height of the image +function Image:getImageSize() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Image:render() end + +---Sets the value of the AutoResize property. +---@param self Image self +---@param AutoResize boolean Whether to automatically resize the image when content exceeds bounds +function Image:setAutoResize(self, AutoResize) end + +---Sets the metadata of the image +---@param key string The key of the metadata to set +---@param value string The value of the metadata to set +---@return Image self The Image instance +function Image:setMetadata(key, value) end + +---Gets the text at the specified position +---@param x number The x position +---@param y number The y position +---@param length number The length of the text to get +---@return string text The text at the specified position +function Image:getText(x, y, length) end + +---Gets the value of the CurrentFrame property. +---@param self Image self +---@return number 1 Current animation frame +function Image:getCurrentFrame(self) end + +---Gets the metadata of the image +---@return table metadata The metadata of the image +function Image:getMetadata() end + +---Sets the value of the CurrentFrame property. +---@param self Image self +---@param CurrentFrame number Current animation frame +function Image:setCurrentFrame(self, CurrentFrame) end + +---Sets the value of the Bimg property. +---@param self Image self +---@param Bimg table The bimg image data +function Image:setBimg(self, Bimg) end + +---Advances to the next frame in the animation +---@return Image self The Image instance +function Image:nextFrame() end + +---Sets the pixel at the specified position +---@param x number The x position +---@param y number The y position +---@param char string The character to set +---@param fg string The foreground color pattern +---@param bg string The background color pattern +---@return Image self The Image instance +function Image:setPixel(x, y, char, fg, bg) end + +---Gets the background color at the specified position +---@param x number The x position +---@param y number The y position +---@param length number The length of the background color pattern to get +---@return string bg The background color pattern +function Image:getBg(x, y, length) end + +---Sets the background color at the specified position +---@param x number The x position +---@param y number The y position +---@param pattern string The background color pattern +---@return Image self The Image instance +function Image:setBg(x, y, pattern) end + +---Sets the text at the specified position +---@param x number The x position +---@param y number The y position +---@param text string The text to set +---@return Image self The Image instance +function Image:setText(x, y, text) end + +---Sets the value of the OffsetX property. +---@param self Image self +---@param OffsetX number Horizontal offset for viewing larger images +function Image:setOffsetX(self, OffsetX) end + +---Gets the specified frame +---@param frameIndex number The index of the frame to get +---@return table frame The frame data +function Image:getFrame(frameIndex) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Image self The initialized instance +---@protected +function Image:init(props, basalt) end + +---Gets the value of the OffsetX property. +---@param self Image self +---@return number 0 Horizontal offset for viewing larger images +function Image:getOffsetX(self) end + +---Resizes the image to the specified width and height +---@param width number The new width of the image +---@param height number The new height of the image +---@return Image self The Image instance +function Image:resizeImage(width, height) end + +---Sets the value of the OffsetY property. +---@param self Image self +---@param OffsetY number Vertical offset for viewing larger images +function Image:setOffsetY(self, OffsetY) end + +---@class BarChart : Graph +local BarChart = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return BarChart self The initialized instance +---@protected +function BarChart:init(props, basalt) end + +---Renders the bar chart by calculating bar positions and heights based on data values +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function BarChart:render() end + +---@class Slider : VisualElement +---@field horizontal boolean Whether the slider is horizontal (false for vertical) +---@field max number Maximum value for value conversion (maps slider position to this range) +---@field step number Current position of the slider handle (1 to width/height) +---@field barColor color Color of the slider track +---@field sliderColor color Color of the slider handle +local Slider = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Slider:mouse_click(button, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Slider:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Slider self The initialized instance +---@protected +function Slider:init(props, basalt) end + +---Sets the value of the BarColor property. +---@param self Slider self +---@param BarColor color Color of the slider track +function Slider:setBarColor(self, BarColor) end + +---Gets the value of the BarColor property. +---@param self Slider self +---@return color gray Color of the slider track +function Slider:getBarColor(self) end + +---Gets the current value of the slider +---@return number value The current value (0 to max) +function Slider:getValue() end + +---Gets the value of the Horizontal property. +---@param self Slider self +---@return boolean true Whether the slider is horizontal (false for vertical) +function Slider:getHorizontal(self) end + +---Registers a function to handle the onChange event. +---@param value number +---@param self Slider self +---@param func function The function to be called when the event fires +function Slider:onOnChange(self, func) end + +---Sets the value of the Max property. +---@param self Slider self +---@param Max number Maximum value for value conversion (maps slider position to this range) +function Slider:setMax(self, Max) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was released +---@param x number The x position of the release +---@param y number The y position of the release +---@return boolean handled Whether the event was handled +---@protected +function Slider:mouse_scroll(button, x, y) end + +---Sets the value of the SliderColor property. +---@param self Slider self +---@param SliderColor color Color of the slider handle +function Slider:setSliderColor(self, SliderColor) end + +---Sets the value of the Horizontal property. +---@param self Slider self +---@param Horizontal boolean Whether the slider is horizontal (false for vertical) +function Slider:setHorizontal(self, Horizontal) end + +---Gets the value of the SliderColor property. +---@param self Slider self +---@return color blue Color of the slider handle +function Slider:getSliderColor(self) end + +---Gets the value of the Max property. +---@param self Slider self +---@return number 100 Maximum value for value conversion (maps slider position to this range) +function Slider:getMax(self) end + +---Sets the value of the Step property. +---@param self Slider self +---@param Step number Current position of the slider handle (1 to width/height) +function Slider:setStep(self, Step) end + +---Gets the value of the Step property. +---@param self Slider self +---@return number 1 Current position of the slider handle (1 to width/height) +function Slider:getStep(self) end + +---@class Log +local Log = {} + +---Sets if the logger should log to a file. +function Log.setLogToFile() end + +---Sends a debug message to the logger. +function Log.debug() end + +---Sets if the logger should log +function Log.setEnabled() end + +---Sends an error message to the logger. +function Log.error() end + +---Sends an info message to the logger. +function Log.info() end + +---Sends a warning message to the logger. +function Log.warn() end + +---@class basalt +local basalt = {} + +---Returns a Plugin API +---@param name string The name of the plugin +---@return table Plugin The plugin API +function basalt.getAPI(name) end + +---Requires specific elements and validates they are available +---@param elements table |string List of element names or single element name +function basalt.requireElements(elements) end + +---Returns the error manager instance +---@return table ErrorManager The error manager +function basalt.getErrorManager() end + +---Returns an element's class without creating a instance +---@param name string The name of the element +---@return table Element The element class +function basalt.getElementClass(name) end + +---Configures the ElementManager (shortcut to elementManager.configure) +---@param config table Configuration options +function basalt.configure(config) end + +---Gets or creates the main frame +---@return BaseFrame BaseFrame The main frame instance +function basalt.getMainFrame() end + +---Returns the active frame +---@return BaseFrame ? BaseFrame The frame to set as active +function basalt.getActiveFrame() end + +---Starts the Basalt runtime +function basalt.run() end + +---Stops the Basalt runtime +function basalt.stop() end + +---Returns the focused frame +---@return BaseFrame ? BaseFrame The focused frame +function basalt.getFocus() end + +---Creates and returns a new UI element of the specified type. +---@param type string The type of element to create (e.g. "Button", "Label", "BaseFrame") +---@return table element The created element instance +function basalt.create(type) end + +---Creates and returns a new BaseFrame +---@return BaseFrame BaseFrame The created frame instance +function basalt.createFrame() end + +---Installs an element interactively or from a specified source +---@param elementName string The name of the element to install +function basalt.install(elementName) end + +---Removes a callback function for a specific event +---@param eventName string The name of the event +---@param callback function The callback function to remove +---@return boolean success Whether the callback was found and removed +function basalt.removeEvent(eventName, callback) end + +---Returns the element manager instance +---@return table ElementManager The element manager +function basalt.getElementManager() end + +---Removes a scheduled update +---@param func thread The scheduled function to remove +---@return boolean success Whether the scheduled function was removed +function basalt.removeSchedule(func) end + +---Sets a frame as focused +---@param frame BaseFrame The frame to set as focused +function basalt.setFocus(frame) end + +---Loads a manifest file that describes element requirements and configuration +---@param path string The path to the manifest file +---@return table manifest The loaded manifest data +function basalt.loadManifest(path) end + +---Triggers a custom event and calls all registered callbacks +---@param eventName string The name of the event to trigger +function basalt.triggerEvent(eventName) end + +---Schedules a function to run in a coroutine +---@param func function The function to schedule +---@return thread func The scheduled function +function basalt.schedule(func) end + +---Registers a callback function for a specific event +---@param eventName string The name of the event to listen for (e.g. "mouse_click", "key", "timer") +---@param callback function The callback function to execute when the event occurs +function basalt.onEvent(eventName, callback) end + +---Runs basalt once, can be used to update the UI manually, but you have to feed it the events +function basalt.update() end + +---Sets the active frame +---@param frame BaseFrame The frame to set as active +function basalt.setActiveFrame(frame) end + +---@class BaseElement : PropertySystem +---@field name string User-defined name for the element +---@field type string A hierarchical identifier of the element's type chain +---@field enabled boolean Controls event processing for this element +---@field states table Table of currently active states with their priorities +---@field eventCallbacks table Collection of registered event handler functions +---@field id string Auto-generated unique identifier for element lookup +local BaseElement = {} + +---Dumps debug information for this element +---@param self BaseElement The element to dump debug info for +function BaseElement.dumpDebug(self) end + +---Gets the theme properties for this element +---@param self BaseElement The element to get theme for +---@return table styles The theme properties +function BaseElement:getTheme(self) end + +---Gets the value of the Type property. +---@param self BaseElement self +---@return string BaseElement A hierarchical identifier of the element's type chain +function BaseElement:getType(self) end + +---Defines a class-level event callback method with automatic event registration +---@param class table The class to register +---@param callbackName string The name of the callback to register +function BaseElement.registerEventCallback(class, callbackName) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return boolean ? handled Whether the event was handled +---@protected +function BaseElement:handleEvent(event) end + +---Sets the value of the States property. +---@param self BaseElement self +---@param States table Table of currently active states with their priorities +function BaseElement:setStates(self, States) end + +---Removes a state from the registry +---@param stateName string The state to remove +---@return BaseElement self +function BaseElement:unregisterState(stateName) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return boolean ? handled Whether the event was handled +---@protected +function BaseElement:dispatchEvent(event) end + +---Enables debugging for this element +---@param self BaseElement The element to debug +---@param level number The debug level +function BaseElement.debug(self, level) end + +---Manually deactivates a state +---@param stateName string The state to deactivate +---@return BaseElement self +function BaseElement:unsetState(stateName) end + +---Sets the value of the Id property. +---@param self BaseElement self +---@param Id string Auto-generated unique identifier for element lookup +function BaseElement:setId(self, Id) end + +---Removes the element from UI tree and cleans up resources +function BaseElement:destroy() end + +---Traverses parent chain to locate the root frame element +---@return BaseFrame BaseFrame The base frame of the element +function BaseElement:getBaseFrame() end + +---Stops benchmarking for a method +---@param methodName string The name of the method to stop benchmarking +---@return BaseElement self The element instance +function BaseElement:stopBenchmark(methodName) end + +---Applies the current theme to this element +---@param self BaseElement The element to apply theme to +---@param applyToChildren boolean ? Whether to apply theme to child elements (default: true) +---@return BaseElement self The element instance +function BaseElement:applyTheme(self, applyToChildren) end + +---Sets the value of the EventCallbacks property. +---@param self BaseElement self +---@param EventCallbacks table Collection of registered event handler functions +function BaseElement:setEventCallbacks(self, EventCallbacks) end + +---Sets up a property change observer with immediate callback registration +---@param property string The property to observe +---@param callback function The callback to call when the property changes +---@return table self The BaseElement instance +function BaseElement:onChange(property, callback) end + +---Gets all currently active states sorted by priority +---@return table states Array of {name, priority} sorted by priority +function BaseElement:getActiveStates() end + +---Executes all registered callbacks for the specified event +---@param event string The event to fire +---@return table self The BaseElement instance +function BaseElement:fireEvent(event) end + +---Gets the highest priority active state +---@return string |nil currentState The state with highest priority +function BaseElement:getCurrentState() end + +---Ends profiling a method +---@param methodName string The name of the method to stop profiling +---@return BaseElement self The element instance +function BaseElement:endProfile(methodName) end + +---Checks if a state is currently active +---@param stateName string The state to check +---@return boolean isActive +function BaseElement:hasState(stateName) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return table self The initialized instance +---@protected +function BaseElement:init(props, basalt) end + +---Propagates render request up the element tree +---@return table self The BaseElement instance +function BaseElement:updateRender() end + +---Gets the value of the EventCallbacks property. +---@param self BaseElement self +---@return table BaseElement Collection of registered event handler functions +function BaseElement:getEventCallbacks(self) end + +---Gets the value of the Enabled property. +---@param self BaseElement self +---@return boolean BaseElement Controls event processing for this element +function BaseElement:getEnabled(self) end + +---Registers a class-level event listener with optional dependency +---@param class table The class to register +---@param eventName string The name of the event to register +function BaseElement.defineEvent(class, eventName) end + +---Sets the value of the Name property. +---@param self BaseElement self +---@param Name string User-defined name for the element +function BaseElement:setName(self, Name) end + +---Adds an event handler function with automatic event registration +---@param event string The event to register the callback for +---@param callback function The callback function to register +---@return table self The BaseElement instance +function BaseElement:registerCallback(event, callback) end + +---Sets the value of the Type property. +---@param self BaseElement self +---@param Type string A hierarchical identifier of the element's type chain +function BaseElement:setType(self, Type) end + +---Enables benchmarking for a method +---@param methodName string The name of the method to benchmark +---@return BaseElement self The element instance +function BaseElement:benchmark(methodName) end + +---Sets the value of the Enabled property. +---@param self BaseElement self +---@param Enabled boolean Controls event processing for this element +function BaseElement:setEnabled(self, Enabled) end + +---Gets the value of the Name property. +---@param self BaseElement self +---@return string BaseElement User-defined name for the element +function BaseElement:getName(self) end + +---Checks if the element matches or inherits from the specified type +---@param type string The type to check for +---@return boolean isType Whether the element is of the specified type +function BaseElement:isType(type) end + +---Registers a new state with optional auto-condition +---@param stateName string The name of the state +---@return BaseElement self The BaseElement instance +function BaseElement:registerState(stateName) end + +---Gets benchmark statistics for a method +---@param methodName string The name of the method to get statistics for +---@return table ? stats The benchmark statistics or nil +function BaseElement:getBenchmarkStats(methodName) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return table self The BaseElement instance +---@protected +function BaseElement:postInit() end + +---Manually activates a state +---@param stateName string The state to activate +---@return BaseElement self +function BaseElement:setState(stateName) end + +---Configures event listening behavior with automatic parent notification +---@param eventName string The name of the event to listen for +---@return table self The BaseElement instance +function BaseElement:listenEvent(eventName) end + +---Updates all states that have auto-conditions +---@return BaseElement self +function BaseElement:updateConditionalStates() end + +---Logs benchmark statistics for a method +---@param methodName string The name of the method to log +---@return BaseElement self The element instance +function BaseElement:logBenchmark(methodName) end + +---Starts profiling a method +---@param methodName string The name of the method to profile +---@return BaseElement self The element instance +function BaseElement:startProfile(methodName) end + +---Gets the value of the States property. +---@param self BaseElement self +---@return table {} Table of currently active states with their priorities +function BaseElement:getStates(self) end + +---Gets the value of the Id property. +---@param self BaseElement self +---@return string BaseElement Auto-generated unique identifier for element lookup +function BaseElement:getId(self) end + +---@class Switch : VisualElement +---@field onBackground number color when ON +---@field checked boolean switch is checked +---@field offBackground number color when OFF +---@field text string to display next to switch +---@field autoSize boolean to automatically size the element to fit switch and text +local Switch = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Switch:init(props, basalt) end + +---Sets the value of the OnBackground property. +---@param self Switch self +---@param OnBackground number color when ON +function Switch:setOnBackground(self, OnBackground) end + +---Gets the value of the OffBackground property. +---@param self Switch self +---@return number Background color when OFF +function Switch:getOffBackground(self) end + +---Gets the value of the OnBackground property. +---@param self Switch self +---@return number Background color when ON +function Switch:getOnBackground(self) end + +---Sets the value of the AutoSize property. +---@param self Switch self +---@param AutoSize boolean to automatically size the element to fit switch and text +function Switch:setAutoSize(self, AutoSize) end + +---Gets the value of the Checked property. +---@param self Switch self +---@return boolean Whether switch is checked +function Switch:getChecked(self) end + +---Gets the value of the Text property. +---@param self Switch self +---@return string Text to display next to switch +function Switch:getText(self) end + +---Sets the value of the Text property. +---@param self Switch self +---@param Text string to display next to switch +function Switch:setText(self, Text) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean Whether the event was handled +---@protected +function Switch:mouse_click(button, x, y) end + +---Sets the value of the Checked property. +---@param self Switch self +---@param Checked boolean switch is checked +function Switch:setChecked(self, Checked) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Switch:render() end + +---Sets the value of the OffBackground property. +---@param self Switch self +---@param OffBackground number color when OFF +function Switch:setOffBackground(self, OffBackground) end + +---Gets the value of the AutoSize property. +---@param self Switch self +---@return boolean Whether to automatically size the element to fit switch and text +function Switch:getAutoSize(self) end + +---@class Animation +local Animation = {} + +---The event handler for the animation (listens to timer events) +---@param event string The event type +---@param timerId number The timer ID +function Animation:event(event, timerId) end + +---Stops the animation immediately: cancels timers, completes running anim instances and clears the element property +function Animation:stop() end + +---Registers a callback for the complete event +---@param callback function The callback function to register +---@return Animation self The animation instance +function Animation:onComplete(callback) end + +---Creates a new Animation +---@param element VisualElement The element to animate +---@return Animation The new animation +function Animation.new(element) end + +---Creates a new sequence +---@return Animation self The animation instance +function Animation:sequence() end + +---Adds a new animation to the sequence +---@param type string The type of animation +---@param args table The animation arguments +---@param duration number The duration in seconds +---@param easing string The easing function name +function Animation:addAnimation(type, args, duration, easing) end + +---Starts the animation +---@return Animation self The animation instance +function Animation:start() end + +---Registers a callback for the start event +---@param callback function The callback function to register +function Animation:onStart(callback) end + +---Registers a new easing function +---@param name string The name of the easing function +---@param func function The easing function (takes progress 0-1, returns modified progress) +function Animation.registerEasing(name, func) end + +---Registers a callback for the update event +---@param callback function The callback function to register +---@return Animation self The animation instance +function Animation:onUpdate(callback) end + +---Registers a new animation type +---@param name string The name of the animation +---@param handlers table Table containing start, update and complete handlers +function Animation.registerAnimation(name, handlers) end + +---@class Button : VisualElement +---@field text string Label text displayed centered within the button +local Button = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Button:render() end + +---Sets the value of the Text property. +---@param self Button self +---@param Text string Label text displayed centered within the button +function Button:setText(self, Text) end + +---Gets the value of the Text property. +---@param self Button self +---@return string Button Label text displayed centered within the button +function Button:getText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Button:init(props, basalt) end + +---@class CheckBox : VisualElement +---@field autoSize boolean Automatically adjusts width based on text length +---@field text string Text shown when the checkbox is unchecked +---@field checked boolean The current state of the checkbox (true=checked, false=unchecked) +---@field checkedText string Text shown when the checkbox is checked +local CheckBox = {} + +---Sets the value of the Checked property. +---@param self CheckBox self +---@param Checked boolean The current state of the checkbox (true=checked, false=unchecked) +function CheckBox:setChecked(self, Checked) end + +---Sets the value of the CheckedText property. +---@param self CheckBox self +---@param CheckedText string Text shown when the checkbox is checked +function CheckBox:setCheckedText(self, CheckedText) end + +---Gets the value of the CheckedText property. +---@param self CheckBox self +---@return string x Text shown when the checkbox is checked +function CheckBox:getCheckedText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function CheckBox:init(props, basalt) end + +---Sets the value of the AutoSize property. +---@param self CheckBox self +---@param AutoSize boolean Automatically adjusts width based on text length +function CheckBox:setAutoSize(self, AutoSize) end + +---Gets the value of the Text property. +---@param self CheckBox self +---@return string empty Text shown when the checkbox is unchecked +function CheckBox:getText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function CheckBox:render() end + +---Sets the value of the Text property. +---@param self CheckBox self +---@param Text string Text shown when the checkbox is unchecked +function CheckBox:setText(self, Text) end + +---Handles mouse interactions to toggle the checkbox state +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean Clicked Whether the event was handled +---@protected +function CheckBox:mouse_click(button, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return CheckBox self The created instance +---@protected +function CheckBox.new() end + +---Gets the value of the Checked property. +---@param self CheckBox self +---@return boolean false The current state of the checkbox (true=checked, false=unchecked) +function CheckBox:getChecked(self) end + +---Gets the value of the AutoSize property. +---@param self CheckBox self +---@return boolean true Automatically adjusts width based on text length +function CheckBox:getAutoSize(self) end + +---@class Label : VisualElement +---@field autoSize boolean Whether the label should automatically resize its width based on the text content +---@field text string The text content to display. Can be a string or a function that returns a string +local Label = {} + +---Sets the value of the AutoSize property. +---@param self Label self +---@param AutoSize boolean Whether the label should automatically resize its width based on the text content +function Label:setAutoSize(self, AutoSize) end + +---Gets the value of the Text property. +---@param self Label self +---@return string Label The text content to display. Can be a string or a function that returns a string +function Label:getText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Label self The initialized instance +---@protected +function Label:init(props, basalt) end + +---Gets the wrapped lines of the Label +---@return table wrappedText The wrapped lines of the Label +function Label:getWrappedText() end + +---Sets the value of the Text property. +---@param self Label self +---@param Text string The text content to display. Can be a string or a function that returns a string +function Label:setText(self, Text) end + +---Gets the value of the AutoSize property. +---@param self Label self +---@return boolean true Whether the label should automatically resize its width based on the text content +function Label:getAutoSize(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Label:render() end + +---@class Breadcrumb : VisualElement +---@field clickable true Whether the segments are clickable +---@field autoSize false Whether to resize the element width automatically based on text +---@field path table Array of strings representing the breadcrumb segments +local Breadcrumb = {} + +---Sets the value of the Path property. +---@param self Breadcrumb self +---@param Path table Array of strings representing the breadcrumb segments +function Breadcrumb:setPath(self, Path) end + +---Gets the value of the AutoSize property. +---@param self Breadcrumb self +---@return false boolean Whether to resize the element width automatically based on text +function Breadcrumb:getAutoSize(self) end + +---@param props table +---@param basalt table +function Breadcrumb:init(props, basalt) end + +---Registers a callback for the select event +---@param callback function The callback function to register +---@return Breadcrumb self The Breadcrumb instance +function Breadcrumb:onSelect(callback) end + +---Sets the value of the AutoSize property. +---@param self Breadcrumb self +---@param AutoSize false Whether to resize the element width automatically based on text +function Breadcrumb:setAutoSize(self, AutoSize) end + +---Sets the value of the Clickable property. +---@param self Breadcrumb self +---@param Clickable true Whether the segments are clickable +function Breadcrumb:setClickable(self, Clickable) end + +---Gets the value of the Clickable property. +---@param self Breadcrumb self +---@return true boolean Whether the segments are clickable +function Breadcrumb:getClickable(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Breadcrumb:render() end + +---@param button number +---@param x number +---@param y number +---@return boolean handled +function Breadcrumb:mouse_click(button, x, y) end + +---Gets the value of the Path property. +---@param self Breadcrumb self +---@return table {} Array of strings representing the breadcrumb segments +function Breadcrumb:getPath(self) end + +---@return table self +function Breadcrumb.new() end + +---@class DropDown : List +---@field dropSymbol string Indicator for dropdown state +---@field selectedText string Text shown when no selection made +---@field dropdownHeight number Maximum visible items when expanded +local DropDown = {} + +---Gets the value of the DropdownHeight property. +---@param self DropDown self +---@return number 5 Maximum visible items when expanded +function DropDown:getDropdownHeight(self) end + +---Sets the value of the DropdownHeight property. +---@param self DropDown self +---@param DropdownHeight number Maximum visible items when expanded +function DropDown:setDropdownHeight(self, DropdownHeight) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function DropDown:mouse_click(button, x, y) end + +---Called when the DropDown loses focus +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function DropDown:blur() end + +---Sets the value of the DropSymbol property. +---@param self DropDown self +---@param DropSymbol string Indicator for dropdown state +function DropDown:setDropSymbol(self, DropSymbol) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return DropDown self The initialized instance +---@protected +function DropDown:init(props, basalt) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was released +---@param x number The x-coordinate of the release +---@param y number The y-coordinate of the release +---@return boolean Whether the event was handled +---@protected +function DropDown:mouse_up(button, x, y) end + +---Called when the DropDown gains focus +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function DropDown:focus() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function DropDown:render() end + +---Gets the value of the SelectedText property. +---@param self DropDown self +---@return string "" Text shown when no selection made +function DropDown:getSelectedText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button being dragged +---@param x number The x-coordinate of the drag +---@param y number The y-coordinate of the drag +---@return boolean Whether the event was handled +---@protected +function DropDown:mouse_drag(button, x, y) end + +---Sets the value of the SelectedText property. +---@param self DropDown self +---@param SelectedText string Text shown when no selection made +function DropDown:setSelectedText(self, SelectedText) end + +---Gets the value of the DropSymbol property. +---@param self DropDown self +---@return string "\31" Indicator for dropdown state +function DropDown:getDropSymbol(self) end + +---@class Tree : VisualElement +---@field showScrollBar boolean Whether to show the scrollbar when nodes exceed height +---@field horizontalOffset number Current horizontal scroll position +---@field scrollBarBackground string Symbol used for the scrollbar background +---@field selectedForegroundColor color foreground color of selected node +---@field nodes table The tree structure containing node objects with {text, children} properties +---@field offset number Current vertical scroll position +---@field selectedNode table nil Currently selected node +---@field selectedBackgroundColor color background color of selected node +---@field scrollBarColor color Color of the scrollbar handle +---@field scrollBarSymbol string " Symbol used for the scrollbar handle +---@field scrollBarBackgroundColor color Background color of the scrollbar +---@field expandedNodes table Table of nodes that are currently expanded +local Tree = {} + +---Sets the value of the ScrollBarBackgroundColor property. +---@param self Tree self +---@param ScrollBarBackgroundColor color Background color of the scrollbar +function Tree:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The scroll direction (1 for up, -1 for down) +---@param x number The x position of the scroll +---@param y number The y position of the scroll +---@return boolean handled Whether the event was handled +---@protected +function Tree:mouse_scroll(direction, x, y) end + +---Gets the value of the ExpandedNodes property. +---@param self Tree self +---@return table {} Table of nodes that are currently expanded +function Tree:getExpandedNodes(self) end + +---Gets the value of the ScrollBarSymbol property. +---@param self Tree self +---@return string " " Symbol used for the scrollbar handle +function Tree:getScrollBarSymbol(self) end + +---Sets the value of the ShowScrollBar property. +---@param self Tree self +---@param ShowScrollBar boolean Whether to show the scrollbar when nodes exceed height +function Tree:setShowScrollBar(self, ShowScrollBar) end + +---Gets the value of the HorizontalOffset property. +---@param self Tree self +---@return number 0 Current horizontal scroll position +function Tree:getHorizontalOffset(self) end + +---Sets the value of the SelectedBackgroundColor property. +---@param self Tree self +---@param SelectedBackgroundColor color background color of selected node +function Tree:setSelectedBackgroundColor(self, SelectedBackgroundColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was released +---@param x number The x-coordinate of the release +---@param y number The y-coordinate of the release +---@return boolean Whether the event was handled +---@protected +function Tree:mouse_up(button, x, y) end + +---Toggles a node's expanded state +---@param node table The node to toggle +---@return Tree self The Tree instance +function Tree:toggleNode(node) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Tree:render() end + +---Initializes the Tree instance +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Tree self The initialized instance +---@protected +function Tree:init(props, basalt) end + +---Gets the value of the SelectedNode property. +---@param self Tree self +---@return table ? nil Currently selected node +function Tree:getSelectedNode(self) end + +---Sets the value of the SelectedNode property. +---@param self Tree self +---@param SelectedNode table nil Currently selected node +function Tree:setSelectedNode(self, SelectedNode) end + +---Sets the value of the ScrollBarBackground property. +---@param self Tree self +---@param ScrollBarBackground string Symbol used for the scrollbar background +function Tree:setScrollBarBackground(self, ScrollBarBackground) end + +---Gets the size of the tree +---@return number width The width of the tree +---@return number height The height of the tree +function Tree:getNodeSize() end + +---Expands a node +---@param node table The node to expand +---@return Tree self The Tree instance +function Tree:expandNode(node) end + +---Gets the value of the ShowScrollBar property. +---@param self Tree self +---@return boolean true Whether to show the scrollbar when nodes exceed height +function Tree:getShowScrollBar(self) end + +---Gets the value of the Offset property. +---@param self Tree self +---@return number 0 Current vertical scroll position +function Tree:getOffset(self) end + +---Gets the value of the ScrollBarColor property. +---@param self Tree self +---@return color lightGray Color of the scrollbar handle +function Tree:getScrollBarColor(self) end + +---Collapses a node +---@param node table The node to collapse +---@return Tree self The Tree instance +function Tree:collapseNode(node) end + +---Registers a callback for when a node is selected +---@param callback function The callback function +---@return Tree self The Tree instance +function Tree:onSelect(callback) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button being dragged +---@param x number The x-coordinate of the drag +---@param y number The y-coordinate of the drag +---@return boolean Whether the event was handled +---@protected +function Tree:mouse_drag(button, x, y) end + +---Gets the value of the SelectedForegroundColor property. +---@param self Tree self +---@return color white foreground color of selected node +function Tree:getSelectedForegroundColor(self) end + +---Sets the value of the Nodes property. +---@param self Tree self +---@param Nodes table The tree structure containing node objects with {text, children} properties +function Tree:setNodes(self, Nodes) end + +---Gets the value of the ScrollBarBackground property. +---@param self Tree self +---@return string "\127" Symbol used for the scrollbar background +function Tree:getScrollBarBackground(self) end + +---Sets the value of the HorizontalOffset property. +---@param self Tree self +---@param HorizontalOffset number Current horizontal scroll position +function Tree:setHorizontalOffset(self, HorizontalOffset) end + +---Gets the value of the SelectedBackgroundColor property. +---@param self Tree self +---@return color lightBlue background color of selected node +function Tree:getSelectedBackgroundColor(self) end + +---Gets the value of the Nodes property. +---@param self Tree self +---@return table {} The tree structure containing node objects with {text, children} properties +function Tree:getNodes(self) end + +---Sets the value of the ExpandedNodes property. +---@param self Tree self +---@param ExpandedNodes table Table of nodes that are currently expanded +function Tree:setExpandedNodes(self, ExpandedNodes) end + +---Sets the value of the Offset property. +---@param self Tree self +---@param Offset number Current vertical scroll position +function Tree:setOffset(self, Offset) end + +---Sets the value of the ScrollBarColor property. +---@param self Tree self +---@param ScrollBarColor color Color of the scrollbar handle +function Tree:setScrollBarColor(self, ScrollBarColor) end + +---Handles mouse click events +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Tree:mouse_click(button, x, y) end + +---Sets the value of the SelectedForegroundColor property. +---@param self Tree self +---@param SelectedForegroundColor color foreground color of selected node +function Tree:setSelectedForegroundColor(self, SelectedForegroundColor) end + +---Gets the value of the ScrollBarBackgroundColor property. +---@param self Tree self +---@return color gray Background color of the scrollbar +function Tree:getScrollBarBackgroundColor(self) end + +---Sets the value of the ScrollBarSymbol property. +---@param self Tree self +---@param ScrollBarSymbol string " Symbol used for the scrollbar handle +function Tree:setScrollBarSymbol(self, ScrollBarSymbol) end + +---@class ContextMenu : Container +---@field items table List of menu items +---@field isOpen boolean Whether the menu is currently open +---@field openSubmenu table Currently open submenu data +---@field itemHeight number Height of each menu item +local ContextMenu = {} + +---Sets the menu items +---@param items table Array of item definitions +---@return ContextMenu self For method chaining +function ContextMenu:setItems(items) end + +---Sets the value of the ItemHeight property. +---@param self ContextMenu self +---@param ItemHeight number Height of each menu item +function ContextMenu:setItemHeight(self, ItemHeight) end + +---Closes the entire menu chain (parent and all submenus) +---@return ContextMenu self For method chaining +function ContextMenu:closeAll() end + +---Closes the menu and any submenus +---@return ContextMenu self For method chaining +function ContextMenu:close() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function ContextMenu:init(props, basalt) end + +---Gets the value of the Items property. +---@param self ContextMenu self +---@return table {} List of menu items +function ContextMenu:getItems(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function ContextMenu:mouse_click() end + +---Sets the value of the IsOpen property. +---@param self ContextMenu self +---@param IsOpen boolean Whether the menu is currently open +function ContextMenu:setIsOpen(self, IsOpen) end + +---Opens the menu +---@return ContextMenu self For method chaining +function ContextMenu:open() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function ContextMenu:render() end + +---Gets the value of the ItemHeight property. +---@param self ContextMenu self +---@return number 1 Height of each menu item +function ContextMenu:getItemHeight(self) end + +---Gets the value of the OpenSubmenu property. +---@param self ContextMenu self +---@return table nil Currently open submenu data +function ContextMenu:getOpenSubmenu(self) end + +---Gets the value of the IsOpen property. +---@param self ContextMenu self +---@return boolean false Whether the menu is currently open +function ContextMenu:getIsOpen(self) end + +---Sets the value of the OpenSubmenu property. +---@param self ContextMenu self +---@param OpenSubmenu table Currently open submenu data +function ContextMenu:setOpenSubmenu(self, OpenSubmenu) end + +---@class ErrorHandler +local ErrorHandler = {} + +---Handles an error +---@param errMsg string The error message +function errorHandler.error(errMsg) end + ---@class Graph : VisualElement ----@field maxValue number The maximum value of the graph ---@field series table The series of the graph ---@field minValue number The minimum value of the graph +---@field maxValue number The maximum value of the graph local Graph = {} ----Sets the value of the Series property. +---Gets the value of the MinValue property. ---@param self Graph self ----@param Series table The series of the graph -function Graph:setSeries(self, Series) end +---@return number 0 The minimum value of the graph +function Graph:getMinValue(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Graph:render() end + +---@param name string The name of the series +---@return Graph self The graph instance +function Graph:focusSeries(name) end + +---@param name string The name of the series +---@param count number The number of points in the series +---@return Graph self The graph instance +function Graph:setSeriesPointCount(name, count) end + +---Gets the value of the MaxValue property. +---@param self Graph self +---@return number 100 The maximum value of the graph +function Graph:getMaxValue(self) end + +---@param name string The name of the series +---@param value number The value of the point +---@return Graph self The graph instance +function Graph:addPoint(name, value) end + +---Clears all points from a series +---@return Graph self The graph instance +function Graph:clear() end + +---Sets the value of the MinValue property. +---@param self Graph self +---@param MinValue number The minimum value of the graph +function Graph:setMinValue(self, MinValue) end ---@param name string The name of the series ---@param symbol string The symbol of the series @@ -4094,1268 +2913,484 @@ function Graph:addSeries(name, symbol, bgCol, fgCol, pointCount) end function Graph:setMaxValue(self, MaxValue) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Graph self The initialized instance ---@protected -function Graph:render() end +function Graph:init(props, basalt) end ----@param name string The name of the series ----@return Graph self The graph instance -function Graph:removeSeries(name) end - ----@param name string The name of the series ----@param count number The number of points in the series ----@return Graph self The graph instance -function Graph:setSeriesPointCount(name, count) end +---Sets the value of the Series property. +---@param self Graph self +---@param Series table The series of the graph +function Graph:setSeries(self, Series) end ---@param name string The name of the series ---@param visible boolean Whether the series should be visible ---@return Graph self The graph instance function Graph:changeSeriesVisibility(name, visible) end ----@param name string The name of the series ----@return Graph self The graph instance -function Graph:focusSeries(name) end - ----@param name string The name of the series ----@param value number The value of the point ----@return Graph self The graph instance -function Graph:addPoint(name, value) end - ----Clears all points from a series ----@return Graph self The graph instance -function Graph:clear() end - ----Gets the value of the MinValue property. ----@param self Graph self ----@return number 0 The minimum value of the graph -function Graph:getMinValue(self) end - ----Sets the value of the MinValue property. ----@param self Graph self ----@param MinValue number The minimum value of the graph -function Graph:setMinValue(self, MinValue) end - ---@param name string The name of the series ---@return table ? series The series function Graph:getSeries(name) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Graph self The initialized instance ----@protected -function Graph:init(props, basalt) end - ----Gets the value of the MaxValue property. ----@param self Graph self ----@return number 100 The maximum value of the graph -function Graph:getMaxValue(self) end - ----@class BigFontText -local BigFontText = {} - ----@class CheckBox : VisualElement ----@field checked boolean The current state of the checkbox (true=checked, false=unchecked) ----@field checkedText string Text shown when the checkbox is checked ----@field autoSize boolean Automatically adjusts width based on text length ----@field text string Text shown when the checkbox is unchecked -local CheckBox = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return CheckBox self The created instance ----@protected -function CheckBox.new() end - ----Gets the value of the AutoSize property. ----@param self CheckBox self ----@return boolean true Automatically adjusts width based on text length -function CheckBox:getAutoSize(self) end - ----Handles mouse interactions to toggle the checkbox state ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean Clicked Whether the event was handled ----@protected -function CheckBox:mouse_click(button, x, y) end - ----Gets the value of the Checked property. ----@param self CheckBox self ----@return boolean false The current state of the checkbox (true=checked, false=unchecked) -function CheckBox:getChecked(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function CheckBox:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function CheckBox:init(props, basalt) end - ----Gets the value of the CheckedText property. ----@param self CheckBox self ----@return string x Text shown when the checkbox is checked -function CheckBox:getCheckedText(self) end - ----Sets the value of the CheckedText property. ----@param self CheckBox self ----@param CheckedText string Text shown when the checkbox is checked -function CheckBox:setCheckedText(self, CheckedText) end - ----Sets the value of the Text property. ----@param self CheckBox self ----@param Text string Text shown when the checkbox is unchecked -function CheckBox:setText(self, Text) end - ----Gets the value of the Text property. ----@param self CheckBox self ----@return string empty Text shown when the checkbox is unchecked -function CheckBox:getText(self) end - ----Sets the value of the Checked property. ----@param self CheckBox self ----@param Checked boolean The current state of the checkbox (true=checked, false=unchecked) -function CheckBox:setChecked(self, Checked) end - ----Sets the value of the AutoSize property. ----@param self CheckBox self ----@param AutoSize boolean Automatically adjusts width based on text length -function CheckBox:setAutoSize(self, AutoSize) end - ----@class Program : VisualElement ----@field program table The program instance ----@field running boolean Whether the program is running ----@field doneCallback function The done callback function ----@field path string The path to the program ----@field errorCallback function The error callback function -local Program = {} - ----Gets the value of the DoneCallback property. ----@param self Program self ----@return function nil The done callback function -function Program:getDoneCallback(self) end - ----Sets the value of the Program property. ----@param self Program self ----@param Program table The program instance -function Program:setProgram(self, Program) end - -function BasaltProgram:setArgs() end - ----Executes a program ----@param path string The path to the program ----@return Program self The Program instance -function Program:execute(path) end - ----Sets the value of the ErrorCallback property. ----@param self Program self ----@param ErrorCallback function The error callback function -function Program:setErrorCallback(self, ErrorCallback) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Program self The initialized instance ----@protected -function Program:init(props, basalt) end - ----Sets the value of the Path property. ----@param self Program self ----@param Path string The path to the program -function Program:setPath(self, Path) end - ----Gets the value of the Program property. ----@param self Program self ----@return table nil The program instance -function Program:getProgram(self) end - ----Gets the value of the Path property. ----@param self Program self ----@return string "" The path to the program -function Program:getPath(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return any result The event result ----@protected -function Program:dispatchEvent(event) end - ----Sends an event to the program ----@param event string The event to send ----@return Program self The Program instance -function Program:sendEvent(event) end - ----Gets the value of the Running property. ----@param self Program self ----@return boolean false Whether the program is running -function Program:getRunning(self) end - ----Gets the value of the ErrorCallback property. ----@param self Program self ----@return function nil The error callback function -function Program:getErrorCallback(self) end - ----Sets the value of the DoneCallback property. ----@param self Program self ----@param DoneCallback function The done callback function -function Program:setDoneCallback(self, DoneCallback) end - ----Registers a callback for the program's error event, if the function returns false, the program won't stop ----@param fn function The callback function to register ----@return Program self The Program instance -function Program:onError(fn) end - ----Sets the value of the Running property. ----@param self Program self ----@param Running boolean Whether the program is running -function Program:setRunning(self, Running) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Program:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Program:focus() end - ----Registers a callback for the program's done event ----@param fn function The callback function to register ----@return Program self The Program instance -function Program:onDone(fn) end - ----Stops the program ----@return Program self The Program instance -function Program:stop() end - ----@class ScrollFrame : Container ----@field contentHeight number The total height of the content (calculated from children) ----@field contentWidth number The total width of the content (calculated from children) ----@field showScrollBar boolean Whether to show scrollbars ----@field scrollBarColor color Color of the scrollbar handle ----@field scrollBarBackgroundColor color Background color of the scrollbar ----@field scrollBarBackground string The symbol used for the scrollbar background ----@field scrollBarSymbol string The symbol used for the scrollbar handle -local ScrollFrame = {} - ----Handles mouse click events for scrollbars and content ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button (1=left, 2=right, 3=middle) ----@param x number The x-coordinate of the click ----@param y number The y-coordinate of the click ----@return boolean Whether the event was handled ----@protected -function ScrollFrame:mouse_click(button, x, y) end - ----Gets the value of the ContentHeight property. ----@param self ScrollFrame self ----@return number 0 The total height of the content (calculated from children) -function ScrollFrame:getContentHeight(self) end - ----Gets the value of the ContentWidth property. ----@param self ScrollFrame self ----@return number 0 The total width of the content (calculated from children) -function ScrollFrame:getContentWidth(self) end - ----Gets the value of the ScrollBarColor property. ----@param self ScrollFrame self ----@return color lightGray Color of the scrollbar handle -function ScrollFrame:getScrollBarColor(self) end - ----Handles mouse drag events for scrollbar ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button being dragged ----@param x number The x-coordinate of the drag ----@param y number The y-coordinate of the drag ----@return boolean Whether the event was handled ----@protected -function ScrollFrame:mouse_drag(button, x, y) end - ----Handles mouse scroll events ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number 1 for up, -1 for down ----@param x number Mouse x position relative to element ----@param y number Mouse y position relative to element ----@return boolean Whether the event was handled ----@protected -function ScrollFrame:mouse_scroll(direction, x, y) end - ----Gets the value of the ScrollBarSymbol property. ----@param self ScrollFrame self ----@return string "_" The symbol used for the scrollbar handle -function ScrollFrame:getScrollBarSymbol(self) end - ----Sets the value of the ContentWidth property. ----@param self ScrollFrame self ----@param ContentWidth number The total width of the content (calculated from children) -function ScrollFrame:setContentWidth(self, ContentWidth) end - ----Sets the value of the ScrollBarBackground property. ----@param self ScrollFrame self ----@param ScrollBarBackground string The symbol used for the scrollbar background -function ScrollFrame:setScrollBarBackground(self, ScrollBarBackground) end - ----Sets the value of the ShowScrollBar property. ----@param self ScrollFrame self ----@param ShowScrollBar boolean Whether to show scrollbars -function ScrollFrame:setShowScrollBar(self, ShowScrollBar) end - ----Sets the value of the ScrollBarSymbol property. ----@param self ScrollFrame self ----@param ScrollBarSymbol string The symbol used for the scrollbar handle -function ScrollFrame:setScrollBarSymbol(self, ScrollBarSymbol) end - ----Handles mouse up events to stop scrollbar dragging ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was released ----@param x number The x-coordinate of the release ----@param y number The y-coordinate of the release ----@return boolean Whether the event was handled ----@protected -function ScrollFrame:mouse_up(button, x, y) end - ----Gets the value of the ShowScrollBar property. ----@param self ScrollFrame self ----@return boolean true Whether to show scrollbars -function ScrollFrame:getShowScrollBar(self) end - ----Renders the ScrollFrame and its scrollbars ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function ScrollFrame:render() end - ----Gets the value of the ScrollBarBackground property. ----@param self ScrollFrame self ----@return string "\127" The symbol used for the scrollbar background -function ScrollFrame:getScrollBarBackground(self) end - ----Gets the value of the ScrollBarBackgroundColor property. ----@param self ScrollFrame self ----@return color gray Background color of the scrollbar -function ScrollFrame:getScrollBarBackgroundColor(self) end - ----Sets the value of the ScrollBarBackgroundColor property. ----@param self ScrollFrame self ----@param ScrollBarBackgroundColor color Background color of the scrollbar -function ScrollFrame:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end - ----Sets the value of the ScrollBarColor property. ----@param self ScrollFrame self ----@param ScrollBarColor color Color of the scrollbar handle -function ScrollFrame:setScrollBarColor(self, ScrollBarColor) end - ----Sets the value of the ContentHeight property. ----@param self ScrollFrame self ----@param ContentHeight number The total height of the content (calculated from children) -function ScrollFrame:setContentHeight(self, ContentHeight) end - ----@class AnimationInstance -local AnimationInstance = {} - ----Gets called when the animation is completed -function AnimationInstance:complete() end - ----Creates a new AnimationInstance ----@param element VisualElement The element to animate ----@param animType string The type of animation ----@param args table The animation arguments ----@param duration number Duration in seconds ----@param easing string The easing function name ----@return AnimationInstance The new animation instance -function AnimationInstance.new(element, animType, args, duration, easing) end - ----Updates the animation ----@param elapsed number The elapsed time in seconds ----@return boolean Whether the animation is finished -function AnimationInstance:update(elapsed) end - ----Starts the animation ----@return AnimationInstance self The animation instance -function AnimationInstance:start() end - ----@class Switch : VisualElement ----@field checked boolean switch is checked ----@field text string to display next to switch ----@field onBackground number color when ON ----@field autoSize boolean to automatically size the element to fit switch and text ----@field offBackground number color when OFF -local Switch = {} - ----Gets the value of the Text property. ----@param self Switch self ----@return string Text to display next to switch -function Switch:getText(self) end - ----Sets the value of the Checked property. ----@param self Switch self ----@param Checked boolean switch is checked -function Switch:setChecked(self, Checked) end - ----Gets the value of the Checked property. ----@param self Switch self ----@return boolean Whether switch is checked -function Switch:getChecked(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Switch:init(props, basalt) end - ----Sets the value of the OnBackground property. ----@param self Switch self ----@param OnBackground number color when ON -function Switch:setOnBackground(self, OnBackground) end - ----Sets the value of the Text property. ----@param self Switch self ----@param Text string to display next to switch -function Switch:setText(self, Text) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Switch:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean Whether the event was handled ----@protected -function Switch:mouse_click(button, x, y) end - ----Gets the value of the OnBackground property. ----@param self Switch self ----@return number Background color when ON -function Switch:getOnBackground(self) end - ----Sets the value of the OffBackground property. ----@param self Switch self ----@param OffBackground number color when OFF -function Switch:setOffBackground(self, OffBackground) end - ----Gets the value of the OffBackground property. ----@param self Switch self ----@return number Background color when OFF -function Switch:getOffBackground(self) end - ----Sets the value of the AutoSize property. ----@param self Switch self ----@param AutoSize boolean to automatically size the element to fit switch and text -function Switch:setAutoSize(self, AutoSize) end - ----Gets the value of the AutoSize property. ----@param self Switch self ----@return boolean Whether to automatically size the element to fit switch and text -function Switch:getAutoSize(self) end - ----@class PropertySystem -local PropertySystem = {} - ----Adds a setter hook to the PropertySystem. Setter hooks are functions that are called before a property is set. ----@param hook function The hook function to add -function PropertySystem.addSetterHook(hook) end - ----Combines multiple properties into a single getter and setter ----@param class table The element class to combine the properties for ----@param name string The name of the combined property -function PropertySystem.combineProperties(class, name) end - ----Observers a property ----@param name string The name of the property ----@param callback function The callback function to call when the property changes ----@return table self The PropertySystem -function PropertySystem:observe(name, callback) end - ----Update call for a property IS USED INTERNALLY ----@param name string The name of the property ----@param value any The value of the property ----@return table self The PropertySystem -function PropertySystem:_updateProperty(name, value) end - ----Defines a property for an element class ----@param class table The element class to define the property for ----@param name string The name of the property ----@param config table The configuration of the property -function PropertySystem.defineProperty(class, name, config) end - ----Creates an element from a blueprint ----@param elementClass table The element class to create from the blueprint ----@param blueprint table The blueprint to create the element from ----@return table element The created element -function PropertySystem.createFromBlueprint(elementClass, blueprint) end - ----Gets a property configuration ----@param name string The name of the property ----@return table config The configuration of the property -function PropertySystem:getPropertyConfig(name) end - ----Removes an observer from a property ----@param name string The name of the property ----@param callback function The callback function to remove ----@return table self The PropertySystem -function PropertySystem:removeObserver(name, callback) end - ----Initializes the PropertySystem IS USED INTERNALLY ----@return table self The PropertySystem -function PropertySystem:__init() end - ----Removes a property from the PropertySystem on instance level ----@param name string The name of the property ----@return table self The PropertySystem -function PropertySystem:removeProperty(name) end - ----Adds a property to the PropertySystem on instance level ----@param name string The name of the property ----@param config table The configuration of the property ----@return table self The PropertySystem -function PropertySystem:instanceProperty(name, config) end - ----Removes all observers from a property ----@return table self The PropertySystem -function PropertySystem:removeAllObservers() end - ----Creates a blueprint of an element class with all its properties ----@param elementClass table The element class to create a blueprint from ----@return table blueprint A table containing all property definitions -function PropertySystem.blueprint(elementClass) end - ----@class BaseElement : PropertySystem ----@field name string User-defined name for the element ----@field states table Table of currently active states with their priorities ----@field eventCallbacks table Collection of registered event handler functions ----@field type string A hierarchical identifier of the element's type chain ----@field enabled boolean Controls event processing for this element ----@field id string Auto-generated unique identifier for element lookup -local BaseElement = {} - ----Manually deactivates a state ----@param stateName string The state to deactivate ----@return BaseElement self -function BaseElement:unsetState(stateName) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return boolean ? handled Whether the event was handled ----@protected -function BaseElement:dispatchEvent(event) end - ----Sets the value of the Name property. ----@param self BaseElement self ----@param Name string User-defined name for the element -function BaseElement:setName(self, Name) end - ----Removes a state from the registry ----@param stateName string The state to remove ----@return BaseElement self -function BaseElement:unregisterState(stateName) end - ----Gets the value of the States property. ----@param self BaseElement self ----@return table {} Table of currently active states with their priorities -function BaseElement:getStates(self) end - ----Defines a class-level event callback method with automatic event registration ----@param class table The class to register ----@param callbackName string The name of the callback to register -function BaseElement.registerEventCallback(class, callbackName) end - ----Enables debugging for this element ----@param self BaseElement The element to debug ----@param level number The debug level -function BaseElement.debug(self, level) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return table self The initialized instance ----@protected -function BaseElement:init(props, basalt) end - ----Propagates render request up the element tree ----@return table self The BaseElement instance -function BaseElement:updateRender() end - ----Sets the value of the Enabled property. ----@param self BaseElement self ----@param Enabled boolean Controls event processing for this element -function BaseElement:setEnabled(self, Enabled) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return table self The BaseElement instance ----@protected -function BaseElement:postInit() end - ----Stops benchmarking for a method ----@param methodName string The name of the method to stop benchmarking ----@return BaseElement self The element instance -function BaseElement:stopBenchmark(methodName) end - ----Checks if a state is currently active ----@param stateName string The state to check ----@return boolean isActive -function BaseElement:hasState(stateName) end - ----Enables benchmarking for a method ----@param methodName string The name of the method to benchmark ----@return BaseElement self The element instance -function BaseElement:benchmark(methodName) end - ----Removes the element from UI tree and cleans up resources -function BaseElement:destroy() end - ----Gets all currently active states sorted by priority ----@return table states Array of {name, priority} sorted by priority -function BaseElement:getActiveStates() end - ----Adds an event handler function with automatic event registration ----@param event string The event to register the callback for ----@param callback function The callback function to register ----@return table self The BaseElement instance -function BaseElement:registerCallback(event, callback) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return boolean ? handled Whether the event was handled ----@protected -function BaseElement:handleEvent(event) end - ----Sets the value of the Type property. ----@param self BaseElement self ----@param Type string A hierarchical identifier of the element's type chain -function BaseElement:setType(self, Type) end - ----Gets the value of the Id property. ----@param self BaseElement self ----@return string BaseElement Auto-generated unique identifier for element lookup -function BaseElement:getId(self) end - ----Gets the value of the Name property. ----@param self BaseElement self ----@return string BaseElement User-defined name for the element -function BaseElement:getName(self) end - ----Gets benchmark statistics for a method ----@param methodName string The name of the method to get statistics for ----@return table ? stats The benchmark statistics or nil -function BaseElement:getBenchmarkStats(methodName) end - ----Sets the value of the Id property. ----@param self BaseElement self ----@param Id string Auto-generated unique identifier for element lookup -function BaseElement:setId(self, Id) end - ----Registers a class-level event listener with optional dependency ----@param class table The class to register ----@param eventName string The name of the event to register -function BaseElement.defineEvent(class, eventName) end - ----Gets the value of the EventCallbacks property. ----@param self BaseElement self ----@return table BaseElement Collection of registered event handler functions -function BaseElement:getEventCallbacks(self) end - ----Applies the current theme to this element ----@param self BaseElement The element to apply theme to ----@param applyToChildren boolean ? Whether to apply theme to child elements (default: true) ----@return BaseElement self The element instance -function BaseElement:applyTheme(self, applyToChildren) end - ----Dumps debug information for this element ----@param self BaseElement The element to dump debug info for -function BaseElement.dumpDebug(self) end - ----Registers a new state with optional auto-condition ----@param stateName string The name of the state ----@return BaseElement self The BaseElement instance -function BaseElement:registerState(stateName) end - ----Checks if the element matches or inherits from the specified type ----@param type string The type to check for ----@return boolean isType Whether the element is of the specified type -function BaseElement:isType(type) end - ----Gets the value of the Type property. ----@param self BaseElement self ----@return string BaseElement A hierarchical identifier of the element's type chain -function BaseElement:getType(self) end - ----Gets the theme properties for this element ----@param self BaseElement The element to get theme for ----@return table styles The theme properties -function BaseElement:getTheme(self) end - ----Starts profiling a method ----@param methodName string The name of the method to profile ----@return BaseElement self The element instance -function BaseElement:startProfile(methodName) end - ----Sets the value of the EventCallbacks property. ----@param self BaseElement self ----@param EventCallbacks table Collection of registered event handler functions -function BaseElement:setEventCallbacks(self, EventCallbacks) end - ----Executes all registered callbacks for the specified event ----@param event string The event to fire ----@return table self The BaseElement instance -function BaseElement:fireEvent(event) end - ----Configures event listening behavior with automatic parent notification ----@param eventName string The name of the event to listen for ----@return table self The BaseElement instance -function BaseElement:listenEvent(eventName) end - ----Sets the value of the States property. ----@param self BaseElement self ----@param States table Table of currently active states with their priorities -function BaseElement:setStates(self, States) end - ----Updates all states that have auto-conditions ----@return BaseElement self -function BaseElement:updateConditionalStates() end - ----Manually activates a state ----@param stateName string The state to activate ----@return BaseElement self -function BaseElement:setState(stateName) end - ----Ends profiling a method ----@param methodName string The name of the method to stop profiling ----@return BaseElement self The element instance -function BaseElement:endProfile(methodName) end - ----Logs benchmark statistics for a method ----@param methodName string The name of the method to log ----@return BaseElement self The element instance -function BaseElement:logBenchmark(methodName) end - ----Sets up a property change observer with immediate callback registration ----@param property string The property to observe ----@param callback function The callback to call when the property changes ----@return table self The BaseElement instance -function BaseElement:onChange(property, callback) end - ----Traverses parent chain to locate the root frame element ----@return BaseFrame BaseFrame The base frame of the element -function BaseElement:getBaseFrame() end - ----Gets the value of the Enabled property. ----@param self BaseElement self ----@return boolean BaseElement Controls event processing for this element -function BaseElement:getEnabled(self) end - ----Gets the highest priority active state ----@return string |nil currentState The state with highest priority -function BaseElement:getCurrentState() end - ----@class List : Collection ----@field offset number Current scroll offset for viewing long lists ----@field showScrollBar boolean Whether to show the scrollbar when items exceed height ----@field emptyText string items" Text to display when the list is empty ----@field scrollBarColor color Color of the scrollbar handle ----@field scrollBarBackgroundColor color Background color of the scrollbar ----@field scrollBarBackground string Symbol used for the scrollbar background ----@field scrollBarSymbol string " Symbol used for the scrollbar handle -local List = {} - ----Gets the value of the ScrollBarBackground property. ----@param self List self ----@return string "\127" Symbol used for the scrollbar background -function List:getScrollBarBackground(self) end - ----Sets the value of the ScrollBarColor property. ----@param self List self ----@param ScrollBarColor color Color of the scrollbar handle -function List:setScrollBarColor(self, ScrollBarColor) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The direction of the scroll (1 for down, -1 for up) ----@param x number The x-coordinate of the scroll ----@param y number The y-coordinate of the scroll ----@return boolean Whether the event was handled ----@protected -function List:mouse_scroll(direction, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return List self The initialized instance ----@protected -function List:init(props, basalt) end - ----Sets the value of the ScrollBarBackground property. ----@param self List self ----@param ScrollBarBackground string Symbol used for the scrollbar background -function List:setScrollBarBackground(self, ScrollBarBackground) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was clicked ----@param x number The x-coordinate of the click ----@param y number The y-coordinate of the click ----@return boolean Whether the event was handled ----@protected -function List:mouse_click(button, x, y) end - ----Gets the value of the ScrollBarSymbol property. ----@param self List self ----@return string " " Symbol used for the scrollbar handle -function List:getScrollBarSymbol(self) end - ----Sets the value of the ScrollBarSymbol property. ----@param self List self ----@param ScrollBarSymbol string " Symbol used for the scrollbar handle -function List:setScrollBarSymbol(self, ScrollBarSymbol) end - ----Sets the value of the ShowScrollBar property. ----@param self List self ----@param ShowScrollBar boolean Whether to show the scrollbar when items exceed height -function List:setShowScrollBar(self, ShowScrollBar) end - ----Gets the value of the ShowScrollBar property. ----@param self List self ----@return boolean true Whether to show the scrollbar when items exceed height -function List:getShowScrollBar(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was released ----@param x number The x-coordinate of the release ----@param y number The y-coordinate of the release ----@return boolean Whether the event was handled ----@protected -function List:mouse_up(button, x, y) end - ----Scrolls to make a specific item visible ----@param index number The index of the item to scroll to ----@return List self The List instance -function List:scrollToItem(index) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button being dragged ----@param x number The x-coordinate of the drag ----@param y number The y-coordinate of the drag ----@return boolean Whether the event was handled ----@protected -function List:mouse_drag(button, x, y) end - ----Scrolls the list to the top ----@return List self The List instance -function List:scrollToTop() end - ----Scrolls the list to the bottom ----@return List self The List instance -function List:scrollToBottom() end - ----Sets the value of the Offset property. ----@param self List self ----@param Offset number Current scroll offset for viewing long lists -function List:setOffset(self, Offset) end - ----Sets the value of the ScrollBarBackgroundColor property. ----@param self List self ----@param ScrollBarBackgroundColor color Background color of the scrollbar -function List:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end - ----Handles key events for keyboard navigation ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param keyCode number The key code ----@return boolean Whether the event was handled ----@protected -function List:key(keyCode) end - ----Sets the value of the EmptyText property. ----@param self List self ----@param EmptyText string items" Text to display when the list is empty -function List:setEmptyText(self, EmptyText) end - ----Registers a callback for the select event ----@param callback function The callback function to register ----@return List self The List instance -function List:onSelect(callback) end - ----Gets the value of the ScrollBarColor property. ----@param self List self ----@return color lightGray Color of the scrollbar handle -function List:getScrollBarColor(self) end - ----Gets the value of the ScrollBarBackgroundColor property. ----@param self List self ----@return color gray Background color of the scrollbar -function List:getScrollBarBackgroundColor(self) end - ----Registers a function to handle the onSelect event. ----@param List self ----@param index number ----@param item table ----@param self List self ----@param func function The function to be called when the event fires -function List:onOnSelect(self, func) end - ----Gets the value of the Offset property. ----@param self List self ----@return number 0 Current scroll offset for viewing long lists -function List:getOffset(self) end - ----Gets the value of the EmptyText property. ----@param self List self ----@return string "No items" Text to display when the list is empty -function List:getEmptyText(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function List:render() end - ----@class Collection : VisualElement ----@field selectedForeground color Text color for selected items ----@field multiSelection boolean Whether multiple items can be selected at once ----@field selectable boolean Whether items can be selected ----@field selectedBackground color Background color for selected items -local Collection = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Collection self The initialized instance ----@protected -function Collection:init(props, basalt) end - ----Registers a function to handle the onSelect event. ----@param index number ----@param item table ----@param self Collection self ----@param func function The function to be called when the event fires -function Collection:onOnSelect(self, func) end - ----Gets the value of the SelectedForeground property. ----@param self Collection self ----@return color white Text color for selected items -function Collection:getSelectedForeground(self) end - ----Sets the value of the SelectedForeground property. ----@param self Collection self ----@param SelectedForeground color Text color for selected items -function Collection:setSelectedForeground(self, SelectedForeground) end - ----Selects the next item in the collection ----@return Collection self The Collection instance -function Collection:selectNext() end - ----Gets the value of the SelectedBackground property. ----@param self Collection self ----@return color blue Background color for selected items -function Collection:getSelectedBackground(self) end - ----Sets the value of the SelectedBackground property. ----@param self Collection self ----@param SelectedBackground color Background color for selected items -function Collection:setSelectedBackground(self, SelectedBackground) end - ----Gets first selected item ----@return table ? selected The first item -function Collection:getSelectedItem() end - ----Gets the value of the Selectable property. ----@param self Collection self ----@return boolean true Whether items can be selected -function Collection:getSelectable(self) end - ----Gets the index of the first selected item ----@return number ? index The index of the first selected item, or nil if none selected -function Collection:getSelectedIndex() end - ----Sets the value of the Selectable property. ----@param self Collection self ----@param Selectable boolean Whether items can be selected -function Collection:setSelectable(self, Selectable) end - -function Collection:clearItemSelection() end - -function Collection:unselectItem() end - ----Gets the currently selected items ----@return table selected Collection of selected items -function Collection:getSelectedItems() end - ----Adds an item to the Collection ----@param text string |table The item to add (string or item table) ----@return Collection self The Collection instance -function Collection:addItem(text) end - ----Selects the previous item in the collection ----@return Collection self The Collection instance -function Collection:selectPrevious() end - ----Removes an item from the Collection ----@param index number The index of the item to remove ----@return Collection self The Collection instance -function Collection:removeItem(index) end - ----Gets the value of the MultiSelection property. ----@param self Collection self ----@return boolean false Whether multiple items can be selected at once -function Collection:getMultiSelection(self) end - ----Sets the value of the MultiSelection property. ----@param self Collection self ----@param MultiSelection boolean Whether multiple items can be selected at once -function Collection:setMultiSelection(self, MultiSelection) end - ----Clears all items from the Collection ----@return Collection self The Collection instance -function Collection:clear() end - -function Collection:selectItem() end - ----Registers a callback for the select event ----@param callback function The callback function to register ----@return Collection self The Collection instance -function Collection:onSelect(callback) end - ----@class Benchmark -local Benchmark = {} - ----Clears all custom benchmarks -function API.clearAll() end - ----Stops a custom benchmark ----@param name string The name of the benchmark to stop -function API.stop(name) end - ----Starts a custom benchmark ----@param name string The name of the benchmark -function API.start(name) end - ----Gets statistics for a benchmark ----@param name string The name of the benchmark ----@return table ? stats The benchmark statistics or nil -function API.getStats(name) end - ----Clears a specific benchmark ----@param name string The name of the benchmark to clear -function API.clear(name) end - ----@class Menu : List ----@field separatorColor color The color used for separator items in the menu ----@field horizontalOffset number Current horizontal scroll offset ----@field maxWidth number Maximum width before scrolling is enabled (nil = auto-size to items) ----@field spacing number The number of spaces between menu items -local Menu = {} - ----Sets the value of the SeparatorColor property. ----@param self Menu self ----@param SeparatorColor color The color used for separator items in the menu -function Menu:setSeparatorColor(self, SeparatorColor) end - ----Gets the value of the SeparatorColor property. ----@param self Menu self ----@return color gray The color used for separator items in the menu -function Menu:getSeparatorColor(self) end - ----Gets the value of the MaxWidth property. ----@param self Menu self ----@return number nil Maximum width before scrolling is enabled (nil = auto-size to items) -function Menu:getMaxWidth(self) end - ----Sets the value of the HorizontalOffset property. ----@param self Menu self ----@param HorizontalOffset number Current horizontal scroll offset -function Menu:setHorizontalOffset(self, HorizontalOffset) end - ----Gets the value of the Spacing property. ----@param self Menu self ----@return number 0 The number of spaces between menu items -function Menu:getSpacing(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Menu:mouse_scroll() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Menu:mouse_click() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Menu:render() end - ----Gets the value of the HorizontalOffset property. ----@param self Menu self ----@return number 0 Current horizontal scroll offset -function Menu:getHorizontalOffset(self) end - ----Calculates the total width of all menu items with spacing ----@return number totalWidth The total width of all items -function Menu:getTotalWidth() end - ----Sets the value of the Spacing property. ----@param self Menu self ----@param Spacing number The number of spaces between menu items -function Menu:setSpacing(self, Spacing) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Menu self The initialized instance ----@protected -function Menu:init(props, basalt) end - ----Sets the value of the MaxWidth property. ----@param self Menu self ----@param MaxWidth number Maximum width before scrolling is enabled (nil = auto-size to items) -function Menu:setMaxWidth(self, MaxWidth) end - ----@class BaseFrame : Container ----@field term term term.current() The terminal or (monitor) peripheral object to render to -local BaseFrame = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the mouse ----@param y number The y position of the mouse ----@protected -function BaseFrame:mouse_up(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param name string The name of the monitor that was touched ----@param x number The x position of the mouse ----@param y number The y position of the mouse ----@protected -function BaseFrame:monitor_touch(name, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param bg colors The background color ----@protected -function BaseFrame:drawBg(x, y, bg) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return table self The initialized instance ----@protected -function BaseFrame:init(props, basalt) end - ----Sets the cursor position ----@param x number The x position to set the cursor to ----@param y number The y position to set the cursor to ----@param blink boolean Whether the cursor should blink -function BaseFrame:setCursor(x, y, blink) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param fg colors The foreground color ----@protected -function BaseFrame:drawFg(x, y, fg) end - ----Gets the value of the Term property. ----@param self BaseFrame self ----@return term |peripheral term.current() The terminal or (monitor) peripheral object to render to -function BaseFrame:getTerm(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was released ----@protected -function BaseFrame:key_up(key) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BaseFrame:term_resize() end - ----Hides the debug log frame ----@param self BaseFrame The frame to hide debug log for -function BaseFrame.closeConsole(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@protected -function BaseFrame:drawText(x, y, text) end - ----Shows the debug log frame ----@param self BaseFrame The frame to show debug log in -function BaseFrame.openConsole(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@param fg colors The foreground color ----@protected -function BaseFrame:textFg(x, y, text, fg) end - ----Toggles the debug log frame ----@param self BaseFrame The frame to toggle debug log for -function BaseFrame.toggleConsole(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the mouse ----@param y number The y position of the mouse ----@protected -function BaseFrame:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BaseFrame:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param width number The width of the text ----@param height number The height of the text ----@param text string The text to render ----@param fg string The foreground color ----@param bg string The background color ----@protected -function BaseFrame:multiBlit(x, y, width, height, text, fg, bg) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was pressed ----@protected -function BaseFrame:char(char) end - ----Sets the value of the Term property. ----@param self BaseFrame self ----@param Term term term.current() The terminal or (monitor) peripheral object to render to -function BaseFrame:setTerm(self, Term) end +---@param name string The name of the series +---@return Graph self The graph instance +function Graph:removeSeries(name) end + +---@class TextBox : VisualElement +---@field autoCompleteMaxWidth number Maximum width of the autocomplete popup (0 uses the textbox width) +---@field autoPairNewlineIndent boolean On Enter between matching braces, create blank line and keep closing aligned +---@field autoPairCharacters table ["("]=")", ["["]="]", ["{"]="}", ['"']='"', ['\'']='\'', ['`']='`'} Mapping of opening to closing characters for auto pairing +---@field cursorColor number Color of the cursor +---@field autoCompleteAcceptOnEnter boolean Whether pressing Enter accepts the current suggestion +---@field autoCompleteAcceptOnClick boolean Whether clicking a suggestion accepts it immediately +---@field scrollX number Horizontal scroll offset +---@field autoCompleteOffsetY number Vertical offset applied to the popup frame relative to the TextBox bottom edge +---@field autoCompleteSelectedForeground color Foreground color for the selected suggestion +---@field autoCompleteForeground color Foreground color of the suggestion popup +---@field autoCompleteOffsetX number Horizontal offset applied to the popup frame relative to the TextBox +---@field autoCompleteSelectedBackground color Background color for the selected suggestion +---@field autoCompleteBackground color Background color of the suggestion popup +---@field autoPairEnabled boolean Whether automatic bracket/quote pairing is enabled +---@field autoCompleteBorderColor color Color of the popup border when enabled +---@field autoCompleteShowBorder boolean Whether to render a character border around the popup +---@field autoCompleteEnabled boolean Whether autocomplete suggestions are enabled +---@field autoCompleteCaseInsensitive boolean Whether suggestions should match case-insensitively +---@field autoCompleteProvider function Optional suggestion provider returning a list for the current prefix +---@field editable boolean Whether text can be edited +---@field autoCompleteCloseOnEscape boolean Whether pressing Escape closes the popup +---@field syntaxPatterns table Syntax highlighting patterns +---@field autoCompleteMaxItems number Maximum number of visible suggestions +---@field autoCompleteMinChars number Minimum characters required before showing suggestions +---@field cursorY number Cursor Y position (line number) +---@field autoCompleteItems table List of suggestions used when no provider is supplied +---@field scrollY number Vertical scroll offset +---@field autoCompleteTokenPattern string Pattern used to extract the current token for suggestions +---@field autoPairOverType boolean When pressing a closing char that matches the next char, move over it instead of inserting +---@field autoPairSkipClosing boolean Skip inserting a closing char if the same one is already at cursor +---@field autoCompleteZOffset number Z-index offset applied to the popup frame +---@field cursorX number Cursor X position +---@field lines table Array of text lines +local TextBox = {} + +---Updates the viewport to keep the cursor in view +---@return TextBox self The TextBox instance +function TextBox:updateViewport() end + +---Gets the value of the CursorY property. +---@param self TextBox self +---@return number 1 Cursor Y position (line number) +function TextBox:getCursorY(self) end + +---Gets the value of the AutoCompleteSelectedForeground property. +---@param self TextBox self +---@return color white Foreground color for the selected suggestion +function TextBox:getAutoCompleteSelectedForeground(self) end + +---Gets the value of the AutoCompleteAcceptOnClick property. +---@param self TextBox self +---@return boolean true Whether clicking a suggestion accepts it immediately +function TextBox:getAutoCompleteAcceptOnClick(self) end + +---Sets the value of the ScrollX property. +---@param self TextBox self +---@param ScrollX number Horizontal scroll offset +function TextBox:setScrollX(self, ScrollX) end + +---Sets the value of the AutoPairCharacters property. +---@param self TextBox self +---@param AutoPairCharacters table ["("]=")", ["["]="]", ["{"]="}", ['"']='"', ['\'']='\'', ['`']='`'} Mapping of opening to closing characters for auto pairing +function TextBox:setAutoPairCharacters(self, AutoPairCharacters) end + +---Sets the value of the AutoPairSkipClosing property. +---@param self TextBox self +---@param AutoPairSkipClosing boolean Skip inserting a closing char if the same one is already at cursor +function TextBox:setAutoPairSkipClosing(self, AutoPairSkipClosing) end + +---Sets the value of the AutoPairOverType property. +---@param self TextBox self +---@param AutoPairOverType boolean When pressing a closing char that matches the next char, move over it instead of inserting +function TextBox:setAutoPairOverType(self, AutoPairOverType) end + +---Gets the value of the ScrollX property. +---@param self TextBox self +---@return number 0 Horizontal scroll offset +function TextBox:getScrollX(self) end + +---Gets the value of the AutoCompleteZOffset property. +---@param self TextBox self +---@return number 1 Z-index offset applied to the popup frame +function TextBox:getAutoCompleteZOffset(self) end + +---Sets the value of the AutoPairEnabled property. +---@param self TextBox self +---@param AutoPairEnabled boolean Whether automatic bracket/quote pairing is enabled +function TextBox:setAutoPairEnabled(self, AutoPairEnabled) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param key number The key that was pressed +---@return boolean handled Whether the event was handled ---@protected -function BaseFrame:key(key) end +function TextBox:key(key) end -function BaseFrame:dispatchEvent() end +---Gets the value of the AutoPairOverType property. +---@param self TextBox self +---@return boolean true When pressing a closing char that matches the next char, move over it instead of inserting +function TextBox:getAutoPairOverType(self) end + +---Gets the value of the Lines property. +---@param self TextBox self +---@return table {} Array of text lines +function TextBox:getLines(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@param fg string The foreground color ----@param bg string The background color +---@param direction number The scroll direction +---@param x number The x position of the scroll +---@param y number The y position of the scroll +---@return boolean handled Whether the event was handled ---@protected -function BaseFrame:blit(x, y, text, fg, bg) end +function TextBox:mouse_scroll(direction, x, y) end + +---Removes a syntax pattern by index (1-based) +---@param index number The index of the pattern to remove +---@return TextBox self +function TextBox:removeSyntaxPattern(index) end + +---Gets the value of the AutoCompleteMaxItems property. +---@param self TextBox self +---@return number 6 Maximum number of visible suggestions +function TextBox:getAutoCompleteMaxItems(self) end + +---Gets the value of the SyntaxPatterns property. +---@param self TextBox self +---@return table {} Syntax highlighting patterns +function TextBox:getSyntaxPatterns(self) end + +---Gets the value of the ScrollY property. +---@param self TextBox self +---@return number 0 Vertical scroll offset +function TextBox:getScrollY(self) end + +---Gets the value of the Editable property. +---@param self TextBox self +---@return boolean true Whether text can be edited +function TextBox:getEditable(self) end + +---Sets the value of the Lines property. +---@param self TextBox self +---@param Lines table Array of text lines +function TextBox:setLines(self, Lines) end + +---Gets the value of the AutoPairSkipClosing property. +---@param self TextBox self +---@return boolean true Skip inserting a closing char if the same one is already at cursor +function TextBox:getAutoPairSkipClosing(self) end + +---Gets the value of the AutoCompleteShowBorder property. +---@param self TextBox self +---@return boolean true Whether to render a character border around the popup +function TextBox:getAutoCompleteShowBorder(self) end + +---Gets the value of the AutoCompleteMaxWidth property. +---@param self TextBox self +---@return number 0 Maximum width of the autocomplete popup (0 uses the textbox width) +function TextBox:getAutoCompleteMaxWidth(self) end + +---Sets the value of the AutoCompleteMaxWidth property. +---@param self TextBox self +---@param AutoCompleteMaxWidth number Maximum width of the autocomplete popup (0 uses the textbox width) +function TextBox:setAutoCompleteMaxWidth(self, AutoCompleteMaxWidth) end + +---Sets the value of the AutoCompleteOffsetY property. +---@param self TextBox self +---@param AutoCompleteOffsetY number Vertical offset applied to the popup frame relative to the TextBox bottom edge +function TextBox:setAutoCompleteOffsetY(self, AutoCompleteOffsetY) end + +function TextBox:destroy() end + +---Gets the value of the AutoCompleteAcceptOnEnter property. +---@param self TextBox self +---@return boolean true Whether pressing Enter accepts the current suggestion +function TextBox:getAutoCompleteAcceptOnEnter(self) end + +---Gets the value of the AutoCompleteOffsetX property. +---@param self TextBox self +---@return number 0 Horizontal offset applied to the popup frame relative to the TextBox +function TextBox:getAutoCompleteOffsetX(self) end + +---Sets the value of the CursorColor property. +---@param self TextBox self +---@param CursorColor number Color of the cursor +function TextBox:setCursorColor(self, CursorColor) end + +---Gets the value of the AutoCompleteItems property. +---@param self TextBox self +---@return table {} List of suggestions used when no provider is supplied +function TextBox:getAutoCompleteItems(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@param bg colors The background color ---@protected -function BaseFrame:textBg(x, y, text, bg) end +function TextBox:paste() end + +---Sets the value of the AutoCompleteForeground property. +---@param self TextBox self +---@param AutoCompleteForeground color Foreground color of the suggestion popup +function TextBox:setAutoCompleteForeground(self, AutoCompleteForeground) end + +---Sets the value of the SyntaxPatterns property. +---@param self TextBox self +---@param SyntaxPatterns table Syntax highlighting patterns +function TextBox:setSyntaxPatterns(self, SyntaxPatterns) end + +---Sets the value of the AutoCompleteMinChars property. +---@param self TextBox self +---@param AutoCompleteMinChars number Minimum characters required before showing suggestions +function TextBox:setAutoCompleteMinChars(self, AutoCompleteMinChars) end + +---Sets the value of the AutoCompleteOffsetX property. +---@param self TextBox self +---@param AutoCompleteOffsetX number Horizontal offset applied to the popup frame relative to the TextBox +function TextBox:setAutoCompleteOffsetX(self, AutoCompleteOffsetX) end + +---Sets the value of the AutoCompleteAcceptOnClick property. +---@param self TextBox self +---@param AutoCompleteAcceptOnClick boolean Whether clicking a suggestion accepts it immediately +function TextBox:setAutoCompleteAcceptOnClick(self, AutoCompleteAcceptOnClick) end + +---Sets the value of the AutoCompleteShowBorder property. +---@param self TextBox self +---@param AutoCompleteShowBorder boolean Whether to render a character border around the popup +function TextBox:setAutoCompleteShowBorder(self, AutoCompleteShowBorder) end + +---Gets the value of the AutoCompleteForeground property. +---@param self TextBox self +---@return color black Foreground color of the suggestion popup +function TextBox:getAutoCompleteForeground(self) end + +---Sets the value of the AutoCompleteMaxItems property. +---@param self TextBox self +---@param AutoCompleteMaxItems number Maximum number of visible suggestions +function TextBox:setAutoCompleteMaxItems(self, AutoCompleteMaxItems) end + +---Sets the value of the AutoCompleteSelectedBackground property. +---@param self TextBox self +---@param AutoCompleteSelectedBackground color Background color for the selected suggestion +function TextBox:setAutoCompleteSelectedBackground(self, AutoCompleteSelectedBackground) end + +---Sets the value of the AutoCompleteAcceptOnEnter property. +---@param self TextBox self +---@param AutoCompleteAcceptOnEnter boolean Whether pressing Enter accepts the current suggestion +function TextBox:setAutoCompleteAcceptOnEnter(self, AutoCompleteAcceptOnEnter) end + +---Gets the value of the AutoPairEnabled property. +---@param self TextBox self +---@return boolean true Whether automatic bracket/quote pairing is enabled +function TextBox:getAutoPairEnabled(self) end + +---Gets the value of the CursorX property. +---@param self TextBox self +---@return number 1 Cursor X position +function TextBox:getCursorX(self) end + +---Sets the value of the AutoCompleteTokenPattern property. +---@param self TextBox self +---@param AutoCompleteTokenPattern string Pattern used to extract the current token for suggestions +function TextBox:setAutoCompleteTokenPattern(self, AutoCompleteTokenPattern) end + +---Gets the value of the AutoPairNewlineIndent property. +---@param self TextBox self +---@return boolean true On Enter between matching braces, create blank line and keep closing aligned +function TextBox:getAutoPairNewlineIndent(self) end + +---Sets the value of the AutoCompleteBackground property. +---@param self TextBox self +---@param AutoCompleteBackground color Background color of the suggestion popup +function TextBox:setAutoCompleteBackground(self, AutoCompleteBackground) end + +---Gets the value of the AutoPairCharacters property. +---@param self TextBox self +---@return table { ["("]=")", ["["]="]", ["{"]="}", ['"']='"', ['\'']='\'', ['`']='`'} Mapping of opening to closing characters for auto pairing +function TextBox:getAutoPairCharacters(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function TextBox:render() end + +---Gets the value of the AutoCompleteSelectedBackground property. +---@param self TextBox self +---@return color gray Background color for the selected suggestion +function TextBox:getAutoCompleteSelectedBackground(self) end + +---Gets the value of the AutoCompleteEnabled property. +---@param self TextBox self +---@return boolean false Whether autocomplete suggestions are enabled +function TextBox:getAutoCompleteEnabled(self) end + +---Gets the value of the AutoCompleteProvider property. +---@param self TextBox self +---@return function nil Optional suggestion provider returning a list for the current prefix +function TextBox:getAutoCompleteProvider(self) end + +---Sets the value of the AutoCompleteZOffset property. +---@param self TextBox self +---@param AutoCompleteZOffset number Z-index offset applied to the popup frame +function TextBox:setAutoCompleteZOffset(self, AutoCompleteZOffset) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function TextBox:mouse_click(button, x, y) end + +---Sets the text of the TextBox +---@param text string The text to set +---@return TextBox self The TextBox instance +function TextBox:setText(text) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was typed +---@return boolean handled Whether the event was handled +---@protected +function TextBox:char(char) end + +---Gets the value of the CursorColor property. +---@param self TextBox self +---@return number nil Color of the cursor +function TextBox:getCursorColor(self) end + +---Clears all syntax highlighting patterns +---@return TextBox self +function TextBox:clearSyntaxPatterns() end + +---Sets the value of the AutoCompleteCloseOnEscape property. +---@param self TextBox self +---@param AutoCompleteCloseOnEscape boolean Whether pressing Escape closes the popup +function TextBox:setAutoCompleteCloseOnEscape(self, AutoCompleteCloseOnEscape) end + +---Sets the value of the AutoCompleteProvider property. +---@param self TextBox self +---@param AutoCompleteProvider function Optional suggestion provider returning a list for the current prefix +function TextBox:setAutoCompleteProvider(self, AutoCompleteProvider) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return TextBox self The initialized instance +---@protected +function TextBox:init(props, basalt) end + +---Adds a new syntax highlighting pattern +---@param pattern string The regex pattern to match +---@param color number The color to apply +---@return TextBox self The TextBox instance +function TextBox:addSyntaxPattern(pattern, color) end + +---Sets the value of the ScrollY property. +---@param self TextBox self +---@param ScrollY number Vertical scroll offset +function TextBox:setScrollY(self, ScrollY) end + +---Gets the value of the AutoCompleteCaseInsensitive property. +---@param self TextBox self +---@return boolean true Whether suggestions should match case-insensitively +function TextBox:getAutoCompleteCaseInsensitive(self) end + +---Gets the value of the AutoCompleteCloseOnEscape property. +---@param self TextBox self +---@return boolean true Whether pressing Escape closes the popup +function TextBox:getAutoCompleteCloseOnEscape(self) end + +---Sets the value of the AutoPairNewlineIndent property. +---@param self TextBox self +---@param AutoPairNewlineIndent boolean On Enter between matching braces, create blank line and keep closing aligned +function TextBox:setAutoPairNewlineIndent(self, AutoPairNewlineIndent) end + +---Sets the value of the AutoCompleteSelectedForeground property. +---@param self TextBox self +---@param AutoCompleteSelectedForeground color Foreground color for the selected suggestion +function TextBox:setAutoCompleteSelectedForeground(self, AutoCompleteSelectedForeground) end + +---Sets the value of the CursorX property. +---@param self TextBox self +---@param CursorX number Cursor X position +function TextBox:setCursorX(self, CursorX) end + +---Sets the value of the CursorY property. +---@param self TextBox self +---@param CursorY number Cursor Y position (line number) +function TextBox:setCursorY(self, CursorY) end + +---Sets the value of the AutoCompleteCaseInsensitive property. +---@param self TextBox self +---@param AutoCompleteCaseInsensitive boolean Whether suggestions should match case-insensitively +function TextBox:setAutoCompleteCaseInsensitive(self, AutoCompleteCaseInsensitive) end + +---Sets the value of the Editable property. +---@param self TextBox self +---@param Editable boolean Whether text can be edited +function TextBox:setEditable(self, Editable) end + +---Sets the value of the AutoCompleteItems property. +---@param self TextBox self +---@param AutoCompleteItems table List of suggestions used when no provider is supplied +function TextBox:setAutoCompleteItems(self, AutoCompleteItems) end + +---Gets the value of the AutoCompleteTokenPattern property. +---@param self TextBox self +---@return string "[%w_]+" Pattern used to extract the current token for suggestions +function TextBox:getAutoCompleteTokenPattern(self) end + +---Gets the value of the AutoCompleteOffsetY property. +---@param self TextBox self +---@return number 1 Vertical offset applied to the popup frame relative to the TextBox bottom edge +function TextBox:getAutoCompleteOffsetY(self) end + +---Gets the value of the AutoCompleteBorderColor property. +---@param self TextBox self +---@return color black Color of the popup border when enabled +function TextBox:getAutoCompleteBorderColor(self) end + +---Sets the value of the AutoCompleteEnabled property. +---@param self TextBox self +---@param AutoCompleteEnabled boolean Whether autocomplete suggestions are enabled +function TextBox:setAutoCompleteEnabled(self, AutoCompleteEnabled) end + +---Gets the value of the AutoCompleteBackground property. +---@param self TextBox self +---@return color lightGray Background color of the suggestion popup +function TextBox:getAutoCompleteBackground(self) end + +---Gets the value of the AutoCompleteMinChars property. +---@param self TextBox self +---@return number 1 Minimum characters required before showing suggestions +function TextBox:getAutoCompleteMinChars(self) end + +---Gets the text of the TextBox +---@return string text The text of the TextBox +function TextBox:getText() end + +---Sets the value of the AutoCompleteBorderColor property. +---@param self TextBox self +---@param AutoCompleteBorderColor color Color of the popup border when enabled +function TextBox:setAutoCompleteBorderColor(self, AutoCompleteBorderColor) end ---@class Toast : VisualElement ----@field duration number Duration in seconds before the toast auto-hides ----@field colorMap table of toast types to their colors ---@field title string The title text of the toast ----@field autoHide boolean Whether the toast should automatically hide after duration ----@field message string The message text of the toast +---@field colorMap table of toast types to their colors ---@field toastType string Type of toast: default, success, error, warning, info ---@field active boolean Whether the toast is currently showing a message +---@field autoHide boolean Whether the toast should automatically hide after duration +---@field duration number Duration in seconds before the toast auto-hides +---@field message string The message text of the toast local Toast = {} +---Gets the value of the Title property. +---@param self Toast self +---@return string "" The title text of the toast +function Toast:getTitle(self) end + ---Sets the value of the Active property. ---@param self Toast self ---@param Active boolean Whether the toast is currently showing a message @@ -5365,202 +3400,181 @@ function Toast:setActive(self, Active) end ---@protected function Toast:dispatchEvent() end ----Shows an info toast ----@param titleOrMessage string The title or message ----@return Toast self The Toast instance -function Toast:info(titleOrMessage) end - ----Gets the value of the ToastType property. +---Gets the value of the ColorMap property. ---@param self Toast self ----@return string "default" Type of toast: default, success, error, warning, info -function Toast:getToastType(self) end - ----Sets the value of the AutoHide property. ----@param self Toast self ----@param AutoHide boolean Whether the toast should automatically hide after duration -function Toast:setAutoHide(self, AutoHide) end - ----Hides the toast ----@return Toast self The Toast instance -function Toast:hide() end - ----Sets the value of the Duration property. ----@param self Toast self ----@param Duration number Duration in seconds before the toast auto-hides -function Toast:setDuration(self, Duration) end - ----Gets the value of the AutoHide property. ----@param self Toast self ----@return boolean true Whether the toast should automatically hide after duration -function Toast:getAutoHide(self) end +---@return table Map of toast types to their colors +function Toast:getColorMap(self) end ---Sets the value of the ColorMap property. ---@param self Toast self ---@param ColorMap table of toast types to their colors function Toast:setColorMap(self, ColorMap) end ----Shows a warning toast ----@param titleOrMessage string The title or message +---Hides the toast ---@return Toast self The Toast instance -function Toast:warning(titleOrMessage) end - ----Sets the value of the Message property. ----@param self Toast self ----@param Message string The message text of the toast -function Toast:setMessage(self, Message) end - ----Gets the value of the Active property. ----@param self Toast self ----@return boolean false Whether the toast is currently showing a message -function Toast:getActive(self) end +function Toast:hide() end ---Sets the value of the Title property. ---@param self Toast self ---@param Title string The title text of the toast function Toast:setTitle(self, Title) end ----Renders the toast ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Toast:render() end - ----Gets the value of the Title property. +---Sets the value of the Message property. ---@param self Toast self ----@return string "" The title text of the toast -function Toast:getTitle(self) end +---@param Message string The message text of the toast +function Toast:setMessage(self, Message) end ----Shows an error toast ----@param titleOrMessage string The title or message ----@return Toast self The Toast instance -function Toast:error(titleOrMessage) end +---Gets the value of the ToastType property. +---@param self Toast self +---@return string "default" Type of toast: default, success, error, warning, info +function Toast:getToastType(self) end ----Shows a success toast ----@param titleOrMessage string The title or message ----@return Toast self The Toast instance -function Toast:success(titleOrMessage) end +---Gets the value of the AutoHide property. +---@param self Toast self +---@return boolean true Whether the toast should automatically hide after duration +function Toast:getAutoHide(self) end + +---Sets the value of the Duration property. +---@param self Toast self +---@param Duration number Duration in seconds before the toast auto-hides +function Toast:setDuration(self, Duration) end ---Gets the value of the Duration property. ---@param self Toast self ---@return number 3 Duration in seconds before the toast auto-hides function Toast:getDuration(self) end ----Sets the value of the ToastType property. ----@param self Toast self ----@param ToastType string Type of toast: default, success, error, warning, info -function Toast:setToastType(self, ToastType) end - ----Gets the value of the Message property. ----@param self Toast self ----@return string "" The message text of the toast -function Toast:getMessage(self) end +---Renders the toast +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Toast:render() end ---Shows a toast message ---@param titleOrMessage string The title (if message provided) or the message (if no message) ---@return Toast self The Toast instance function Toast:show(titleOrMessage) end ----Gets the value of the ColorMap property. +---Sets the value of the ToastType property. ---@param self Toast self ----@return table Map of toast types to their colors -function Toast:getColorMap(self) end +---@param ToastType string Type of toast: default, success, error, warning, info +function Toast:setToastType(self, ToastType) end ----@class Button : VisualElement ----@field text string Label text displayed centered within the button -local Button = {} +---Shows a warning toast +---@param titleOrMessage string The title or message +---@return Toast self The Toast instance +function Toast:warning(titleOrMessage) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Button:init(props, basalt) end +---Shows a success toast +---@param titleOrMessage string The title or message +---@return Toast self The Toast instance +function Toast:success(titleOrMessage) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Button:render() end +---Shows an error toast +---@param titleOrMessage string The title or message +---@return Toast self The Toast instance +function Toast:error(titleOrMessage) end ----Gets the value of the Text property. ----@param self Button self ----@return string Button Label text displayed centered within the button -function Button:getText(self) end +---Sets the value of the AutoHide property. +---@param self Toast self +---@param AutoHide boolean Whether the toast should automatically hide after duration +function Toast:setAutoHide(self, AutoHide) end ----Sets the value of the Text property. ----@param self Button self ----@param Text string Label text displayed centered within the button -function Button:setText(self, Text) end +---Gets the value of the Message property. +---@param self Toast self +---@return string "" The message text of the toast +function Toast:getMessage(self) end ----@class BarChart : Graph -local BarChart = {} +---Shows an info toast +---@param titleOrMessage string The title or message +---@return Toast self The Toast instance +function Toast:info(titleOrMessage) end ----Renders the bar chart by calculating bar positions and heights based on data values ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BarChart:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return BarChart self The initialized instance ----@protected -function BarChart:init(props, basalt) end +---Gets the value of the Active property. +---@param self Toast self +---@return boolean false Whether the toast is currently showing a message +function Toast:getActive(self) end ---@class SideNav : Container ----@field tabs table List of navigation item definitions ----@field sidebarBackground color Background color for the sidebar area ---@field sidebarScrollOffset number Current scroll offset for navigation items in scrollable mode ----@field activeTabTextColor color Foreground color for the active navigation item text ----@field sidebarPosition string Position of the sidebar ("left" or "right") ----@field sidebarWidth number Width of the sidebar navigation area ----@field activeTabBackground color Background color for the active navigation item ---@field activeTab number The currently active navigation item ID +---@field activeTabTextColor color Foreground color for the active navigation item text +---@field activeTabBackground color Background color for the active navigation item +---@field sidebarPosition string Position of the sidebar ("left" or "right") +---@field tabs table List of navigation item definitions +---@field sidebarWidth number Width of the sidebar navigation area +---@field sidebarBackground color Background color for the sidebar area local SideNav = {} -function SideNav:mouse_scroll() end - -function SideNav:drawBg() end - ----Sets the value of the SidebarWidth property. +---Sets the value of the SidebarPosition property. ---@param self SideNav self ----@param SidebarWidth number Width of the sidebar navigation area -function SideNav:setSidebarWidth(self, SidebarWidth) end +---@param SidebarPosition string Position of the sidebar ("left" or "right") +function SideNav:setSidebarPosition(self, SidebarPosition) end + +---Gets the value of the SidebarScrollOffset property. +---@param self SideNav self +---@return number 0 Current scroll offset for navigation items in scrollable mode +function SideNav:getSidebarScrollOffset(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected function SideNav:sortChildrenEvents() end -function SideNav:mouse_move() end +---@param element table The element to assign to a navigation item +---@param tabId number The ID of the navigation item to assign the element to +---@return SideNav self For method chaining +function SideNav:setTab(element, tabId) end ----@param elementType string The type of element to add ----@param tabId number Optional navigation item ID, defaults to active item ----@return table element The created element -function SideNav:addElement(elementType, tabId) end +---Gets the value of the ActiveTabTextColor property. +---@param self SideNav self +---@return color black Foreground color for the active navigation item text +function SideNav:getActiveTabTextColor(self) end + +function SideNav:mouse_up() end + +---Gets the value of the SidebarBackground property. +---@param self SideNav self +---@return color gray Background color for the sidebar area +function SideNav:getSidebarBackground(self) end + +function SideNav:mouse_release() end + +function SideNav:setCursor() end + +function SideNav:blit() end + +function SideNav:drawBg() end ---Gets the value of the Tabs property. ---@param self SideNav self ---@return table {} List of navigation item definitions function SideNav:getTabs(self) end +function SideNav:getRelativePosition() end + +---Sets the value of the ActiveTabTextColor property. +---@param self SideNav self +---@param ActiveTabTextColor color Foreground color for the active navigation item text +function SideNav:setActiveTabTextColor(self, ActiveTabTextColor) end + +function SideNav:multiBlit() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param child table The child element to add +---@return Container self For method chaining +---@protected +function SideNav:addChild(child) end + ---Gets the value of the ActiveTabBackground property. ---@param self SideNav self ---@return color white Background color for the active navigation item function SideNav:getActiveTabBackground(self) end ----Sets the value of the Tabs property. +---Sets the value of the SidebarScrollOffset property. ---@param self SideNav self ----@param Tabs table List of navigation item definitions -function SideNav:setTabs(self, Tabs) end +---@param SidebarScrollOffset number Current scroll offset for navigation items in scrollable mode +function SideNav:setSidebarScrollOffset(self, SidebarScrollOffset) end -function SideNav:setCursor() end - -function SideNav:mouse_drag() end - ----Gets the value of the SidebarPosition property. ----@param self SideNav self ----@return string left Position of the sidebar ("left" or "right") -function SideNav:getSidebarPosition(self) end - -function SideNav:blit() end - -function SideNav:textFg() end +function SideNav:_getSidebarMetrics() end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The button that was clicked @@ -5570,26 +3584,27 @@ function SideNav:textFg() end ---@protected function SideNav:mouse_click(button, x, y) end -function SideNav:drawFg() end +function SideNav:textFg() end + +function SideNav:textBg() end + +---returns a proxy for adding elements to the navigation item +---@param title string The title of the navigation item +---@return table tabHandler The navigation item handler proxy for adding elements +function SideNav:newTab(title) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected function SideNav:render() end ----Sets the value of the SidebarBackground property. ----@param self SideNav self ----@param SidebarBackground color Background color for the sidebar area -function SideNav:setSidebarBackground(self, SidebarBackground) end +function SideNav:mouse_scroll() end ----Gets the value of the ActiveTabTextColor property. ----@param self SideNav self ----@return color black Foreground color for the active navigation item text -function SideNav:getActiveTabTextColor(self) end +---Scrolls the sidebar up or down +---@param direction number -1 to scroll up, 1 to scroll down +---@return SideNav self For method chaining +function SideNav:scrollSidebar(direction) end ----Sets the value of the SidebarScrollOffset property. ----@param self SideNav self ----@param SidebarScrollOffset number Current scroll offset for navigation items in scrollable mode -function SideNav:setSidebarScrollOffset(self, SidebarScrollOffset) end +function SideNav:mouse_drag() end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param child table The child element to check @@ -5597,47 +3612,43 @@ function SideNav:setSidebarScrollOffset(self, SidebarScrollOffset) end ---@protected function SideNav:isChildVisible(child) end ----Sets the value of the SidebarPosition property. +---Gets the value of the SidebarPosition property. ---@param self SideNav self ----@param SidebarPosition string Position of the sidebar ("left" or "right") -function SideNav:setSidebarPosition(self, SidebarPosition) end +---@return string left Position of the sidebar ("left" or "right") +function SideNav:getSidebarPosition(self) end -function SideNav:textBg() end - ----Gets the value of the SidebarScrollOffset property. ----@param self SideNav self ----@return number 0 Current scroll offset for navigation items in scrollable mode -function SideNav:getSidebarScrollOffset(self) end +function SideNav:mouse_move() end ---@param tabId number The ID of the navigation item to activate function SideNav:setActiveTab(tabId) end -function SideNav:_getSidebarMetrics() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return number xOffset The X offset for content ----@protected -function SideNav:getContentXOffset() end - ----Sets the value of the ActiveTabTextColor property. ----@param self SideNav self ----@param ActiveTabTextColor color Foreground color for the active navigation item text -function SideNav:setActiveTabTextColor(self, ActiveTabTextColor) end - ----Scrolls the sidebar up or down ----@param direction number -1 to scroll up, 1 to scroll down ----@return SideNav self For method chaining -function SideNav:scrollSidebar(direction) end - -function SideNav:mouse_release() end - ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with ---@param basalt table The basalt instance ---@protected function SideNav:init(props, basalt) end -function SideNav:getRelativePosition() end +function SideNav:drawText() end + +---Gets the value of the SidebarWidth property. +---@param self SideNav self +---@return number 12 Width of the sidebar navigation area +function SideNav:getSidebarWidth(self) end + +---Sets the value of the Tabs property. +---@param self SideNav self +---@param Tabs table List of navigation item definitions +function SideNav:setTabs(self, Tabs) end + +---Sets the value of the SidebarBackground property. +---@param self SideNav self +---@param SidebarBackground color Background color for the sidebar area +function SideNav:setSidebarBackground(self, SidebarBackground) end + +---@param elementType string The type of element to add +---@param tabId number Optional navigation item ID, defaults to active item +---@return table element The created element +function SideNav:addElement(elementType, tabId) end ---Sets the value of the ActiveTabBackground property. ---@param self SideNav self @@ -5645,42 +3656,2042 @@ function SideNav:getRelativePosition() end function SideNav:setActiveTabBackground(self, ActiveTabBackground) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param child table The child element to add ----@return Container self For method chaining +---@return number xOffset The X offset for content ---@protected -function SideNav:addChild(child) end - ----returns a proxy for adding elements to the navigation item ----@param title string The title of the navigation item ----@return table tabHandler The navigation item handler proxy for adding elements -function SideNav:newTab(title) end - ----Gets the value of the SidebarWidth property. ----@param self SideNav self ----@return number 12 Width of the sidebar navigation area -function SideNav:getSidebarWidth(self) end +function SideNav:getContentXOffset() end ---Gets the value of the ActiveTab property. ---@param self SideNav self ---@return number nil The currently active navigation item ID function SideNav:getActiveTab(self) end -function SideNav:drawText() end +function SideNav:drawFg() end ----Gets the value of the SidebarBackground property. +---Sets the value of the SidebarWidth property. ---@param self SideNav self ----@return color gray Background color for the sidebar area -function SideNav:getSidebarBackground(self) end +---@param SidebarWidth number Width of the sidebar navigation area +function SideNav:setSidebarWidth(self, SidebarWidth) end ----@param element table The element to assign to a navigation item ----@param tabId number The ID of the navigation item to assign the element to ----@return SideNav self For method chaining -function SideNav:setTab(element, tabId) end +---@class ThemeAPI +local ThemeAPI = {} -function SideNav:mouse_up() end +---Gets the current theme configuration +---@return table theme The current theme configuration +function ThemeAPI.getTheme() end -function SideNav:multiBlit() end +---Loads a theme from a JSON file +---@param path string Path to the theme JSON file +function ThemeAPI.loadTheme(path) end ----@class Reactive -local Reactive = {} +---Sets the current theme +---@param newTheme table The theme configuration to set +function ThemeAPI.setTheme(newTheme) end + +---@class Container : VisualElement +---@field focusedChild table Currently focused child element (receives keyboard events) +---@field offsetX number Horizontal scroll/content offset +---@field childrenEvents table Registered event handlers for all children +---@field visibleChildren table Currently visible child elements (calculated based on viewport) +---@field children table Collection of all child elements +---@field eventListenerCount table Number of listeners per event type +---@field offsetY number Vertical scroll/content offset +---@field childrenSorted boolean Indicates if children are sorted by z-index +---@field visibleChildrenEvents table Event handlers for currently visible children +---@field childrenEventsSorted boolean Indicates if event handlers are properly sorted +local Container = {} + +---Registers an event handler for a specific child element +---@param child table The child element to register events for +---@param eventName string The name of the event to register +---@return Container self For method chaining +function Container:registerChildEvent(child, eventName) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was pressed +---@return boolean handled Whether the event was handled +---@protected +function Container:key(key) end + +---Sets the value of the ChildrenEventsSorted property. +---@param self Container self +---@param ChildrenEventsSorted boolean Indicates if event handlers are properly sorted +function Container:setChildrenEventsSorted(self, ChildrenEventsSorted) end + +---Updates the current layout (recalculates positions) +---@return Container self For method chaining +function Container:updateLayout() end + +---Tests whether a child element is currently visible within the container's viewport +---@param child table The child element to check +---@return boolean isVisible Whether the child is within view bounds +function Container:isChildVisible(child) end + +---Creates a new Slider element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Slider element A new Slider element. +function Container:addSlider(self, props) end + +---Removes all child elements and resets the container's state +---@return Container self For method chaining +function Container:clear() end + +---Registers the children events of the container +---@param child table The child to register events for +---@return Container self The container instance +function Container:registerChildrenEvents(child) end + +---Creates a new Switch element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Switch element A new Switch element. +function Container:addSwitch(self, props) end + +---Enables benchmarking for a container and all its children +---@param methodName string The method to benchmark +---@return Container self The container instance +function Container:benchmarkContainer(methodName) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param width number The width of the text +---@param height number The height of the text +---@param text string The text to draw +---@param fg string The foreground color of the text +---@param bg string The background color of the text +---@return Container self The container instance +---@protected +function Container:multiBlit(x, y, width, height, text, fg, bg) end + +---Gets the value of the ChildrenEvents property. +---@param self Container self +---@return table {} Registered event handlers for all children +function Container:getChildrenEvents(self) end + +---Sets the value of the ChildrenEvents property. +---@param self Container self +---@param ChildrenEvents table Registered event handlers for all children +function Container:setChildrenEvents(self, ChildrenEvents) end + +---Creates a new Button element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Button element A new Button element. +function Container:addButton(self, props) end + +---Re-sorts children by their z-index and updates visibility +---@return Container self For method chaining +function Container:sortChildren() end + +---Unregisters the children events of the container +---@param child table The child to unregister events for +---@param eventName string The event name to unregister +---@return Container self The container instance +function Container:unregisterChildEvent(child, eventName) end + +---Creates a new Collection element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Collection element A new Collection element. +function Container:addCollection(self, props) end + +---Adds a new element to this container's hierarchy +---@param child table The element to add as a child +---@return Container self For method chaining +function Container:addChild(child) end + +---Sets the value of the VisibleChildrenEvents property. +---@param self Container self +---@param VisibleChildrenEvents table Event handlers for currently visible children +function Container:setVisibleChildrenEvents(self, VisibleChildrenEvents) end + +function Container:drawBg() end + +---Gets the value of the OffsetY property. +---@param self Container self +---@return number 0 Vertical scroll/content offset +function Container:getOffsetY(self) end + +---Creates a new BigFont element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BigFont element A new BigFont element. +function Container:addBigFont(self, props) end + +---Creates a new BaseElement element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BaseElement element A new BaseElement element. +function Container:addBaseElement(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return boolean handled Whether the event was handled +---@protected +function Container:handleEvent(event) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@protected +function Container:mouse_release(button, x, y) end + +---Creates a new CheckBox element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return CheckBox element A new CheckBox element. +function Container:addCheckBox(self, props) end + +---Gets the value of the ChildrenEventsSorted property. +---@param self Container self +---@return boolean true Indicates if event handlers are properly sorted +function Container:getChildrenEventsSorted(self) end + +---Sets the value of the Children property. +---@param self Container self +---@param Children table Collection of all child elements +function Container:setChildren(self, Children) end + +---Gets the value of the FocusedChild property. +---@param self Container self +---@return table nil Currently focused child element (receives keyboard events) +function Container:getFocusedChild(self) end + +---Creates a new Container element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Container element A new Container element. +function Container:addContainer(self, props) end + +---Creates a new List element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return List element A new List element. +function Container:addList(self, props) end + +---Gets the value of the VisibleChildren property. +---@param self Container self +---@return table {} Currently visible child elements (calculated based on viewport) +function Container:getVisibleChildren(self) end + +---Enables debugging for this container and all its children +---@param self Container The container to debug +---@param level number The debug level +function Container.debugChildren(self, level) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Container:init(props, basalt) end + +---Creates a new BaseFrame element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BaseFrame element A new BaseFrame element. +function Container:addBaseFrame(self, props) end + +---Creates a new VisualElement element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return VisualElement element A new VisualElement element. +function Container:addVisualElement(self, props) end + +---Creates a new Label element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Label element A new Label element. +function Container:addLabel(self, props) end + +---Gets the value of the Children property. +---@param self Container self +---@return table {} Collection of all child elements +function Container:getChildren(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was pressed +---@return boolean handled Whether the event was handled +---@protected +function Container:char(char) end + +---Sets the value of the OffsetY property. +---@param self Container self +---@param OffsetY number Vertical scroll/content offset +function Container:setOffsetY(self, OffsetY) end + +---Sets the value of the FocusedChild property. +---@param self Container self +---@param FocusedChild table Currently focused child element (receives keyboard events) +function Container:setFocusedChild(self, FocusedChild) end + +---Gets the value of the OffsetX property. +---@param self Container self +---@return number 0 Horizontal scroll/content offset +function Container:getOffsetX(self) end + +---Creates a new TextBox element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return TextBox element A new TextBox element. +function Container:addTextBox(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param text string The text to draw +---@param bg color The background color of the text +---@return Container self The container instance +---@protected +function Container:textBg(x, y, text, bg) end + +---Applies a layout from a file to this container +---@param layoutPath string Path to the layout file (e.g. "layouts/grid") +---@return Container self For method chaining +function Container:applyLayout(layoutPath) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was released +---@return boolean handled Whether the event was handled +---@protected +function Container:key_up(key) end + +---Creates a new Menu element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Menu element A new Menu element. +function Container:addMenu(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param text string The text to draw +---@param fg string The foreground color of the text +---@param bg string The background color of the text +---@return Container self The container instance +---@protected +function Container:blit(x, y, text, fg, bg) end + +function Container:drawText() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_click(button, x, y) end + +---Creates a new SideNav element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return SideNav element A new SideNav element. +function Container:addSideNav(self, props) end + +---Creates a new ScrollBar element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ScrollBar element A new ScrollBar element. +function Container:addScrollBar(self, props) end + +---Locates a child element using a path-like syntax (e.g. "panel/button1") +---@param path string Path to the child (e.g. "panel/button1", "header/title") +---@return Element ? child The found element or nil if not found +function Container:getChild(path) end + +---Creates a new ContextMenu element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ContextMenu element A new ContextMenu element. +function Container:addContextMenu(self, props) end + +---Creates a new Tree element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Tree element A new Tree element. +function Container:addTree(self, props) end + +---Gets the value of the VisibleChildrenEvents property. +---@param self Container self +---@return table {} Event handlers for currently visible children +function Container:getVisibleChildrenEvents(self) end + +---Sets the value of the OffsetX property. +---@param self Container self +---@param OffsetX number Horizontal scroll/content offset +function Container:setOffsetX(self, OffsetX) end + +---Calls a event on all children +---@param visibleOnly boolean Whether to only call the event on visible children +---@param event string The event to call +---@return boolean handled Whether the event was handled +---@return table ? child The child that handled the event +function Container:callChildrenEvent(visibleOnly, event) end + +---Creates a new Program element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Program element A new Program element. +function Container:addProgram(self, props) end + +---Sorts the children events of the container +---@param eventName string The event name to sort +---@return Container self The container instance +function Container:sortChildrenEvents(eventName) end + +---Creates a new Toast element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Toast element A new Toast element. +function Container:addToast(self, props) end + +---Gets the value of the ChildrenSorted property. +---@param self Container self +---@return boolean true Indicates if children are sorted by z-index +function Container:getChildrenSorted(self) end + +---Creates a new BarChart element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BarChart element A new BarChart element. +function Container:addBarChart(self, props) end + +---Unregisters the children events of the container +---@param child table The child to unregister events for +---@return Container self The container instance +function Container:removeChildrenEvents(child) end + +---Creates a new ProgressBar element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ProgressBar element A new ProgressBar element. +function Container:addProgressBar(self, props) end + +---Sets the value of the ChildrenSorted property. +---@param self Container self +---@param ChildrenSorted boolean Indicates if children are sorted by z-index +function Container:setChildrenSorted(self, ChildrenSorted) end + +---Removes the current layout +---@return Container self For method chaining +function Container:clearLayout() end + +---Removes an element from this container's hierarchy and cleans up its events +---@param child table The element to remove +---@return Container self For method chaining +function Container:removeChild(child) end + +---Stops benchmarking for a container and all its children +---@param methodName string The method to stop benchmarking +---@return Container self The container instance +function Container:stopContainerBenchmark(methodName) end + +---Creates a new Display element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Display element A new Display element. +function Container:addDisplay(self, props) end + +---Sets the value of the EventListenerCount property. +---@param self Container self +---@param EventListenerCount table Number of listeners per event type +function Container:setEventListenerCount(self, EventListenerCount) end + +---Creates a new Input element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Input element A new Input element. +function Container:addInput(self, props) end + +---Creates a new Graph element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Graph element A new Graph element. +function Container:addGraph(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Container:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The direction of the scroll +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_scroll(direction, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param text string The text to draw +---@param fg color The foreground color of the text +---@return Container self The container instance +---@protected +function Container:textFg(x, y, text, fg) end + +---Creates a new Timer element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Timer element A new Timer element. +function Container:addTimer(self, props) end + +---Creates a new ScrollFrame element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ScrollFrame element A new ScrollFrame element. +function Container:addScrollFrame(self, props) end + +---Creates a new Frame element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Frame element A new Frame element. +function Container:addFrame(self, props) end + +---Creates a new TabControl element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return TabControl element A new TabControl element. +function Container:addTabControl(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param _ number unknown +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_move(_, x, y) end + +---Creates a new LineChart element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return LineChart element A new LineChart element. +function Container:addLineChart(self, props) end + +---Creates a new ComboBox element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ComboBox element A new ComboBox element. +function Container:addComboBox(self, props) end + +---Creates a new DropDown element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return DropDown element A new DropDown element. +function Container:addDropDown(self, props) end + +---Creates a new Image element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Image element A new Image element. +function Container:addImage(self, props) end + +---Creates a new Accordion element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Accordion element A new Accordion element. +function Container:addAccordion(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_drag(button, x, y) end + +---Creates a new Breadcrumb element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Breadcrumb element A new Breadcrumb element. +function Container:addBreadcrumb(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_up(button, x, y) end + +---Creates a new Table element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Table element A new Table element. +function Container:addTable(self, props) end + +---Logs benchmark statistics for a container and all its children +---@param methodName string The method to log +---@return Container self The container instance +function Container:logContainerBenchmarks(methodName) end + +---Sets the value of the VisibleChildren property. +---@param self Container self +---@param VisibleChildren table Currently visible child elements (calculated based on viewport) +function Container:setVisibleChildren(self, VisibleChildren) end + +function Container:drawFg() end + +---Gets the value of the EventListenerCount property. +---@param self Container self +---@return table {} Number of listeners per event type +function Container:getEventListenerCount(self) end + +---Creates a new Dialog element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Dialog element A new Dialog element. +function Container:addDialog(self, props) end + +---@class Benchmark +local Benchmark = {} + +---Clears a specific benchmark +---@param name string The name of the benchmark to clear +function API.clear(name) end + +---Starts a custom benchmark +---@param name string The name of the benchmark +function API.start(name) end + +---Gets statistics for a benchmark +---@param name string The name of the benchmark +---@return table ? stats The benchmark statistics or nil +function API.getStats(name) end + +---Clears all custom benchmarks +function API.clearAll() end + +---Stops a custom benchmark +---@param name string The name of the benchmark to stop +function API.stop(name) end + +---@class Accordion : Container +---@field panelHeaderHeight number Height of each panel header +---@field allowMultiple boolean Allow multiple panels to be open at once +---@field panels table List of panel definitions +---@field headerBackground color Background color for panel headers +---@field headerTextColor color Text color for panel headers +---@field expandedHeaderTextColor color Text color for expanded panel headers +---@field expandedHeaderBackground color Background color for expanded panel headers +local Accordion = {} + +---@param panelId number The ID of the panel +---@return table ? container The panel's container or nil +function Accordion:getPanel(panelId) end + +---Sets the value of the ExpandedHeaderTextColor property. +---@param self Accordion self +---@param ExpandedHeaderTextColor color Text color for expanded panel headers +function Accordion:setExpandedHeaderTextColor(self, ExpandedHeaderTextColor) end + +---Sets the value of the Panels property. +---@param self Accordion self +---@param Panels table List of panel definitions +function Accordion:setPanels(self, Panels) end + +---Sets the value of the HeaderTextColor property. +---@param self Accordion self +---@param HeaderTextColor color Text color for panel headers +function Accordion:setHeaderTextColor(self, HeaderTextColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Accordion:render() end + +---Creates a new panel and returns the panel's container +---@param title string The title of the panel +---@param expanded boolean Whether the panel starts expanded (default: false) +---@return table panelContainer The container for this panel +function Accordion:newPanel(title, expanded) end + +---@param panelId number The ID of the panel to toggle +---@return Accordion self For method chaining +function Accordion:togglePanel(panelId) end + +---Sets the value of the PanelHeaderHeight property. +---@param self Accordion self +---@param PanelHeaderHeight number Height of each panel header +function Accordion:setPanelHeaderHeight(self, PanelHeaderHeight) end + +---Sets the value of the HeaderBackground property. +---@param self Accordion self +---@param HeaderBackground color Background color for panel headers +function Accordion:setHeaderBackground(self, HeaderBackground) end + +---Gets the value of the AllowMultiple property. +---@param self Accordion self +---@return boolean false Allow multiple panels to be open at once +function Accordion:getAllowMultiple(self) end + +---@param panelId number The ID of the panel to collapse +---@return Accordion self For method chaining +function Accordion:collapsePanel(panelId) end + +---Gets the value of the Panels property. +---@param self Accordion self +---@return table {} List of panel definitions +function Accordion:getPanels(self) end + +---Sets the value of the ExpandedHeaderBackground property. +---@param self Accordion self +---@param ExpandedHeaderBackground color Background color for expanded panel headers +function Accordion:setExpandedHeaderBackground(self, ExpandedHeaderBackground) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click (global) +---@param y number The y position of the click (global) +---@return boolean Whether the event was handled +---@protected +function Accordion:mouse_click(button, x, y) end + +---Gets the value of the ExpandedHeaderBackground property. +---@param self Accordion self +---@return color lightGray Background color for expanded panel headers +function Accordion:getExpandedHeaderBackground(self) end + +---Sets the value of the AllowMultiple property. +---@param self Accordion self +---@param AllowMultiple boolean Allow multiple panels to be open at once +function Accordion:setAllowMultiple(self, AllowMultiple) end + +---Gets the value of the ExpandedHeaderTextColor property. +---@param self Accordion self +---@return color black Text color for expanded panel headers +function Accordion:getExpandedHeaderTextColor(self) end + +---Gets the value of the HeaderBackground property. +---@param self Accordion self +---@return color gray Background color for panel headers +function Accordion:getHeaderBackground(self) end + +---Gets the value of the HeaderTextColor property. +---@param self Accordion self +---@return color white Text color for panel headers +function Accordion:getHeaderTextColor(self) end + +function Accordion:mouse_scroll() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Accordion:init(props, basalt) end + +---Gets the value of the PanelHeaderHeight property. +---@param self Accordion self +---@return number 1 Height of each panel header +function Accordion:getPanelHeaderHeight(self) end + +---@param panelId number The ID of the panel to expand +---@return Accordion self For method chaining +function Accordion:expandPanel(panelId) end + +---@class VisualElement : BaseElement +---@field layoutConfig table Configuration for layout systems (grow, shrink, alignSelf, etc.) +---@field height number The height of the element +---@field borderLeft boolean Draw left border +---@field backgroundEnabled boolean Whether to render the background +---@field borderBottom boolean Draw bottom border +---@field borderRight boolean Draw right border +---@field background color The background color +---@field width number The width of the element +---@field z number The z-index for layering elements +---@field borderTop boolean Draw top border +---@field x number The horizontal position relative to parent +---@field y number The vertical position relative to parent +---@field visible boolean Whether the element is visible +---@field ignoreOffset boolean Whether to ignore the parent's offset +---@field foreground color The text/foreground color +---@field borderColor color Border color +local VisualElement = {} + +---Adds or updates a drawable character border around the element. The border will automatically adapt to size/background changes because the command reads current properties each render. +---@param colorOrOptions any Border color or options table +---@return VisualElement self +function VisualElement:addBorder(colorOrOptions) end + +---Gets the value of the BorderRight property. +---@param self VisualElement self +---@return boolean false Draw right border +function VisualElement:getBorderRight(self) end + +---Sets a constraint on a property relative to another element's property +---@param property string The property to constrain (x, y, width, height, left, right, top, bottom, centerX, centerY) +---@param targetElement BaseElement |string The target element or "parent" +---@param targetProperty string The target property to constrain to (left, right, top, bottom, centerX, centerY, width, height) +---@param offset number The offset to apply (negative = inside, positive = outside, fractional = percentage) +---@return VisualElement self The element instance +function VisualElement:setConstraint(property, targetElement, targetProperty, offset) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The scroll direction +---@param x number The x position of the scroll +---@param y number The y position of the scroll +---@return boolean scroll Whether the element was scrolled +---@protected +function VisualElement:mouse_scroll(direction, x, y) end + +---Sets the value of the Background property. +---@param self VisualElement self +---@param Background color The background color +function VisualElement:setBackground(self, Background) end + +---Gets the value of the BorderLeft property. +---@param self VisualElement self +---@return boolean false Draw left border +function VisualElement:getBorderLeft(self) end + +---Positions the element below the target with optional gap +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:below(target) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:postRender() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:blur() end + +---Centers the element vertically relative to the target with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:centerVertical(target) end + +---Matches the element's height to the target's height with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:matchHeight(target) end + +---Registers a function to handle the onEnter event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnEnter(self, func) end + +---Registers a function to handle the onClickUp event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnClickUp(self, func) end + +---Positions the element to the right of the target with optional gap +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:rightOf(target) end + +function VisualElement:drawText() end + +---Sets the value of the Width property. +---@param self VisualElement self +---@param Width number The width of the element +function VisualElement:setWidth(self, Width) end + +---Registers a function to handle the onScroll event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnScroll(self, func) end + +---Stretches the element to match the target's width with optional margin +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:stretchWidth(target) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was released +---@param x number The x position of the release +---@param y number The y position of the release +---@return boolean release Whether the element was released on the element +---@protected +function VisualElement:mouse_up(button, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param text string The text char to draw +---@param fg string The foreground color +---@param bg string The background color +---@protected +function VisualElement:blit(x, y, text, fg, bg) end + +---Sets the value of the BorderRight property. +---@param self VisualElement self +---@param BorderRight boolean Draw right border +function VisualElement:setBorderRight(self, BorderRight) end + +---Returns the relative position of the element or the given coordinates. +---@return number x The relative x position +---@return number y The relative y position +function VisualElement:getRelativePosition() end + +---Stretches the element to fill its parent's width and height with optional margin +---@return VisualElement self +function VisualElement:fillParent() end + +---Gets the value of the X property. +---@param self VisualElement self +---@return number 1 The horizontal position relative to parent +function VisualElement:getX(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was pressed +---@protected +function VisualElement:char(char) end + +---Checks if the specified coordinates are within the bounds of the element +---@param x number The x position to check +---@param y number The y position to check +---@return boolean isInBounds Whether the coordinates are within the bounds of the element +function VisualElement:isInBounds(x, y) end + +---Stretches the element to match the target's height with optional margin +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:stretchHeight(target) end + +---Gets the value of the Height property. +---@param self VisualElement self +---@return number 1 The height of the element +function VisualElement:getHeight(self) end + +---Aligns the element's right edge to the target's right edge with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:alignRight(target) end + +---Registers a function to handle the onFocus event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnFocus(self, func) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:focus() end + +---Registers a function to handle the onBlur event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnBlur(self, func) end + +---Sets the value of the Height property. +---@param self VisualElement self +---@param Height number The height of the element +function VisualElement:setHeight(self, Height) end + +---Gets the value of the Y property. +---@param self VisualElement self +---@return number 1 The vertical position relative to parent +function VisualElement:getY(self) end + +---Positions the element above the target with optional gap +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:above(target) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean clicked Whether the element was clicked +---@protected +function VisualElement:mouse_click(button, x, y) end + +---Convenience to stop animations from the element +function VisualElement.stopAnimation() end + +---Matches the element's width to the target's width with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:matchWidth(target) end + +---Sets the value of the Y property. +---@param self VisualElement self +---@param Y number The vertical position relative to parent +function VisualElement:setY(self, Y) end + +---Registers a function to handle the onKey event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnKey(self, func) end + +---Centers the element horizontally relative to the target with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:centerHorizontal(target) end + +---Gets the value of the BorderTop property. +---@param self VisualElement self +---@return boolean false Draw top border +function VisualElement:getBorderTop(self) end + +---Gets the value of the Background property. +---@param self VisualElement self +---@return color black The background color +function VisualElement:getBackground(self) end + +---Registers a function to handle the onDrag event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnDrag(self, func) end + +---Calculates the position of the element relative to its parent +---@return number x The x position +---@return number y The y position +function VisualElement:calculatePosition() end + +---Sets the value of the X property. +---@param self VisualElement self +---@param X number The horizontal position relative to parent +function VisualElement:setX(self, X) end + +---Aligns the element's right edge to its parent's right edge with optional gap +---@return VisualElement self +function VisualElement:toRight() end + +---Gets the value of the BackgroundEnabled property. +---@param self VisualElement self +---@return boolean true Whether to render the background +function VisualElement:getBackgroundEnabled(self) end + +---Sets the element's width as a percentage of the target's width +---@param target BaseElement |string The target element or "parent" +---@param percent number Percentage of target's width (0-100) +---@return VisualElement self +function VisualElement:widthPercent(target, percent) end + +---Gets a single property from the layoutConfig table +---@param key string The layout config property to get +---@return any value The value of the property, or nil if not set +function VisualElement:getLayoutConfigProperty(key) end + +---Updates all constraints, recalculating positions and sizes +---@return VisualElement self The element instance +function VisualElement:updateConstraints() end + +---Removes a constraint from the element +---@param property string The property of the constraint to remove +---@return VisualElement self The element instance +function VisualElement:removeConstraint(property) end + +---Sets the value of the Z property. +---@param self VisualElement self +---@param Z number The z-index for layering elements +function VisualElement:setZ(self, Z) end + +---Gets the value of the Visible property. +---@param self VisualElement self +---@return boolean true Whether the element is visible +function VisualElement:getVisible(self) end + +---Positions the element to the left of the target with optional gap +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:leftOf(target) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function VisualElement:init(props, basalt) end + +---Centers the element within its parent both horizontally and vertically +---@return VisualElement self +function VisualElement:center() end + +---Sets the value of the BackgroundEnabled property. +---@param self VisualElement self +---@param BackgroundEnabled boolean Whether to render the background +function VisualElement:setBackgroundEnabled(self, BackgroundEnabled) end + +---Registers a function to handle the onChar event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnChar(self, func) end + +---Aligns the element's left edge to its parent's left edge with optional gap +---@return VisualElement self +function VisualElement:toLeft() end + +---Aligns the element's top edge to the target's top edge with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:alignTop(target) end + +---Updates a single property in the layoutConfig table +---@param key string The layout config property to update (grow, shrink, basis, alignSelf, order, etc.) +---@param value any The value to set for the property +---@return VisualElement self The element instance +function VisualElement:setLayoutConfigProperty(key, value) end + +---Registers a function to handle the onLeave event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnLeave(self, func) end + +---Gets the value of the Width property. +---@param self VisualElement self +---@return number 1 The width of the element +function VisualElement:getWidth(self) end + +---Gets the value of the Z property. +---@param self VisualElement self +---@return number 1 The z-index for layering elements +function VisualElement:getZ(self) end + +---Sets the value of the Foreground property. +---@param self VisualElement self +---@param Foreground color The text/foreground color +function VisualElement:setForeground(self, Foreground) end + +---Sets the value of the LayoutConfig property. +---@param self VisualElement self +---@param LayoutConfig table Configuration for layout systems (grow, shrink, alignSelf, etc.) +function VisualElement:setLayoutConfig(self, LayoutConfig) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param text string The text char to draw +---@param bg color The background color +---@protected +function VisualElement:textBg(x, y, text, bg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was pressed +---@protected +function VisualElement:key(key) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked while dragging +---@param x number The x position of the drag +---@param y number The y position of the drag +---@return boolean drag Whether the element was dragged +---@protected +function VisualElement:mouse_drag(button, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param text string The text char to draw +---@param fg color The foreground color +---@protected +function VisualElement:textFg(x, y, text, fg) end + +---Centers the element both horizontally and vertically relative to the target +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:centerIn(target) end + +---Registers a function to handle the onClick event. +---@param button string +---@param x number +---@param y number +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnClick(self, func) end + +---Aligns the element's bottom edge to its parent's bottom edge with optional gap +---@return VisualElement self +function VisualElement:toBottom() end + +---Aligns the element's left edge to the target's left edge with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:alignLeft(target) end + +---Sets the value of the Visible property. +---@param self VisualElement self +---@param Visible boolean Whether the element is visible +function VisualElement:setVisible(self, Visible) end + +---Resolves all constraints for the element +---@return VisualElement self The element instance +function VisualElement:resolveAllConstraints() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:render() end + +---This function is used to prioritize the element by moving it to the top of its parent's children. It removes the element from its parent and adds it back, effectively changing its order. +---@return VisualElement self The VisualElement instance +function VisualElement:prioritize() end + +---Gets the value of the BorderColor property. +---@param self VisualElement self +---@return color white Border color +function VisualElement:getBorderColor(self) end + +---Gets the value of the LayoutConfig property. +---@param self VisualElement self +---@return table {} Configuration for layout systems (grow, shrink, alignSelf, etc.) +function VisualElement:getLayoutConfig(self) end + +---Sets the value of the BorderTop property. +---@param self VisualElement self +---@param BorderTop boolean Draw top border +function VisualElement:setBorderTop(self, BorderTop) end + +---Registers a function to handle the onRelease event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnRelease(self, func) end + +---Sets the value of the BorderBottom property. +---@param self VisualElement self +---@param BorderBottom boolean Draw bottom border +function VisualElement:setBorderBottom(self, BorderBottom) end + +---Registers a function to handle the onKeyUp event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnKeyUp(self, func) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was released +---@protected +function VisualElement:key_up(key) end + +---Removes the previously added border (if any) +---@return VisualElement self +function VisualElement:removeBorder() end + +function VisualElement:drawBg() end + +---Sets the value of the IgnoreOffset property. +---@param self VisualElement self +---@param IgnoreOffset boolean Whether to ignore the parent's offset +function VisualElement:setIgnoreOffset(self, IgnoreOffset) end + +---Stretches the element to match the target's width and height with optional margin +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:stretch(target) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param _ number unknown +---@param x number The x position of the mouse +---@param y number The y position of the mouse +---@return boolean hover Whether the mouse has moved over the element +---@protected +function VisualElement:mouse_move(_, x, y) end + +---Creates a new Animation Object +---@return Animation animation The new animation +function VisualElement:animate() end + +---Aligns the element's top edge to its parent's top edge with optional gap +---@return VisualElement self +function VisualElement:toTop() end + +---Returns the absolute position of the element or the given coordinates. +---@return number x The absolute x position +---@return number y The absolute y position +function VisualElement:getAbsolutePosition() end + +---Gets the value of the IgnoreOffset property. +---@param self VisualElement self +---@return boolean false Whether to ignore the parent's offset +function VisualElement:getIgnoreOffset(self) end + +---Sets the value of the BorderColor property. +---@param self VisualElement self +---@param BorderColor color Border color +function VisualElement:setBorderColor(self, BorderColor) end + +---Stretches the element to fill its parent's width with optional margin +---@return VisualElement self +function VisualElement:fillWidth() end + +---Gets the value of the Foreground property. +---@param self VisualElement self +---@return color white The text/foreground color +function VisualElement:getForeground(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was released +---@param x number The x position of the release +---@param y number The y position of the release +---@protected +function VisualElement:mouse_release(button, x, y) end + +function VisualElement:drawFg() end + +---Sets or removes focus from this element +---@param focused boolean Whether to focus or blur +---@return VisualElement self +function VisualElement:setFocused(focused) end + +function VisualElement:destroy() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param width number The width of the area to draw +---@param height number The height of the area to draw +---@param text string The text to draw +---@param fg string The foreground color +---@param bg string The background color +---@protected +function VisualElement:multiBlit(x, y, width, height, text, fg, bg) end + +---Gets the value of the BorderBottom property. +---@param self VisualElement self +---@return boolean false Draw bottom border +function VisualElement:getBorderBottom(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position of the cursor +---@param y number The y position of the cursor +---@param blink boolean Whether the cursor should blink +---@param color number The color of the cursor +---@return VisualElement self The VisualElement instance +---@protected +function VisualElement:setCursor(x, y, blink, color) end + +---Stretches the element to fill its parent's height with optional margin +---@return VisualElement self +function VisualElement:fillHeight() end + +---Sets the value of the BorderLeft property. +---@param self VisualElement self +---@param BorderLeft boolean Draw left border +function VisualElement:setBorderLeft(self, BorderLeft) end + +---Sets the element's height as a percentage of the target's height +---@param target BaseElement |string The target element or "parent" +---@param percent number Percentage of target's height (0-100) +---@return VisualElement self +function VisualElement:heightPercent(target, percent) end + +---Aligns the element's bottom edge to the target's bottom edge with optional offset +---@param target BaseElement |string The target element or "parent" +---@return VisualElement self +function VisualElement:alignBottom(target) end + +---Gets whether this element is focused +---@return boolean isFocused +function VisualElement:isFocused() end + +---@class Table : Collection +---@field showScrollBar boolean Whether to show the scrollbar when items exceed height +---@field scrollBarSymbol string " Symbol used for the scrollbar handle +---@field scrollBarBackground string Symbol used for the scrollbar background +---@field sortColumn number nil Currently sorted column index +---@field offset number Scroll offset for vertical scrolling +---@field headerColor color Color of the column headers +---@field gridColor color Color of grid lines +---@field scrollBarColor color Color of the scrollbar handle +---@field columns table List of column definitions with {name, width} properties +---@field sortDirection string Sort direction ("asc" or "desc") +---@field scrollBarBackgroundColor color Background color of the scrollbar +---@field customSortFunction table Custom sort functions for columns +local Table = {} + +---Sets the value of the ScrollBarSymbol property. +---@param self Table self +---@param ScrollBarSymbol string " Symbol used for the scrollbar handle +function Table:setScrollBarSymbol(self, ScrollBarSymbol) end + +---Sets a custom sort function for a specific column +---@param columnIndex number The index of the column +---@param sortFn function Function that takes (rowA, rowB) and returns comparison result +---@return Table self The Table instance +function Table:setColumnSortFunction(columnIndex, sortFn) end + +---Sets the value of the Columns property. +---@param self Table self +---@param Columns table List of column definitions with {name, width} properties +function Table:setColumns(self, Columns) end + +---Gets the currently selected row +---@return table ? row The selected row or nil +function Table:getSelectedRow() end + +---Sets the value of the SortDirection property. +---@param self Table self +---@param SortDirection string Sort direction ("asc" or "desc") +function Table:setSortDirection(self, SortDirection) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Table:mouse_click() end + +---Gets the value of the ScrollBarBackgroundColor property. +---@param self Table self +---@return color gray Background color of the scrollbar +function Table:getScrollBarBackgroundColor(self) end + +---Sorts the table data by column +---@param columnIndex number The index of the column to sort by +---@param fn function ? Optional custom sorting function +---@return Table self The Table instance +function Table:sortByColumn(columnIndex, fn) end + +---Removes a row by index +---@param rowIndex number The index of the row to remove +---@return Table self The Table instance +function Table:removeRow(rowIndex) end + +---Sets the value of the ShowScrollBar property. +---@param self Table self +---@param ShowScrollBar boolean Whether to show the scrollbar when items exceed height +function Table:setShowScrollBar(self, ShowScrollBar) end + +---Gets a row by index +---@param rowIndex number The index of the row +---@return table ? row The row data or nil +function Table:getRow(rowIndex) end + +---Gets the value of the SortDirection property. +---@param self Table self +---@return string "asc" Sort direction ("asc" or "desc") +function Table:getSortDirection(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Table:mouse_up() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Table:mouse_drag() end + +---Gets the value of the ScrollBarBackground property. +---@param self Table self +---@return string "\127" Symbol used for the scrollbar background +function Table:getScrollBarBackground(self) end + +---Sets the value of the CustomSortFunction property. +---@param self Table self +---@param CustomSortFunction table Custom sort functions for columns +function Table:setCustomSortFunction(self, CustomSortFunction) end + +---Gets the value of the CustomSortFunction property. +---@param self Table self +---@return table {} Custom sort functions for columns +function Table:getCustomSortFunction(self) end + +---Updates a specific cell value +---@param rowIndex number The row index +---@param colIndex number The column index +---@param value any The new value +---@return Table self The Table instance +function Table:updateCell(rowIndex, colIndex, value) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Table:render() end + +---Sets the value of the Offset property. +---@param self Table self +---@param Offset number Scroll offset for vertical scrolling +function Table:setOffset(self, Offset) end + +---Sets the value of the ScrollBarBackgroundColor property. +---@param self Table self +---@param ScrollBarBackgroundColor color Background color of the scrollbar +function Table:setScrollBarBackgroundColor(self, ScrollBarBackgroundColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Table:mouse_scroll() end + +---Registers callback for row selection +---@param callback function The callback function(rowIndex, row) +---@return Table self The Table instance +function Table:onRowSelect(callback) end + +---Sets the value of the ScrollBarBackground property. +---@param self Table self +---@param ScrollBarBackground string Symbol used for the scrollbar background +function Table:setScrollBarBackground(self, ScrollBarBackground) end + +---Gets all table data +---@return table data Array of row cell arrays +function Table:getData() end + +---Gets the value of the SortColumn property. +---@param self Table self +---@return number ? nil Currently sorted column index +function Table:getSortColumn(self) end + +---Adds a new column to the table +---@param name string The name of the column +---@param width number |string The width of the column (number, "auto", or "30%") +---@return Table self The Table instance +function Table:addColumn(name, width) end + +---Sets the value of the SortColumn property. +---@param self Table self +---@param SortColumn number nil Currently sorted column index +function Table:setSortColumn(self, SortColumn) end + +---Gets the value of the ShowScrollBar property. +---@param self Table self +---@return boolean true Whether to show the scrollbar when items exceed height +function Table:getShowScrollBar(self) end + +---Sets the value of the ScrollBarColor property. +---@param self Table self +---@param ScrollBarColor color Color of the scrollbar handle +function Table:setScrollBarColor(self, ScrollBarColor) end + +---Gets the value of the GridColor property. +---@param self Table self +---@return color gray Color of grid lines +function Table:getGridColor(self) end + +---Sets the value of the GridColor property. +---@param self Table self +---@param GridColor color Color of grid lines +function Table:setGridColor(self, GridColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Table self The initialized instance +---@protected +function Table:init(props, basalt) end + +---Set data with automatic formatting +---@param rawData table The raw data array (array of row arrays) +---@param formatters table ? Optional formatter functions for columns {[2] = function(value) return value end} +---@return Table self The Table instance +function Table:setData(rawData, formatters) end + +---Sets the value of the HeaderColor property. +---@param self Table self +---@param HeaderColor color Color of the column headers +function Table:setHeaderColor(self, HeaderColor) end + +---Gets the value of the ScrollBarSymbol property. +---@param self Table self +---@return string " " Symbol used for the scrollbar handle +function Table:getScrollBarSymbol(self) end + +---Gets the value of the Columns property. +---@param self Table self +---@return table {} List of column definitions with {name, width} properties +function Table:getColumns(self) end + +---Gets the value of the Offset property. +---@param self Table self +---@return number 0 Scroll offset for vertical scrolling +function Table:getOffset(self) end + +---Gets the value of the ScrollBarColor property. +---@param self Table self +---@return color lightGray Color of the scrollbar handle +function Table:getScrollBarColor(self) end + +---Clears all table data +---@return Table self The Table instance +function Table:clearData() end + +---Gets the value of the HeaderColor property. +---@param self Table self +---@return color blue Color of the column headers +function Table:getHeaderColor(self) end + +---Registers a function to handle the onRowSelect event. +---@param rowIndex number +---@param row table +---@param self Table self +---@param func function The function to be called when the event fires +function Table:onOnRowSelect(self, func) end + +---Adds a new row to the table +---@return Table self The Table instance +function Table:addRow() end + +---@class Dialog : Frame +---@field title string The dialog title +---@field secondaryColor color Secondary button color (Cancel, dismiss actions) +---@field buttonForeground color Foreground color for buttons +---@field primaryColor color Primary button color (OK, confirm actions) +---@field modal boolean If true, blocks all events outside the dialog +local Dialog = {} + +---Handles mouse click events +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Dialog:mouse_click() end + +---Gets the value of the PrimaryColor property. +---@param self Dialog self +---@return color lime Primary button color (OK, confirm actions) +function Dialog:getPrimaryColor(self) end + +---Gets the value of the Title property. +---@param self Dialog self +---@return string "" The dialog title +function Dialog:getTitle(self) end + +---Sets the value of the SecondaryColor property. +---@param self Dialog self +---@param SecondaryColor color Secondary button color (Cancel, dismiss actions) +function Dialog:setSecondaryColor(self, SecondaryColor) end + +---Sets the value of the Modal property. +---@param self Dialog self +---@param Modal boolean If true, blocks all events outside the dialog +function Dialog:setModal(self, Modal) end + +---Sets the value of the Title property. +---@param self Dialog self +---@param Title string The dialog title +function Dialog:setTitle(self, Title) end + +---Closes the dialog +---@return Dialog self The Dialog instance +function Dialog:close() end + +---Handles mouse drag events +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Dialog:mouse_drag() end + +---Creates a simple alert dialog +---@param title string The alert title +---@param message string The alert message +---@return Dialog self The Dialog instance +function Dialog:alert(title, message) end + +---Gets the value of the ButtonForeground property. +---@param self Dialog self +---@return color black Foreground color for buttons +function Dialog:getButtonForeground(self) end + +---Handles mouse scroll events +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Dialog:mouse_scroll() end + +---Gets the value of the SecondaryColor property. +---@param self Dialog self +---@return color lightGray Secondary button color (Cancel, dismiss actions) +function Dialog:getSecondaryColor(self) end + +---Sets the value of the ButtonForeground property. +---@param self Dialog self +---@param ButtonForeground color Foreground color for buttons +function Dialog:setButtonForeground(self, ButtonForeground) end + +---Shows the dialog +---@return Dialog self The Dialog instance +function Dialog:show() end + +---Renders the dialog +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Dialog:render() end + +---Creates a prompt dialog with input +---@param title string The dialog title +---@param message string The prompt message +---@return Dialog self The Dialog instance +function Dialog:prompt(title, message) end + +---Sets the value of the PrimaryColor property. +---@param self Dialog self +---@param PrimaryColor color Primary button color (OK, confirm actions) +function Dialog:setPrimaryColor(self, PrimaryColor) end + +---Handles mouse up events +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Dialog:mouse_up() end + +---Creates a confirm dialog +---@param title string The dialog title +---@param message string The confirmation message +---@param callback function Callback (receives boolean result) +---@return Dialog self The Dialog instance +function Dialog:confirm(title, message, callback) end + +---Gets the value of the Modal property. +---@param self Dialog self +---@return boolean true If true, blocks all events outside the dialog +function Dialog:getModal(self) end + +---@class ProgressBar : VisualElement +---@field direction string The direction of the progress bar ("up", "down", "left", "right") +---@field progress number Current progress value (0-100) +---@field showPercentage boolean Whether to show the percentage text in the center +---@field progressColor color The color used for the filled portion of the progress bar +local ProgressBar = {} + +---Gets the value of the Progress property. +---@param self ProgressBar self +---@return number 0 Current progress value (0-100) +function ProgressBar:getProgress(self) end + +---Sets the value of the ProgressColor property. +---@param self ProgressBar self +---@param ProgressColor color The color used for the filled portion of the progress bar +function ProgressBar:setProgressColor(self, ProgressColor) end + +---Gets the value of the ShowPercentage property. +---@param self ProgressBar self +---@return boolean false Whether to show the percentage text in the center +function ProgressBar:getShowPercentage(self) end + +---Sets the value of the ShowPercentage property. +---@param self ProgressBar self +---@param ShowPercentage boolean Whether to show the percentage text in the center +function ProgressBar:setShowPercentage(self, ShowPercentage) end + +---Gets the value of the ProgressColor property. +---@param self ProgressBar self +---@return color lime The color used for the filled portion of the progress bar +function ProgressBar:getProgressColor(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function ProgressBar:render() end + +---Sets the value of the Direction property. +---@param self ProgressBar self +---@param Direction string The direction of the progress bar ("up", "down", "left", "right") +function ProgressBar:setDirection(self, Direction) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return ProgressBar self The initialized instance +---@protected +function ProgressBar:init(props, basalt) end + +---Sets the value of the Progress property. +---@param self ProgressBar self +---@param Progress number Current progress value (0-100) +function ProgressBar:setProgress(self, Progress) end + +---Gets the value of the Direction property. +---@param self ProgressBar self +---@return string right The direction of the progress bar ("up", "down", "left", "right") +function ProgressBar:getDirection(self) end + +---@class Display : VisualElement +local Display = {} + +---Writes text directly to the display with optional colors +---@param x number X position (1-based) +---@param y number Y position (1-based) +---@param text string Text to write +---@return Display self For method chaining +function Display:write(x, y, text) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Display:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Display:init(props, basalt) end + +---Retrieves the underlying ComputerCraft window object +---@return table window A CC window object with all standard terminal methods +function Display:getWindow() end + +---@class TabControl : Container +---@field scrollableTab boolean Enables scroll mode for tabs if they exceed width +---@field tabScrollOffset number Current scroll offset for tabs in scrollable mode +---@field activeTabTextColor color Foreground color for the active tab text +---@field activeTabBackground color Background color for the active tab +---@field headerBackground color Background color for the tab header area +---@field activeTab number The currently active tab ID +---@field tabHeight number Height of the tab header area +---@field tabs table List of tab definitions +local TabControl = {} + +function TabControl:drawText() end + +function TabControl:drawFg() end + +function TabControl:setCursor() end + +---Gets the value of the HeaderBackground property. +---@param self TabControl self +---@return color gray Background color for the tab header area +function TabControl:getHeaderBackground(self) end + +---Sets the value of the TabScrollOffset property. +---@param self TabControl self +---@param TabScrollOffset number Current scroll offset for tabs in scrollable mode +function TabControl:setTabScrollOffset(self, TabScrollOffset) end + +function TabControl:textFg() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param child table The child element to check +---@return boolean Whether the child should be visible +---@protected +function TabControl:isChildVisible(child) end + +---Sets the value of the ActiveTabTextColor property. +---@param self TabControl self +---@param ActiveTabTextColor color Foreground color for the active tab text +function TabControl:setActiveTabTextColor(self, ActiveTabTextColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function TabControl:init(props, basalt) end + +---returns a proxy for adding elements to the tab +---@param title string The title of the tab +---@return table tabHandler The tab handler proxy for adding elements to the new tab +function TabControl:newTab(title) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click (global) +---@param y number The y position of the click (global) +---@return boolean Whether the event was handled +---@protected +function TabControl:mouse_click(button, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return number yOffset The Y offset for content +---@protected +function TabControl:getContentYOffset() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function TabControl:sortChildrenEvents() end + +---Gets the value of the ActiveTabTextColor property. +---@param self TabControl self +---@return color black Foreground color for the active tab text +function TabControl:getActiveTabTextColor(self) end + +function TabControl:textBg() end + +function TabControl:mouse_scroll() end + +---Sets the value of the ActiveTabBackground property. +---@param self TabControl self +---@param ActiveTabBackground color Background color for the active tab +function TabControl:setActiveTabBackground(self, ActiveTabBackground) end + +function TabControl:getRelativePosition() end + +---Gets the value of the TabScrollOffset property. +---@param self TabControl self +---@return number 0 Current scroll offset for tabs in scrollable mode +function TabControl:getTabScrollOffset(self) end + +---Sets the value of the HeaderBackground property. +---@param self TabControl self +---@param HeaderBackground color Background color for the tab header area +function TabControl:setHeaderBackground(self, HeaderBackground) end + +function TabControl:mouse_drag() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param child table The child element to add +---@return Container self For method chaining +---@protected +function TabControl:addChild(child) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function TabControl:render() end + +---Gets the value of the ActiveTab property. +---@param self TabControl self +---@return number nil The currently active tab ID +function TabControl:getActiveTab(self) end + +---Sets the value of the ScrollableTab property. +---@param self TabControl self +---@param ScrollableTab boolean Enables scroll mode for tabs if they exceed width +function TabControl:setScrollableTab(self, ScrollableTab) end + +function TabControl:mouse_up() end + +function TabControl:mouse_move() end + +---Sets the value of the TabHeight property. +---@param self TabControl self +---@param TabHeight number Height of the tab header area +function TabControl:setTabHeight(self, TabHeight) end + +---Gets the value of the Tabs property. +---@param self TabControl self +---@return table {} List of tab definitions +function TabControl:getTabs(self) end + +function TabControl:mouse_release() end + +---Scrolls the tab header left or right if scrollableTab is enabled +---@param direction number -1 to scroll left, 1 to scroll right +---@return TabControl self For method chaining +function TabControl:scrollTabs(direction) end + +---@param tabId number The ID of the tab to activate +function TabControl:setActiveTab(tabId) end + +---@param elementType string The type of element to add +---@param tabId number Optional tab ID, defaults to active tab +---@return table element The created element +function TabControl:addElement(elementType, tabId) end + +function TabControl:_getHeaderMetrics() end + +---Gets the value of the ActiveTabBackground property. +---@param self TabControl self +---@return color white Background color for the active tab +function TabControl:getActiveTabBackground(self) end + +---@param element table The element to assign to a tab +---@param tabId number The ID of the tab to assign the element to +---@return TabControl self For method chaining +function TabControl:setTab(element, tabId) end + +function TabControl:drawBg() end + +function TabControl:blit() end + +---Sets the value of the Tabs property. +---@param self TabControl self +---@param Tabs table List of tab definitions +function TabControl:setTabs(self, Tabs) end + +---Gets the value of the ScrollableTab property. +---@param self TabControl self +---@return boolean false Enables scroll mode for tabs if they exceed width +function TabControl:getScrollableTab(self) end + +function TabControl:multiBlit() end + +---Gets the value of the TabHeight property. +---@param self TabControl self +---@return number 1 Height of the tab header area +function TabControl:getTabHeight(self) end + +---@class Render +local Render = {} + +---Blits text to the screen with multiple lines +---@param x number The x position to blit to +---@param y number The y position to blit to +---@param width number The width of the text +---@param height number The height of the text +---@param text string The text to blit +---@param fg colors The foreground color of the text +---@param bg colors The background color of the text +---@return Render +function Render:multiBlit(x, y, width, height, text, fg, bg) end + +---Blits text to the screen with a foreground color +---@param x number The x position to blit to +---@param y number The y position to blit to +---@param text string The text to blit +---@param fg colors The foreground color of the text +---@return Render +function Render:textFg(x, y, text, fg) end + +---Blits text to the screen +---@param x number The x position to blit to +---@param y number The y position to blit to +---@param text string The text to blit +---@return Render +function Render:text(x, y, text) end + +---Blits a background color to the screen +---@param x number The x position +---@param y number The y position +---@param bg string The background color to blit +---@return Render +function Render:bg(x, y, bg) end + +---Clears an area of the screen +---@param x number The x position of the area +---@param y number The y position of the area +---@param width number The width of the area +---@param height number The height of the area +---@param bg colors The background color to clear the area with +---@return Render +function Render:clearArea(x, y, width, height, bg) end + +---Creates a new Render object +---@param terminal table The terminal object to render to +---@return Render +function Render.new(terminal) end + +---Clears the screen +---@param bg colors The background color to clear the screen with +---@return Render +function Render:clear(bg) end + +---Gets the size of the render +---@return number , number +function Render:getSize() end + +---Sets the size of the render +---@param width number The width of the render +---@param height number The height of the render +---@return Render +function Render:setSize(width, height) end + +---Adds a dirty rectangle to the buffer +---@param x number The x position of the rectangle +---@param y number The y position of the rectangle +---@param width number The width of the rectangle +---@param height number The height of the rectangle +---@return Render +function Render:addDirtyRect(x, y, width, height) end + +---Renders the buffer to the screen +---@return Render +function Render:render() end + +---Checks if two rectangles overlap +---@param r1 table The first rectangle +---@param r2 table The second rectangle +---@return boolean +function Render:rectOverlaps(r1, r2) end + +---Blits a foreground color to the screen +---@param x number The x position +---@param y number The y position +---@param fg string The foreground color to blit +---@return Render +function Render:fg(x, y, fg) end + +---Blits text to the screen with a background color +---@param x number The x position to blit to +---@param y number The y position to blit to +---@param text string The text to blit +---@param bg colors The background color of the text +---@return Render +function Render:textBg(x, y, text, bg) end + +---Merges two rectangles +---@param target table The target rectangle +---@param source table The source rectangle +---@return Render +function Render:mergeRects(target, source) end + +---Sets the cursor position +---@param x number The x position of the cursor +---@param y number The y position of the cursor +---@param blink boolean Whether the cursor should blink +---@return Render +function Render:setCursor(x, y, blink) end + +---Blits text to the screen +---@param x number The x position to blit to +---@param y number The y position to blit to +---@param text string The text to blit +---@param fg string The foreground color of the text +---@param bg string The background color of the text +---@return Render +function Render:blit(x, y, text, fg, bg) end diff --git a/config.lua b/config.lua index 8a11e8e..683db25 100644 --- a/config.lua +++ b/config.lua @@ -1,507 +1,507 @@ return { ["metadata"] = { - ["generated"] = "Mon Nov 3 12:29:37 2025", + ["generated"] = "Tue Nov 4 08:43:59 2025", ["version"] = "2.0", }, ["categories"] = { ["elements"] = { ["description"] = "UI Elements", ["files"] = { - ["Timer"] = { - ["description"] = "", - ["path"] = "elements/Timer.lua", - ["requires"] = { - [1] = "BaseElement", - }, - ["size"] = 2914, - ["default"] = true, - }, - ["Tree"] = { - ["description"] = "", - ["path"] = "elements/Tree.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 22144, - ["default"] = true, - }, - ["List"] = { - ["description"] = "A scrollable list of selectable items", - ["path"] = "elements/List.lua", - ["requires"] = { - [1] = "Collection", - }, - ["size"] = 15474, - ["default"] = true, - }, - ["VisualElement"] = { - ["description"] = "The Visual Element class which is the base class for all visual UI elements", - ["path"] = "elements/VisualElement.lua", - ["requires"] = { - [1] = "BaseElement", - }, - ["size"] = 45082, - ["default"] = true, - }, - ["ContextMenu"] = { - ["description"] = "A ContextMenu element that displays a menu with items and submenus.", - ["path"] = "elements/ContextMenu.lua", - ["requires"] = { - [1] = "Container", - }, - ["size"] = 10636, - ["default"] = true, - }, - ["Menu"] = { - ["description"] = "A horizontal menu bar with selectable items.", - ["path"] = "elements/Menu.lua", - ["requires"] = { - [1] = "List", - }, - ["size"] = 8582, - ["default"] = true, - }, - ["TextBox"] = { - ["description"] = "A multi-line text editor component with cursor support and text manipulation features", - ["path"] = "elements/TextBox.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 43530, - ["default"] = false, - }, - ["Table"] = { - ["description"] = "", - ["path"] = "elements/Table.lua", - ["requires"] = { - [1] = "Collection", - }, - ["size"] = 25362, - ["default"] = true, - }, - ["Program"] = { - ["description"] = "", - ["path"] = "elements/Program.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 12730, - ["default"] = true, - }, - ["Display"] = { - ["description"] = "The Display is a special element which uses the CC Window API which you can use.", - ["path"] = "elements/Display.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 4668, - ["default"] = false, - }, - ["Breadcrumb"] = { - ["description"] = "", - ["path"] = "elements/Breadcrumb.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 4314, - ["default"] = true, - }, - ["Dialog"] = { - ["description"] = "A dialog overlay system with common presets (alert, confirm, prompt).", - ["path"] = "elements/Dialog.lua", - ["requires"] = { - [1] = "Frame", - }, - ["size"] = 8878, - ["default"] = true, - }, - ["BaseElement"] = { - ["description"] = "The base class for all UI elements in Basalt.", - ["path"] = "elements/BaseElement.lua", - ["requires"] = { - }, - ["size"] = 13870, - ["default"] = true, - }, - ["Container"] = { - ["description"] = "The container class. It is a visual element that can contain other elements. It is the base class for all containers", - ["path"] = "elements/Container.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 27475, - ["default"] = true, - }, - ["BaseFrame"] = { - ["description"] = "This is the base frame class. It is the root element of all elements and the only element without a parent.", - ["path"] = "elements/BaseFrame.lua", - ["requires"] = { - [1] = "Container", - }, - ["size"] = 9017, - ["default"] = true, - }, - ["Button"] = { - ["description"] = "The Button is a standard button element with click handling and state management.", - ["path"] = "elements/Button.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 2437, - ["default"] = true, - }, - ["Input"] = { - ["description"] = "A text input field with various features", - ["path"] = "elements/Input.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 9200, - ["default"] = true, - }, - ["ProgressBar"] = { - ["description"] = "", - ["path"] = "elements/ProgressBar.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 3398, - ["default"] = true, - }, - ["SideNav"] = { - ["description"] = "A SideNav element that provides sidebar navigation with multiple content areas.", - ["path"] = "elements/SideNav.lua", - ["requires"] = { - [1] = "Container", - }, - ["size"] = 22135, - ["default"] = true, - }, - ["Slider"] = { - ["description"] = "", - ["path"] = "elements/Slider.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 4977, - ["default"] = true, - }, - ["Collection"] = { - ["description"] = "A collection of items", - ["path"] = "elements/Collection.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 7778, - ["default"] = true, - }, - ["Accordion"] = { - ["description"] = "An Accordion element that provides collapsible panels with headers.", - ["path"] = "elements/Accordion.lua", - ["requires"] = { - [1] = "Container", - }, - ["size"] = 14913, - ["default"] = true, - }, - ["CheckBox"] = { - ["description"] = "This is a checkbox. It is a visual element that can be checked.", - ["path"] = "elements/CheckBox.lua", - ["requires"] = { - }, - ["size"] = 3700, - ["default"] = true, - }, - ["LineChart"] = { - ["description"] = "", - ["path"] = "elements/LineChart.lua", - ["requires"] = { - }, - ["size"] = 3171, - ["default"] = false, - }, - ["Label"] = { - ["description"] = "A simple text display element that automatically resizes its width based on the text content.", - ["path"] = "elements/Label.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 3092, - ["default"] = true, - }, - ["BarChart"] = { - ["description"] = "", - ["path"] = "elements/BarChart.lua", - ["requires"] = { - }, - ["size"] = 3507, - ["default"] = true, - }, ["ComboBox"] = { - ["description"] = "A ComboBox that combines dropdown selection with editable text input", + ["default"] = false, ["path"] = "elements/ComboBox.lua", + ["size"] = 14752, + ["description"] = "A ComboBox that combines dropdown selection with editable text input", ["requires"] = { [1] = "DropDown", }, - ["size"] = 14752, - ["default"] = false, }, - ["Graph"] = { - ["description"] = "A point based graph element", - ["path"] = "elements/Graph.lua", - ["requires"] = { - }, - ["size"] = 6933, - ["default"] = false, - }, - ["ScrollFrame"] = { - ["description"] = "A scrollable container that automatically displays scrollbars when content overflows.", - ["path"] = "elements/ScrollFrame.lua", - ["requires"] = { - [1] = "Container", - }, - ["size"] = 17273, + ["VisualElement"] = { ["default"] = true, - }, - ["TabControl"] = { - ["description"] = "A TabControl element that provides tabbed interface with multiple content areas.", - ["path"] = "elements/TabControl.lua", + ["path"] = "elements/VisualElement.lua", + ["size"] = 45082, + ["description"] = "The Visual Element class which is the base class for all visual UI elements", ["requires"] = { - [1] = "Container", + [1] = "BaseElement", }, - ["size"] = 20903, - ["default"] = true, - }, - ["Image"] = { - ["description"] = "An element that displays an image in bimg format", - ["path"] = "elements/Image.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 15117, - ["default"] = false, }, ["BigFont"] = { - ["description"] = "", + ["default"] = false, ["path"] = "elements/BigFont.lua", + ["size"] = 21551, + ["description"] = "", ["requires"] = { [1] = "VisualElement", }, - ["size"] = 21551, - ["default"] = false, }, - ["Frame"] = { - ["description"] = "A frame element that serves as a grouping container for other elements.", - ["path"] = "elements/Frame.lua", + ["ContextMenu"] = { + ["default"] = true, + ["path"] = "elements/ContextMenu.lua", + ["size"] = 10636, + ["description"] = "A ContextMenu element that displays a menu with items and submenus.", ["requires"] = { [1] = "Container", }, - ["size"] = 6646, + }, + ["Image"] = { + ["default"] = false, + ["path"] = "elements/Image.lua", + ["size"] = 15117, + ["description"] = "An element that displays an image in bimg format", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Slider"] = { ["default"] = true, + ["path"] = "elements/Slider.lua", + ["size"] = 4977, + ["description"] = "", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Tree"] = { + ["default"] = true, + ["path"] = "elements/Tree.lua", + ["size"] = 22144, + ["description"] = "", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Frame"] = { + ["default"] = true, + ["path"] = "elements/Frame.lua", + ["size"] = 6646, + ["description"] = "A frame element that serves as a grouping container for other elements.", + ["requires"] = { + [1] = "Container", + }, + }, + ["Collection"] = { + ["default"] = true, + ["path"] = "elements/Collection.lua", + ["size"] = 7778, + ["description"] = "A collection of items", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Input"] = { + ["default"] = true, + ["path"] = "elements/Input.lua", + ["size"] = 9200, + ["description"] = "A text input field with various features", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["ScrollFrame"] = { + ["default"] = true, + ["path"] = "elements/ScrollFrame.lua", + ["size"] = 17439, + ["description"] = "A scrollable container that automatically displays scrollbars when content overflows.", + ["requires"] = { + [1] = "Container", + }, + }, + ["Switch"] = { + ["default"] = true, + ["path"] = "elements/Switch.lua", + ["size"] = 3269, + ["description"] = "The Switch is a standard Switch element with click handling and state management.", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["ScrollBar"] = { + ["default"] = true, + ["path"] = "elements/ScrollBar.lua", + ["size"] = 9665, + ["description"] = "A ScrollBar element that can be attached to other elements to control their scroll properties.", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Program"] = { + ["default"] = true, + ["path"] = "elements/Program.lua", + ["size"] = 12730, + ["description"] = "", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["ProgressBar"] = { + ["default"] = true, + ["path"] = "elements/ProgressBar.lua", + ["size"] = 3398, + ["description"] = "", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Graph"] = { + ["default"] = false, + ["path"] = "elements/Graph.lua", + ["size"] = 6933, + ["description"] = "A point based graph element", + ["requires"] = { + }, + }, + ["Timer"] = { + ["default"] = true, + ["path"] = "elements/Timer.lua", + ["size"] = 2914, + ["description"] = "", + ["requires"] = { + [1] = "BaseElement", + }, + }, + ["BaseElement"] = { + ["default"] = true, + ["path"] = "elements/BaseElement.lua", + ["size"] = 13870, + ["description"] = "The base class for all UI elements in Basalt.", + ["requires"] = { + }, + }, + ["TabControl"] = { + ["default"] = true, + ["path"] = "elements/TabControl.lua", + ["size"] = 20903, + ["description"] = "A TabControl element that provides tabbed interface with multiple content areas.", + ["requires"] = { + [1] = "Container", + }, + }, + ["Toast"] = { + ["default"] = true, + ["path"] = "elements/Toast.lua", + ["size"] = 7917, + ["description"] = "A toast notification element that displays temporary messages.", + ["requires"] = { + [1] = "VisualElement", + }, }, ["DropDown"] = { - ["description"] = "A DropDown menu that shows a list of selectable items", + ["default"] = false, ["path"] = "elements/DropDown.lua", + ["size"] = 7887, + ["description"] = "A DropDown menu that shows a list of selectable items", ["requires"] = { [1] = "List", }, - ["size"] = 7887, + }, + ["Table"] = { + ["default"] = true, + ["path"] = "elements/Table.lua", + ["size"] = 25362, + ["description"] = "", + ["requires"] = { + [1] = "Collection", + }, + }, + ["BaseFrame"] = { + ["default"] = true, + ["path"] = "elements/BaseFrame.lua", + ["size"] = 9017, + ["description"] = "This is the base frame class. It is the root element of all elements and the only element without a parent.", + ["requires"] = { + [1] = "Container", + }, + }, + ["Accordion"] = { + ["default"] = true, + ["path"] = "elements/Accordion.lua", + ["size"] = 14913, + ["description"] = "An Accordion element that provides collapsible panels with headers.", + ["requires"] = { + [1] = "Container", + }, + }, + ["CheckBox"] = { + ["default"] = true, + ["path"] = "elements/CheckBox.lua", + ["size"] = 3700, + ["description"] = "This is a checkbox. It is a visual element that can be checked.", + ["requires"] = { + }, + }, + ["TextBox"] = { ["default"] = false, - }, - ["Switch"] = { - ["description"] = "The Switch is a standard Switch element with click handling and state management.", - ["path"] = "elements/Switch.lua", + ["path"] = "elements/TextBox.lua", + ["size"] = 43530, + ["description"] = "A multi-line text editor component with cursor support and text manipulation features", ["requires"] = { [1] = "VisualElement", }, - ["size"] = 3269, - ["default"] = true, }, - ["ScrollBar"] = { - ["description"] = "A ScrollBar element that can be attached to other elements to control their scroll properties.", - ["path"] = "elements/ScrollBar.lua", + ["Menu"] = { + ["default"] = true, + ["path"] = "elements/Menu.lua", + ["size"] = 8582, + ["description"] = "A horizontal menu bar with selectable items.", + ["requires"] = { + [1] = "List", + }, + }, + ["Button"] = { + ["default"] = true, + ["path"] = "elements/Button.lua", + ["size"] = 2437, + ["description"] = "The Button is a standard button element with click handling and state management.", ["requires"] = { [1] = "VisualElement", }, - ["size"] = 9665, - ["default"] = true, }, - ["Toast"] = { - ["description"] = "A toast notification element that displays temporary messages.", - ["path"] = "elements/Toast.lua", + ["List"] = { + ["default"] = true, + ["path"] = "elements/List.lua", + ["size"] = 15474, + ["description"] = "A scrollable list of selectable items", + ["requires"] = { + [1] = "Collection", + }, + }, + ["Label"] = { + ["default"] = true, + ["path"] = "elements/Label.lua", + ["size"] = 3092, + ["description"] = "A simple text display element that automatically resizes its width based on the text content.", ["requires"] = { [1] = "VisualElement", }, - ["size"] = 7917, + }, + ["LineChart"] = { + ["default"] = false, + ["path"] = "elements/LineChart.lua", + ["size"] = 3171, + ["description"] = "", + ["requires"] = { + }, + }, + ["BarChart"] = { ["default"] = true, + ["path"] = "elements/BarChart.lua", + ["size"] = 3507, + ["description"] = "", + ["requires"] = { + }, + }, + ["Container"] = { + ["default"] = true, + ["path"] = "elements/Container.lua", + ["size"] = 27475, + ["description"] = "The container class. It is a visual element that can contain other elements. It is the base class for all containers", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Dialog"] = { + ["default"] = true, + ["path"] = "elements/Dialog.lua", + ["size"] = 8878, + ["description"] = "A dialog overlay system with common presets (alert, confirm, prompt).", + ["requires"] = { + [1] = "Frame", + }, + }, + ["Display"] = { + ["default"] = false, + ["path"] = "elements/Display.lua", + ["size"] = 4668, + ["description"] = "The Display is a special element which uses the CC Window API which you can use.", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["SideNav"] = { + ["default"] = true, + ["path"] = "elements/SideNav.lua", + ["size"] = 22135, + ["description"] = "A SideNav element that provides sidebar navigation with multiple content areas.", + ["requires"] = { + [1] = "Container", + }, + }, + ["Breadcrumb"] = { + ["default"] = true, + ["path"] = "elements/Breadcrumb.lua", + ["size"] = 4314, + ["description"] = "", + ["requires"] = { + [1] = "VisualElement", + }, }, }, }, ["core"] = { ["description"] = "Core Files", ["files"] = { - ["layoutManager"] = { + ["init"] = { + ["default"] = true, + ["path"] = "init.lua", + ["size"] = 622, ["description"] = "", - ["path"] = "layoutManager.lua", ["requires"] = { }, - ["size"] = 3634, - ["default"] = true, }, ["errorManager"] = { - ["description"] = "", + ["default"] = true, ["path"] = "errorManager.lua", - ["requires"] = { - }, ["size"] = 3789, - ["default"] = true, - }, - ["log"] = { ["description"] = "", - ["path"] = "log.lua", ["requires"] = { }, - ["size"] = 3142, + }, + ["layoutManager"] = { ["default"] = true, + ["path"] = "layoutManager.lua", + ["size"] = 3634, + ["description"] = "", + ["requires"] = { + }, }, ["propertySystem"] = { - ["description"] = "", + ["default"] = true, ["path"] = "propertySystem.lua", - ["requires"] = { - }, ["size"] = 18186, - ["default"] = true, - }, - ["render"] = { ["description"] = "", - ["path"] = "render.lua", ["requires"] = { }, - ["size"] = 12422, - ["default"] = true, - }, - ["elementManager"] = { - ["description"] = "", - ["path"] = "elementManager.lua", - ["requires"] = { - }, - ["size"] = 15411, - ["default"] = true, - }, - ["init"] = { - ["description"] = "", - ["path"] = "init.lua", - ["requires"] = { - }, - ["size"] = 622, - ["default"] = true, }, ["main"] = { - ["description"] = "", + ["default"] = true, ["path"] = "main.lua", - ["requires"] = { - }, ["size"] = 19883, - ["default"] = true, - }, - }, - }, - ["plugins"] = { - ["description"] = "Plugins", - ["files"] = { - ["canvas"] = { ["description"] = "", - ["path"] = "plugins/canvas.lua", ["requires"] = { }, - ["size"] = 7873, - ["default"] = true, }, - ["reactive"] = { + ["render"] = { + ["default"] = true, + ["path"] = "render.lua", + ["size"] = 12422, ["description"] = "", - ["path"] = "plugins/reactive.lua", ["requires"] = { }, - ["size"] = 11845, - ["default"] = true, }, - ["theme"] = { + ["elementManager"] = { + ["default"] = true, + ["path"] = "elementManager.lua", + ["size"] = 15411, ["description"] = "", - ["path"] = "plugins/theme.lua", ["requires"] = { }, - ["size"] = 6775, - ["default"] = true, }, - ["xml"] = { + ["log"] = { + ["default"] = true, + ["path"] = "log.lua", + ["size"] = 3142, ["description"] = "", - ["path"] = "plugins/xml.lua", ["requires"] = { }, - ["size"] = 14042, - ["default"] = true, - }, - ["debug"] = { - ["description"] = "", - ["path"] = "plugins/debug.lua", - ["requires"] = { - }, - ["size"] = 6250, - ["default"] = true, - }, - ["animation"] = { - ["description"] = "", - ["path"] = "plugins/animation.lua", - ["requires"] = { - }, - ["size"] = 18421, - ["default"] = true, - }, - ["benchmark"] = { - ["description"] = "", - ["path"] = "plugins/benchmark.lua", - ["requires"] = { - [1] = "VisualElement", - }, - ["size"] = 12581, - ["default"] = true, }, }, }, ["libraries"] = { ["description"] = "Libraries", ["files"] = { - ["colorHex"] = { - ["description"] = "", - ["path"] = "libraries/colorHex.lua", - ["requires"] = { - }, - ["size"] = 132, - ["default"] = true, - }, ["utils"] = { - ["description"] = "", + ["default"] = true, ["path"] = "libraries/utils.lua", - ["requires"] = { - }, ["size"] = 2661, - ["default"] = true, - }, - ["collectionentry"] = { ["description"] = "", - ["path"] = "libraries/collectionentry.lua", ["requires"] = { }, - ["size"] = 3551, - ["default"] = true, }, ["expect"] = { - ["description"] = "", + ["default"] = true, ["path"] = "libraries/expect.lua", + ["size"] = 846, + ["description"] = "", ["requires"] = { }, - ["size"] = 846, + }, + ["colorHex"] = { ["default"] = true, + ["path"] = "libraries/colorHex.lua", + ["size"] = 132, + ["description"] = "", + ["requires"] = { + }, + }, + ["collectionentry"] = { + ["default"] = true, + ["path"] = "libraries/collectionentry.lua", + ["size"] = 3551, + ["description"] = "", + ["requires"] = { + }, + }, + }, + }, + ["plugins"] = { + ["description"] = "Plugins", + ["files"] = { + ["xml"] = { + ["default"] = true, + ["path"] = "plugins/xml.lua", + ["size"] = 14042, + ["description"] = "", + ["requires"] = { + }, + }, + ["canvas"] = { + ["default"] = true, + ["path"] = "plugins/canvas.lua", + ["size"] = 7873, + ["description"] = "", + ["requires"] = { + }, + }, + ["theme"] = { + ["default"] = true, + ["path"] = "plugins/theme.lua", + ["size"] = 6775, + ["description"] = "", + ["requires"] = { + }, + }, + ["animation"] = { + ["default"] = true, + ["path"] = "plugins/animation.lua", + ["size"] = 18421, + ["description"] = "", + ["requires"] = { + }, + }, + ["reactive"] = { + ["default"] = true, + ["path"] = "plugins/reactive.lua", + ["size"] = 11845, + ["description"] = "", + ["requires"] = { + }, + }, + ["benchmark"] = { + ["default"] = true, + ["path"] = "plugins/benchmark.lua", + ["size"] = 12581, + ["description"] = "", + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["debug"] = { + ["default"] = true, + ["path"] = "plugins/debug.lua", + ["size"] = 6250, + ["description"] = "", + ["requires"] = { + }, }, }, }, diff --git a/release/basalt-core.lua b/release/basalt-core.lua new file mode 100644 index 0000000..9989695 --- /dev/null +++ b/release/basalt-core.lua @@ -0,0 +1,3710 @@ +local minified = true +local minified_elementDirectory = {} +local minified_pluginDirectory = {} +local project = {} +local loadedProject = {} +local baseRequire = require +require = function(path) if(project[path..".lua"])then if(loadedProject[path]==nil)then loadedProject[path] = project[path..".lua"]() end return loadedProject[path] end return baseRequire(path) end +minified_elementDirectory["BaseFrame"] = {} +minified_elementDirectory["Timer"] = {} +minified_elementDirectory["Program"] = {} +minified_elementDirectory["BarChart"] = {} +minified_elementDirectory["ScrollFrame"] = {} +minified_elementDirectory["TabControl"] = {} +minified_elementDirectory["Button"] = {} +minified_elementDirectory["Label"] = {} +minified_elementDirectory["SideNav"] = {} +minified_elementDirectory["Input"] = {} +minified_elementDirectory["Toast"] = {} +minified_elementDirectory["Switch"] = {} +minified_elementDirectory["Frame"] = {} +minified_elementDirectory["Container"] = {} +minified_elementDirectory["Dialog"] = {} +minified_elementDirectory["Tree"] = {} +minified_elementDirectory["Breadcrumb"] = {} +minified_elementDirectory["Table"] = {} +minified_elementDirectory["Menu"] = {} +minified_elementDirectory["Slider"] = {} +minified_elementDirectory["ScrollBar"] = {} +minified_elementDirectory["VisualElement"] = {} +minified_elementDirectory["ProgressBar"] = {} +minified_elementDirectory["CheckBox"] = {} +minified_elementDirectory["BaseElement"] = {} +minified_elementDirectory["ContextMenu"] = {} +minified_elementDirectory["List"] = {} +minified_elementDirectory["Collection"] = {} +minified_elementDirectory["Accordion"] = {} +minified_pluginDirectory["canvas"] = {} +minified_pluginDirectory["theme"] = {} +minified_pluginDirectory["reactive"] = {} +minified_pluginDirectory["xml"] = {} +minified_pluginDirectory["debug"] = {} +minified_pluginDirectory["animation"] = {} +minified_pluginDirectory["benchmark"] = {} +project["errorManager.lua"] = function(...) local d=require("log") +local _a={tracebackEnabled=true,header="Basalt Error"}local function aa(ba,ca)term.setTextColor(ca)print(ba) +term.setTextColor(colors.white)end +function _a.error(ba) +if _a.errorHandled then error()end;term.setBackgroundColor(colors.black) +term.clear()term.setCursorPos(1,1) +aa(_a.header..":",colors.red)print()local ca=2;local da;while true do local db=debug.getinfo(ca,"Sl") +if not db then break end;da=db;ca=ca+1 end;local _b=da or +debug.getinfo(2,"Sl")local ab=_b.source:sub(2) +local bb=_b.currentline;local cb=ba +if(_a.tracebackEnabled)then local db=debug.traceback() +if db then +for _c in db:gmatch("[^\r\n]+")do +local ac,bc=_c:match("([^:]+):(%d+):") +if ac and bc then term.setTextColor(colors.lightGray) +term.write(ac)term.setTextColor(colors.gray)term.write(":") +term.setTextColor(colors.lightBlue)term.write(bc)term.setTextColor(colors.gray)_c=_c:gsub( +ac..":"..bc,"")end;aa(_c,colors.gray)end;print()end end +if ab and bb then term.setTextColor(colors.red) +term.write("Error in ")term.setTextColor(colors.white)term.write(ab) +term.setTextColor(colors.red)term.write(":") +term.setTextColor(colors.lightBlue)term.write(bb)term.setTextColor(colors.red) +term.write(": ") +if cb then cb=string.gsub(cb,"stack traceback:.*","") +if cb~=""then +aa(cb,colors.red)else aa("Error message not available",colors.gray)end else aa("Error message not available",colors.gray)end;local db=fs.open(ab,"r") +if db then local _c=""local ac=1 +repeat _c=db.readLine()if +ac==tonumber(bb)then aa("\149Line "..bb,colors.cyan) +aa(_c,colors.lightGray)break end;ac=ac+1 until not _c;db.close()end end;term.setBackgroundColor(colors.black) +d.error(ba)_a.errorHandled=true;error()end;return _a end +project["render.lua"] = function(...) local _a=require("libraries/colorHex")local aa=require("log") +local ba={}ba.__index=ba;local ca=string.sub +function ba.new(da)local _b=setmetatable({},ba) +_b.terminal=da;_b.width,_b.height=da.getSize() +_b.buffer={text={},fg={},bg={},dirtyRects={}} +for y=1,_b.height do _b.buffer.text[y]=string.rep(" ",_b.width) +_b.buffer.fg[y]=string.rep("0",_b.width)_b.buffer.bg[y]=string.rep("f",_b.width)end;return _b end;function ba:addDirtyRect(da,_b,ab,bb) +table.insert(self.buffer.dirtyRects,{x=da,y=_b,width=ab,height=bb})return self end +function ba:blit(da,_b,ab,bb,cb)if +_b<1 or _b>self.height then return self end;if(#ab~=#bb or +#ab~=#cb)then +error("Text, fg, and bg must be the same length")end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.fg[_b]=ca( +self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width) +self.buffer.bg[_b]=ca( +self.buffer.bg[_b]:sub(1,da-1)..cb..self.buffer.bg[_b]:sub(da+#cb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:multiBlit(da,_b,ab,bb,cb,db,_c)if _b<1 or _b>self.height then return self end;if( +#cb~=#db or#cb~=#_c)then +error("Text, fg, and bg must be the same length")end;cb=cb:rep(ab) +db=db:rep(ab)_c=_c:rep(ab) +for dy=0,bb-1 do local ac=_b+dy +if ac>=1 and ac<=self.height then +self.buffer.text[ac]=ca(self.buffer.text[ac]:sub(1, +da-1)..cb.. +self.buffer.text[ac]:sub(da+#cb),1,self.width) +self.buffer.fg[ac]=ca( +self.buffer.fg[ac]:sub(1,da-1)..db..self.buffer.fg[ac]:sub(da+#db),1,self.width) +self.buffer.bg[ac]=ca( +self.buffer.bg[ac]:sub(1,da-1).._c..self.buffer.bg[ac]:sub(da+#_c),1,self.width)end end;self:addDirtyRect(da,_b,ab,bb)return self end +function ba:textFg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end +bb=_a[bb]or"0"bb=bb:rep(#ab) +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.fg[_b]=ca( +self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:textBg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end +bb=_a[bb]or"f" +self.buffer.text[_b]=ca( +self.buffer.text[_b]:sub(1,da-1).. +ab..self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.bg[_b]=ca( +self.buffer.bg[_b]:sub(1,da-1).. +bb:rep(#ab)..self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, +da-1)..ab.. +self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, +da-1)..ab.. +self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, +da-1)..ab.. +self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, +da-1)..ab.. +self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:clear(da)local _b=_a[da]or"f" +for y=1,self.height do +self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) +self.buffer.bg[y]=string.rep(_b,self.width)self:addDirtyRect(1,y,self.width,1)end;return self end +function ba:render()local da={} +for _b,ab in ipairs(self.buffer.dirtyRects)do local bb=false;for cb,db in ipairs(da)do +if +self:rectOverlaps(ab,db)then self:mergeRects(db,ab)bb=true;break end end;if not bb then +table.insert(da,ab)end end +for _b,ab in ipairs(da)do +for y=ab.y,ab.y+ab.height-1 do +if y>=1 and y<=self.height then +self.terminal.setCursorPos(ab.x,y) +self.terminal.blit(self.buffer.text[y]:sub(ab.x,ab.x+ab.width-1),self.buffer.fg[y]:sub(ab.x, +ab.x+ab.width-1),self.buffer.bg[y]:sub(ab.x, +ab.x+ab.width-1))end end end;self.buffer.dirtyRects={} +if self.blink then +self.terminal.setTextColor(self.cursorColor or +colors.white) +self.terminal.setCursorPos(self.xCursor,self.yCursor)self.terminal.setCursorBlink(true)else +self.terminal.setCursorBlink(false)end;return self end +function ba:rectOverlaps(da,_b)return +not( +da.x+da.width<=_b.x or _b.x+_b.width<=da.x or da.y+da.height<=_b.y or +_b.y+_b.height<=da.y)end +function ba:mergeRects(da,_b)local ab=math.min(da.x,_b.x) +local bb=math.min(da.y,_b.y) +local cb=math.max(da.x+da.width,_b.x+_b.width) +local db=math.max(da.y+da.height,_b.y+_b.height)da.x=ab;da.y=bb;da.width=cb-ab;da.height=db-bb;return self end +function ba:setCursor(da,_b,ab,bb) +if bb~=nil then self.terminal.setTextColor(bb)end;self.terminal.setCursorPos(da,_b) +self.terminal.setCursorBlink(ab)self.xCursor=da;self.yCursor=_b;self.blink=ab;self.cursorColor=bb +return self end +function ba:clearArea(da,_b,ab,bb,cb)local db=_a[cb]or"f" +for dy=0,bb-1 do local _c=_b+dy;if +_c>=1 and _c<=self.height then local ac=string.rep(" ",ab)local bc=string.rep(db,ab) +self:blit(da,_c,ac,"0",db)end end;return self end;function ba:getSize()return self.width,self.height end +function ba:setSize(da,_b) +self.width=da;self.height=_b +for y=1,self.height do +self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) +self.buffer.bg[y]=string.rep("f",self.width)end;return self end;return ba end +project["init.lua"] = function(...) local da={...}local _b=fs.getDir(da[2])local ab=package.path +local bb="path;/path/?.lua;/path/?/init.lua;"local cb=bb:gsub("path",_b)package.path=cb.."rom/?;"..ab +local function db(bc)package.path= +cb.."rom/?"local cc=require("errorManager") +package.path=ab;cc.header="Basalt Loading Error"cc.error(bc)end;local _c,ac=pcall(require,"main")package.loaded.log=nil +package.path=ab;if not _c then db(ac)else return ac end end +project["elements/BaseFrame.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("Container")local da=require("errorManager")local _b=require("render") +local ab=setmetatable({},ca)ab.__index=ab +local function bb(cb) +local db,_c=pcall(function()return peripheral.getType(cb)end)if db then return true end;return false end +ab.defineProperty(ab,"term",{default=nil,type="table",setter=function(cb,db)cb._peripheralName=nil;if +cb.basalt.getActiveFrame(cb._values.term)==cb then +cb.basalt.setActiveFrame(cb,false)end;if +db==nil or db.setCursorPos==nil then return db end;if(bb(db))then +cb._peripheralName=peripheral.getName(db)end;cb._values.term=db +if +cb.basalt.getActiveFrame(db)==nil then cb.basalt.setActiveFrame(cb)end;cb._render=_b.new(db)cb._renderUpdate=true;local _c,ac=db.getSize() +cb.set("width",_c)cb.set("height",ac)return db end})function ab.new()local cb=setmetatable({},ab):__init() +cb.class=ab;return cb end;function ab:init(cb,db) +ca.init(self,cb,db)self.set("term",term.current()) +self.set("type","BaseFrame")return self end +function ab:multiBlit(cb,db,_c,ac,bc,cc,dc)if +(cb<1)then _c=_c+cb-1;cb=1 end;if(db<1)then ac=ac+db-1;db=1 end +self._render:multiBlit(cb,db,_c,ac,bc,cc,dc)end;function ab:textFg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end +self._render:textFg(cb,db,_c,ac)end;function ab:textBg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 - +cb)cb=1 end +self._render:textBg(cb,db,_c,ac)end;function ab:drawText(cb,db,_c)if cb<1 then _c=string.sub(_c, +1 -cb)cb=1 end +self._render:text(cb,db,_c)end +function ab:drawFg(cb,db,_c)if cb<1 then +_c=string.sub(_c,1 -cb)cb=1 end;self._render:fg(cb,db,_c)end;function ab:drawBg(cb,db,_c)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end +self._render:bg(cb,db,_c)end +function ab:blit(cb,db,_c,ac,bc) +if cb<1 then +_c=string.sub(_c,1 -cb)ac=string.sub(ac,1 -cb)bc=string.sub(bc,1 -cb)cb=1 end;self._render:blit(cb,db,_c,ac,bc)end;function ab:setCursor(cb,db,_c,ac)local bc=self.get("term") +self._render:setCursor(cb,db,_c,ac)end +function ab:monitor_touch(cb,db,_c) +local ac=self.get("term")if ac==nil then return end +if(bb(ac))then if self._peripheralName==cb then +self:mouse_click(1,db,_c) +self.basalt.schedule(function()sleep(0.1)self:mouse_up(1,db,_c)end)end end end;function ab:mouse_click(cb,db,_c)ca.mouse_click(self,cb,db,_c) +self.basalt.setFocus(self)end +function ab:mouse_up(cb,db,_c) +ca.mouse_up(self,cb,db,_c)ca.mouse_release(self,cb,db,_c)end +function ab:term_resize()local cb,db=self.get("term").getSize() +if(cb== +self.get("width")and db==self.get("height"))then return end;self.set("width",cb)self.set("height",db) +self._render:setSize(cb,db)self._renderUpdate=true end +function ab:key(cb)self:fireEvent("key",cb)ca.key(self,cb)end +function ab:key_up(cb)self:fireEvent("key_up",cb)ca.key_up(self,cb)end +function ab:char(cb)self:fireEvent("char",cb)ca.char(self,cb)end +function ab:dispatchEvent(cb,...)local db=self.get("term")if db==nil then return end;if(bb(db))then if +cb=="mouse_click"then return end end +ca.dispatchEvent(self,cb,...)end;function ab:render() +if(self._renderUpdate)then if self._render~=nil then ca.render(self) +self._render:render()self._renderUpdate=false end end end +return ab end +project["elements/Timer.lua"] = function(...) local d=require("elementManager") +local _a=d.getElement("BaseElement")local aa=setmetatable({},_a)aa.__index=aa +aa.defineProperty(aa,"interval",{default=1,type="number"}) +aa.defineProperty(aa,"action",{default=function()end,type="function"}) +aa.defineProperty(aa,"running",{default=false,type="boolean"}) +aa.defineProperty(aa,"amount",{default=-1,type="number"})aa.defineEvent(aa,"timer")function aa.new() +local ba=setmetatable({},aa):__init()ba.class=aa;return ba end;function aa:init(ba,ca) +_a.init(self,ba,ca)self.set("type","Timer")end +function aa:start()if +not self.running then self.running=true;local ba=self.get("interval") +self.timerId=os.startTimer(ba)end;return self end +function aa:stop()if self.running then self.running=false +os.cancelTimer(self.timerId)end;return self end +function aa:dispatchEvent(ba,...)_a.dispatchEvent(self,ba,...) +if ba=="timer"then +local ca=select(1,...) +if ca==self.timerId then self.action()local da=self.get("amount")if da>0 then self.set("amount", +da-1)end;if da~=0 then +self.timerId=os.startTimer(self.get("interval"))end end end end;return aa end +project["elements/Program.lua"] = function(...) local ca=require("elementManager") +local da=ca.getElement("VisualElement")local _b=require("errorManager")local ab=setmetatable({},da) +ab.__index=ab +ab.defineProperty(ab,"program",{default=nil,type="table"}) +ab.defineProperty(ab,"path",{default="",type="string"}) +ab.defineProperty(ab,"running",{default=false,type="boolean"}) +ab.defineProperty(ab,"errorCallback",{default=nil,type="function"}) +ab.defineProperty(ab,"doneCallback",{default=nil,type="function"})ab.defineEvent(ab,"*")local bb={}bb.__index=bb +local cb=dofile("rom/modules/main/cc/require.lua").make +function bb.new(_c,ac,bc)local cc=setmetatable({},bb)cc.env=ac or{}cc.args={}cc.addEnvironment= +bc==nil and true or bc;cc.program=_c;return cc end;function bb:setArgs(...)self.args={...}end +local function db(_c) +local ac={shell=shell,multishell=multishell}ac.require,ac.package=cb(ac,_c)return ac end +function bb:run(_c,ac,bc) +self.window=window.create(self.program:getBaseFrame():getTerm(),1,1,ac,bc,false) +local cc=shell.resolveProgram(_c)or fs.exists(_c)and _c or nil +if(cc~=nil)then +if(fs.exists(cc))then local dc=fs.open(cc,"r")local _d=dc.readAll() +dc.close() +local ad=setmetatable(db(fs.getDir(_c)),{__index=_ENV})ad.term=self.window;ad.term.current=term.current +ad.term.redirect=term.redirect;ad.term.native=function()return self.window end +if +(self.addEnvironment)then for __a,a_a in pairs(self.env)do ad[__a]=a_a end else ad=self.env end +self.coroutine=coroutine.create(function()local __a=load(_d,"@/".._c,nil,ad)if __a then +local a_a=__a(table.unpack(self.args))return a_a end end)local bd=term.current()term.redirect(self.window) +local cd,dd=coroutine.resume(self.coroutine)term.redirect(bd) +if not cd then +local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end +local a_a=self.program.get("errorCallback") +if a_a then local b_a=debug.traceback(self.coroutine,dd) +local c_a=a_a(self.program,dd,b_a:gsub(dd,""))if(c_a==false)then self.filter=nil;return cd,dd end end;_b.header="Basalt Program Error ".._c;_b.error(dd)end +if coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)self.program.set("program",nil) +local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end end else _b.header="Basalt Program Error ".._c +_b.error("File not found")end else _b.header="Basalt Program Error" +_b.error("Program ".._c.." not found")end end;function bb:resize(_c,ac)self.window.reposition(1,1,_c,ac) +self:resume("term_resize",_c,ac)end +function bb:resume(_c,...)local ac={...}if +(_c:find("mouse_"))then +ac[2],ac[3]=self.program:getRelativePosition(ac[2],ac[3])end;if self.coroutine==nil or +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)return end +if +(self.filter~=nil)then if(_c~=self.filter)then return end;self.filter=nil end;local bc=term.current()term.redirect(self.window) +local cc,dc=coroutine.resume(self.coroutine,_c,table.unpack(ac))term.redirect(bc) +if cc then self.filter=dc +if +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)self.program.set("program",nil) +local _d=self.program.get("doneCallback")if _d then _d(self.program,cc,dc)end end else local _d=self.program.get("doneCallback")if _d then +_d(self.program,cc,dc)end +local ad=self.program.get("errorCallback") +if ad then local bd=debug.traceback(self.coroutine,dc) +bd=bd==nil and""or bd;dc=dc or"Unknown error" +local cd=ad(self.program,dc,bd:gsub(dc,""))if(cd==false)then self.filter=nil;return cc,dc end end;_b.header="Basalt Program Error"_b.error(dc)end;return cc,dc end +function bb:stop()if self.coroutine==nil or +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)return end +coroutine.close(self.coroutine)self.coroutine=nil end;function ab.new()local _c=setmetatable({},ab):__init() +_c.class=ab;_c.set("z",5)_c.set("width",30)_c.set("height",12) +return _c end +function ab:init(_c,ac) +da.init(self,_c,ac)self.set("type","Program") +self:observe("width",function(bc,cc) +local dc=bc.get("program") +if dc then dc:resize(cc,bc.get("height"))end end) +self:observe("height",function(bc,cc)local dc=bc.get("program")if dc then +dc:resize(bc.get("width"),cc)end end)return self end +function ab:execute(_c,ac,bc,...)self.set("path",_c)self.set("running",true) +local cc=bb.new(self,ac,bc)self.set("program",cc)cc:setArgs(...) +cc:run(_c,self.get("width"),self.get("height"),...)self:updateRender()return self end;function ab:stop()local _c=self.get("program")if _c then _c:stop() +self.set("running",false)self.set("program",nil)end +return self end;function ab:sendEvent(_c,...) +self:dispatchEvent(_c,...)return self end;function ab:onError(_c) +self.set("errorCallback",_c)return self end;function ab:onDone(_c) +self.set("doneCallback",_c)return self end +function ab:dispatchEvent(_c,...) +local ac=self.get("program")local bc=da.dispatchEvent(self,_c,...) +if ac then ac:resume(_c,...) +if +(self:hasState("focused"))then local cc=ac.window.getCursorBlink() +local dc,_d=ac.window.getCursorPos() +self:setCursor(dc,_d,cc,ac.window.getTextColor())end;self:updateRender()end;return bc end +function ab:focus() +if(da.focus(self))then local _c=self.get("program")if _c then +local ac=_c.window.getCursorBlink()local bc,cc=_c.window.getCursorPos() +self:setCursor(bc,cc,ac,_c.window.getTextColor())end end end +function ab:render()da.render(self)local _c=self.get("program") +if _c then +local ac,bc=_c.window.getSize()for y=1,bc do local cc,dc,_d=_c.window.getLine(y)if cc then +self:blit(1,y,cc,dc,_d)end end end end;return ab end +project["elements/BarChart.lua"] = function(...) local aa=require("elementManager") +local ba=aa.getElement("VisualElement")local ca=aa.getElement("Graph") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b;function _b.new() +local ab=setmetatable({},_b):__init()ab.class=_b;return ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","BarChart")return self end +function _b:render()ba.render(self)local ab=self.get("width") +local bb=self.get("height")local cb=self.get("minValue")local db=self.get("maxValue") +local _c=self.get("series")local ac=0;local bc={} +for ad,bd in pairs(_c)do if(bd.visible)then if#bd.data>0 then ac=ac+1 +table.insert(bc,bd)end end end;local cc=ac;local dc=1 +local _d=math.min(bc[1]and bc[1].pointCount or 0,math.floor((ab+dc)/ ( +cc+dc))) +for groupIndex=1,_d do local ad=( (groupIndex-1)* (cc+dc))+1 +for bd,cd in ipairs(bc)do +local dd=cd.data[groupIndex] +if dd then local __a=ad+ (bd-1)local a_a=(dd-cb)/ (db-cb) +local b_a=math.floor(bb- (a_a* (bb-1)))b_a=math.max(1,math.min(b_a,bb))for barY=b_a,bb do +self:blit(__a,barY,cd.symbol,da[cd.fgColor],da[cd.bgColor])end end end end end;return _b end +project["elements/ScrollFrame.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("Container")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarBackgroundSymbol",{default="\127",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarBackgroundColor2",{default=colors.black,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"contentWidth",{default=0,type="number",getter=function(da)local _b=0;local ab=da.get("children") +for bb,cb in ipairs(ab)do +local db=cb.get("x")local _c=cb.get("width")local ac=db+_c-1;if ac>_b then _b=ac end end;return _b end}) +ca.defineProperty(ca,"contentHeight",{default=0,type="number",getter=function(da)local _b=0;local ab=da.get("children") +for bb,cb in ipairs(ab)do +local db=cb.get("y")local _c=cb.get("height")local ac=db+_c-1;if ac>_b then _b=ac end end;return _b end})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_drag")ca.defineEvent(ca,"mouse_up") +ca.defineEvent(ca,"mouse_scroll")function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",20)da.set("height",10)da.set("z",5) +return da end +function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","ScrollFrame")return self end +function ca:mouse_click(da,_b,ab) +if aa.mouse_click(self,da,_b,ab)then +local bb,cb=self:getRelativePosition(_b,ab)local db=self.get("width")local _c=self.get("height") +local ac=self.get("showScrollBar")local bc=self.get("contentWidth") +local cc=self.get("contentHeight")local dc=ac and bc>db;local _d=dc and _c-1 or _c +local ad=ac and cc>_d;local bd=ad and db-1 or db +if +ad and bb==db and(not dc or cb<_c)then local cd=_d +local dd=math.max(1,math.floor((_d/cc)*cd))local __a=cc-_d;local a_a= +__a>0 and(self.get("offsetY")/__a*100)or 0;local b_a= +math.floor((a_a/100)* (cd-dd))+1 +if cb>=b_a and cb0 and(self.get("offsetX")/__a*100)or 0;local b_a= +math.floor((a_a/100)* (cd-dd))+1 +if bb>=b_a and bbbc;local dc=cc and db-1 or db;local _d=dc +local ad=math.max(1,math.floor((dc/ac)*_d))local bd=ac-dc;cb=math.max(1,math.min(_d,cb))local cd=cb- ( +self._scrollBarDragOffset or 0)local dd= +( (cd-1)/ (_d-ad))*100 +local __a=math.floor((dd/100)*bd+0.5) +self.set("offsetY",math.max(0,math.min(bd,__a)))return true end +if self._hScrollBarDragging then local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("width")local _c=self.get("contentWidth") +local ac=self.get("contentHeight")local bc=self.get("height") +local cc=self.get("showScrollBar")and _c>db;local dc=cc and bc-1 or bc +local _d=self.get("showScrollBar")and ac>dc;local ad=_d and db-1 or db;local bd=ad +local cd=math.max(1,math.floor((ad/_c)*bd))local dd=_c-ad;bb=math.max(1,math.min(bd,bb))local __a=bb- ( +self._hScrollBarDragOffset or 0)local a_a= +( (__a-1)/ (bd-cd))*100 +local b_a=math.floor((a_a/100)*dd+0.5) +self.set("offsetX",math.max(0,math.min(dd,b_a)))return true end;return +aa.mouse_drag and aa.mouse_drag(self,da,_b,ab)or false end +function ca:mouse_up(da,_b,ab)if self._scrollBarDragging then self._scrollBarDragging=false +self._scrollBarDragOffset=nil;return true end +if self._hScrollBarDragging then +self._hScrollBarDragging=false;self._hScrollBarDragOffset=nil;return true end;return +aa.mouse_up and aa.mouse_up(self,da,_b,ab)or false end +function ca:mouse_scroll(da,_b,ab) +if self:isInBounds(_b,ab)then +local bb,cb=self.get("offsetX"),self.get("offsetY")local db,_c=self:getRelativePosition(_b+bb,ab+cb) +local ac,bc=self:callChildrenEvent(true,"mouse_scroll",da,db,_c)if ac then return true end;local cc=self.get("height") +local dc=self.get("width")local _d=self.get("offsetY")local ad=self.get("offsetX") +local bd=self.get("contentWidth")local cd=self.get("contentHeight") +local dd=self.get("showScrollBar")and bd>dc;local __a=dd and cc-1 or cc +local a_a=self.get("showScrollBar")and cd>__a;local b_a=a_a and dc-1 or dc +if a_a then local c_a=math.max(0,cd-__a)local d_a=math.min(c_a,math.max(0, +_d+da)) +self.set("offsetY",d_a)elseif dd then local c_a=math.max(0,bd-b_a) +local d_a=math.min(c_a,math.max(0,ad+da))self.set("offsetX",d_a)end;return true end;return false end +function ca:render()aa.render(self)local da=self.get("height") +local _b=self.get("width")local ab=self.get("offsetY")local bb=self.get("offsetX") +local cb=self.get("showScrollBar")local db=self.get("contentWidth") +local _c=self.get("contentHeight")local ac=cb and db>_b;local bc=ac and da-1 or da +local cc=cb and _c>bc;local dc=cc and _b-1 or _b +if cc then local _d=bc +local ad=math.max(1,math.floor((bc/_c)*_d))local bd=_c-bc;local cd=self.get("scrollBarBackgroundSymbol") +local dd=self.get("scrollBarColor")local __a=self.get("scrollBarBackgroundColor") +local a_a=self.get("scrollBarBackgroundColor2")local b_a=bd>0 and(ab/bd*100)or 0;local c_a= +math.floor((b_a/100)* (_d-ad))+1;for i=1,_d do +if i>=c_a and i0 and(bb/bd*100)or 0;local c_a= +math.floor((b_a/100)* (_d-ad))+1;for i=1,_d do +if i>=c_a and i0 then cb._tabId=1;self:updateTabVisibility()end end;return self end;function bb:updateTabVisibility()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)end +function bb:setActiveTab(cb) +local db=self.get("activeTab")if db==cb then return self end;self.set("activeTab",cb) +self:updateTabVisibility()self:dispatchEvent("tabChanged",cb,db)return self end +function bb:isChildVisible(cb) +if not da.isChildVisible(self,cb)then return false end +if cb._tabId then return cb._tabId==self.get("activeTab")end;return true end +function bb:getContentYOffset()local cb=self:_getHeaderMetrics()return cb.headerHeight end +function bb:_getHeaderMetrics()local cb=self.get("tabs")or{} +local db=self.get("width")or 1;local _c=self.get("tabHeight")or 1 +local ac=self.get("scrollableTab")local bc={} +if ac then local cc=self.get("tabScrollOffset")or 0 +local dc=1;local _d=0 +for ad,bd in ipairs(cb)do local cd=#bd.title+2;if cd>db then cd=db end;local dd=dc-cc +local __a=0;local a_a=0;if dd<1 then __a=1 -dd end +if dd+cd-1 >db then a_a=(dd+cd-1)-db end +if dd+cd>1 and dd<=db then local b_a=math.max(1,dd)local c_a=cd-__a-a_a +table.insert(bc,{id=bd.id,title=bd.title,line=1,x1=b_a,x2= +b_a+c_a-1,width=cd,displayWidth=c_a,actualX=dc,startClip=__a,endClip=a_a})end;dc=dc+cd end;_d=dc-1;return +{headerHeight=1,lines=1,positions=bc,totalWidth=_d,scrollOffset=cc,maxScroll=math.max(0,_d-db)}else local cc=1;local dc=1 +for bd,cd in ipairs(cb)do local dd=# +cd.title+2;if dd>db then dd=db end +if dc+dd-1 >db then cc=cc+1;dc=1 end +table.insert(bc,{id=cd.id,title=cd.title,line=cc,x1=dc,x2=dc+dd-1,width=dd})dc=dc+dd end;local _d=cc;local ad=math.max(_c,_d) +return{headerHeight=ad,lines=_d,positions=bc}end end +function bb:mouse_click(cb,db,_c) +if not ca.mouse_click(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) +local cc=self:_getHeaderMetrics() +if bc<=cc.headerHeight then if#cc.positions==0 then return true end +for dc,_d in +ipairs(cc.positions)do +if _d.line==bc and ac>=_d.x1 and ac<=_d.x2 then +self:setActiveTab(_d.id)self.set("focusedChild",nil)return true end end;return true end;return da.mouse_click(self,cb,db,_c)end +function bb:getRelativePosition(cb,db) +local _c=self:_getHeaderMetrics().headerHeight +if cb==nil or db==nil then return ca.getRelativePosition(self)else +local ac,bc=ca.getRelativePosition(self,cb,db)return ac,bc-_c end end +function bb:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d=self:_getHeaderMetrics().headerHeight;return da.multiBlit(self,cb,( +db or 1)+_d,_c,ac,bc,cc,dc)end +function bb:textFg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textFg(self,cb,( +db or 1)+bc,_c,ac)end +function bb:textBg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textBg(self,cb,( +db or 1)+bc,_c,ac)end +function bb:drawText(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawText(self,cb,( +db or 1)+ac,_c)end +function bb:drawFg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawFg(self,cb,( +db or 1)+ac,_c)end +function bb:drawBg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawBg(self,cb,( +db or 1)+ac,_c)end +function bb:blit(cb,db,_c,ac,bc)local cc=self:_getHeaderMetrics().headerHeight;return da.blit(self,cb,( +db or 1)+cc,_c,ac,bc)end +function bb:mouse_up(cb,db,_c) +if not ca.mouse_up(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) +local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then return true end;return da.mouse_up(self,cb,db,_c)end +function bb:mouse_release(cb,db,_c)ca.mouse_release(self,cb,db,_c) +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight +if bc<=cc then return end;return da.mouse_release(self,cb,db,_c)end +function bb:mouse_move(cb,db,_c) +if ca.mouse_move(self,cb,db,_c)then +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then +return true end +local dc={self:getRelativePosition(db,_c)} +local _d,ad=self:callChildrenEvent(true,"mouse_move",table.unpack(dc))if _d then return true end end;return false end +function bb:mouse_drag(cb,db,_c) +if ca.mouse_drag(self,cb,db,_c)then +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then +return true end;return da.mouse_drag(self,cb,db,_c)end;return false end +function bb:scrollTabs(cb) +if not self.get("scrollableTab")then return self end;local db=self:_getHeaderMetrics() +local _c=self.get("tabScrollOffset")or 0;local ac=db.maxScroll or 0;local bc=_c+ (cb*5) +bc=math.max(0,math.min(ac,bc))self.set("tabScrollOffset",bc)return self end +function bb:mouse_scroll(cb,db,_c) +if ca.mouse_scroll(self,cb,db,_c)then +local ac=self:_getHeaderMetrics().headerHeight;if self.get("scrollableTab")and _c==self.get("y")then +self:scrollTabs(cb)return true end;return +da.mouse_scroll(self,cb,db,_c)end;return false end +function bb:setCursor(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight +if +self.parent then local cc,dc=self:calculatePosition()local _d=cb+cc-1 +local ad=db+dc-1 +bc +if + +(_d<1)or(_d>self.parent.get("width"))or(ad<1)or(ad>self.parent.get("height"))then return self.parent:setCursor(_d,ad,false)end;return self.parent:setCursor(_d,ad,_c,ac)end;return self end +function bb:render()ca.render(self)local cb=self.get("width") +local db=self:_getHeaderMetrics()local _c=db.headerHeight or 1 +ca.multiBlit(self,1,1,cb,_c," ",_b[self.get("foreground")],_b[self.get("headerBackground")])local ac=self.get("activeTab") +for bc,cc in ipairs(db.positions)do +local dc=(cc.id==ac)and +self.get("activeTabBackground")or self.get("headerBackground")local _d=(cc.id==ac)and self.get("activeTabTextColor")or +self.get("foreground") +ca.multiBlit(self,cc.x1,cc.line, +cc.displayWidth or(cc.x2 -cc.x1 +1),1," ",_b[self.get("foreground")],_b[dc])local ad=cc.title;local bd=1 + (cc.startClip or 0) +local cd=#cc.title- (cc.startClip or +0)- (cc.endClip or 0)if cd>0 then ad=cc.title:sub(bd,bd+cd-1)local dd=cc.x1;if +(cc.startClip or 0)==0 then dd=dd+1 end +ca.textFg(self,dd,cc.line,ad,_d)end end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(bc)end end +for bc,cc in ipairs(self.get("visibleChildren")or{})do if cc==self then +error("CIRCULAR REFERENCE DETECTED!")return end;cc:render()cc:postRender()end end +function bb:sortChildrenEvents(cb) +local db=self._values.childrenEvents and self._values.childrenEvents[cb] +if db then local _c={}for ac,bc in ipairs(db)do +if self:isChildVisible(bc)then table.insert(_c,bc)end end +for i=2,#_c do local ac=_c[i] +local bc=ac.get("z")local cc=i-1 +while cc>0 do local dc=_c[cc].get("z")if dc>bc then _c[cc+1]=_c[cc] +cc=cc-1 else break end end;_c[cc+1]=ac end +self._values.visibleChildrenEvents=self._values.visibleChildrenEvents or{}self._values.visibleChildrenEvents[cb]=_c end;self.set("childrenEventsSorted",true)return self end;return bb end +project["elements/Button.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement") +local ba=require("libraries/utils").getCenteredPosition;local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"text",{default="Button",type="string",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up")function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",10)da.set("height",3)da.set("z",5) +return da end;function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","Button")end +function ca:render() +aa.render(self)local da=self.getResolved("text") +da=da:sub(1,self.get("width")) +local _b,ab=ba(da,self.get("width"),self.get("height")) +self:textFg(_b,ab,da,self.getResolved("foreground"))end;return ca end +project["elements/Label.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/utils").wrapText +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"text",{default="Label",type="string",canTriggerRender=true,setter=function(da,_b) +if(type(_b)=="function")then _b=_b()end +if(da.get("autoSize"))then da.set("width",#_b)else da.set("height",# +ba(_b,da.get("width")))end;return _b end}) +ca.defineProperty(ca,"autoSize",{default=true,type="boolean",canTriggerRender=true,setter=function(da,_b)if(_b)then +da.set("width",#da.get("text"))else +da.set("height",#ba(da.get("text"),da.get("width")))end;return _b end}) +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("z",3)da.set("foreground",colors.black) +da.set("backgroundEnabled",false)return da end +function ca:init(da,_b)aa.init(self,da,_b)if(self.parent)then +self.set("background",self.parent.get("background")) +self.set("foreground",self.parent.get("foreground"))end +self.set("type","Label")return self end;function ca:getWrappedText()local da=self.get("text") +local _b=ba(da,self.get("width"))return _b end +function ca:render() +aa.render(self)local da=self.get("text") +if(self.get("autoSize"))then +self:textFg(1,1,da,self.get("foreground"))else local _b=ba(da,self.get("width"))for ab,bb in ipairs(_b)do +self:textFg(1,ab,bb,self.get("foreground"))end end end;return ca end +project["elements/SideNav.lua"] = function(...) local aa=require("elementManager") +local ba=require("elements/VisualElement")local ca=aa.getElement("Container") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"activeTab",{default=nil,type="number",allowNil=true,canTriggerRender=true,setter=function(ab,bb) +return bb end}) +_b.defineProperty(_b,"sidebarWidth",{default=12,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"tabs",{default={},type="table"}) +_b.defineProperty(_b,"sidebarBackground",{default=colors.gray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"activeTabBackground",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"activeTabTextColor",{default=colors.black,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"sidebarScrollOffset",{default=0,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"sidebarPosition",{default="left",type="string",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +_b.defineEvent(_b,"mouse_up")_b.defineEvent(_b,"mouse_scroll")function _b.new() +local ab=setmetatable({},_b):__init()ab.class=_b;ab.set("width",30)ab.set("height",15) +ab.set("z",10)return ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","SideNav")end +function _b:newTab(ab)local bb=self.get("tabs")or{}local cb=#bb+1 +table.insert(bb,{id=cb,title=tostring( +ab or("Item "..cb))})self.set("tabs",bb)if not self.get("activeTab")then +self.set("activeTab",cb)end;self:updateTabVisibility() +local db=self;local _c={} +setmetatable(_c,{__index=function(ac,bc) +if +type(bc)=="string"and bc:sub(1,3)=="add"and type(db[bc])=="function"then +return +function(dc,...) +local _d=db[bc](db,...) +if _d then _d._tabId=cb;db.set("childrenSorted",false) +db.set("childrenEventsSorted",false)db:updateRender()end;return _d end end;local cc=db[bc]if type(cc)=="function"then +return function(dc,...)return cc(db,...)end end;return cc end})return _c end;_b.addTab=_b.newTab;function _b:setTab(ab,bb)ab._tabId=bb +self:updateTabVisibility()return self end +function _b:addElement(ab,bb) +local cb=ca.addElement(self,ab)local db=bb or self.get("activeTab")if db then cb._tabId=db +self:updateTabVisibility()end;return cb end +function _b:addChild(ab)ca.addChild(self,ab)if not ab._tabId then +local bb=self.get("tabs")or{} +if#bb>0 then ab._tabId=1;self:updateTabVisibility()end end;return self end;function _b:updateTabVisibility()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)end +function _b:setActiveTab(ab) +local bb=self.get("activeTab")if bb==ab then return self end;self.set("activeTab",ab) +self:updateTabVisibility()self:dispatchEvent("tabChanged",ab,bb)return self end +function _b:isChildVisible(ab) +if not ca.isChildVisible(self,ab)then return false end +if ab._tabId then return ab._tabId==self.get("activeTab")end;return true end +function _b:getContentXOffset()local ab=self:_getSidebarMetrics()return ab.sidebarWidth end +function _b:_getSidebarMetrics()local ab=self.get("tabs")or{} +local bb=self.get("height")or 1;local cb=self.get("sidebarWidth")or 12;local db= +self.get("sidebarScrollOffset")or 0 +local _c=self.get("sidebarPosition")or"left"local ac={}local bc=1;local cc=#ab +for dc,_d in ipairs(ab)do local ad=1;local bd=bc-db;local cd=0;local dd=0 +if bd<1 then cd=1 -bd end;if bd+ad-1 >bb then dd=(bd+ad-1)-bb end +if +bd+ad>1 and bd<=bb then local __a=math.max(1,bd)local a_a=ad-cd-dd +table.insert(ac,{id=_d.id,title=_d.title,y1=__a,y2=__a+a_a-1,height=ad,displayHeight=a_a,actualY=bc,startClip=cd,endClip=dd})end;bc=bc+ad end;return +{sidebarWidth=cb,sidebarPosition=_c,positions=ac,totalHeight=cc,scrollOffset=db,maxScroll=math.max(0,cc-bb)}end +function _b:mouse_click(ab,bb,cb) +if not ba.mouse_click(self,ab,bb,cb)then return false end;local db,_c=ba.getRelativePosition(self,bb,cb) +local ac=self:_getSidebarMetrics()local bc=self.get("width")or 1;local cc=false;if +ac.sidebarPosition=="right"then cc=db> (bc-ac.sidebarWidth)else +cc=db<=ac.sidebarWidth end +if cc then if#ac.positions==0 then +return true end;for dc,_d in ipairs(ac.positions)do +if _c>=_d.y1 and _c<=_d.y2 then +self:setActiveTab(_d.id)self.set("focusedChild",nil)return true end end +return true end;return ca.mouse_click(self,ab,bb,cb)end +function _b:getRelativePosition(ab,bb)local cb=self:_getSidebarMetrics() +local db=self.get("width")or 1 +if ab==nil or bb==nil then return ba.getRelativePosition(self)else +local _c,ac=ba.getRelativePosition(self,ab,bb) +if cb.sidebarPosition=="right"then return _c,ac else return _c-cb.sidebarWidth,ac end end end +function _b:multiBlit(ab,bb,cb,db,_c,ac,bc)local cc=self:_getSidebarMetrics() +if +cc.sidebarPosition=="right"then return ca.multiBlit(self,ab,bb,cb,db,_c,ac,bc)else +return ca.multiBlit(self,(ab or 1)+ +cc.sidebarWidth,bb,cb,db,_c,ac,bc)end end +function _b:textFg(ab,bb,cb,db)local _c=self:_getSidebarMetrics() +if +_c.sidebarPosition=="right"then return ca.textFg(self,ab,bb,cb,db)else return +ca.textFg(self,(ab or 1)+_c.sidebarWidth,bb,cb,db)end end +function _b:textBg(ab,bb,cb,db)local _c=self:_getSidebarMetrics() +if +_c.sidebarPosition=="right"then return ca.textBg(self,ab,bb,cb,db)else return +ca.textBg(self,(ab or 1)+_c.sidebarWidth,bb,cb,db)end end +function _b:drawText(ab,bb,cb)local db=self:_getSidebarMetrics() +if +db.sidebarPosition=="right"then return ca.drawText(self,ab,bb,cb)else return +ca.drawText(self,(ab or 1)+db.sidebarWidth,bb,cb)end end +function _b:drawFg(ab,bb,cb)local db=self:_getSidebarMetrics() +if +db.sidebarPosition=="right"then return ca.drawFg(self,ab,bb,cb)else return +ca.drawFg(self,(ab or 1)+db.sidebarWidth,bb,cb)end end +function _b:drawBg(ab,bb,cb)local db=self:_getSidebarMetrics() +if +db.sidebarPosition=="right"then return ca.drawBg(self,ab,bb,cb)else return +ca.drawBg(self,(ab or 1)+db.sidebarWidth,bb,cb)end end +function _b:blit(ab,bb,cb,db,_c)local ac=self:_getSidebarMetrics() +if ac.sidebarPosition=="right"then return +ca.blit(self,ab,bb,cb,db,_c)else return +ca.blit(self,(ab or 1)+ac.sidebarWidth,bb,cb,db,_c)end end +function _b:mouse_up(ab,bb,cb) +if not ba.mouse_up(self,ab,bb,cb)then return false end;local db,_c=ba.getRelativePosition(self,bb,cb) +local ac=self:_getSidebarMetrics()local bc=self.get("width")or 1;local cc=false;if +ac.sidebarPosition=="right"then cc=db> (bc-ac.sidebarWidth)else +cc=db<=ac.sidebarWidth end;if cc then return true end;return +ca.mouse_up(self,ab,bb,cb)end +function _b:mouse_release(ab,bb,cb)ba.mouse_release(self,ab,bb,cb) +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then return end;return ca.mouse_release(self,ab,bb,cb)end +function _b:mouse_move(ab,bb,cb) +if ba.mouse_move(self,ab,bb,cb)then +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then return true end +local dc={self:getRelativePosition(bb,cb)} +local _d,ad=self:callChildrenEvent(true,"mouse_move",table.unpack(dc))if _d then return true end end;return false end +function _b:mouse_drag(ab,bb,cb) +if ba.mouse_drag(self,ab,bb,cb)then +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then return true end;return ca.mouse_drag(self,ab,bb,cb)end;return false end +function _b:scrollSidebar(ab)local bb=self:_getSidebarMetrics()local cb= +self.get("sidebarScrollOffset")or 0;local db=bb.maxScroll or 0;local _c=cb+ +(ab*2)_c=math.max(0,math.min(db,_c)) +self.set("sidebarScrollOffset",_c)return self end +function _b:mouse_scroll(ab,bb,cb) +if ba.mouse_scroll(self,ab,bb,cb)then +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then self:scrollSidebar(ab)return true end;return +ca.mouse_scroll(self,ab,bb,cb)end;return false end +function _b:setCursor(ab,bb,cb,db)local _c=self:_getSidebarMetrics() +if self.parent then +local ac,bc=self:calculatePosition()local cc,dc +if _c.sidebarPosition=="right"then cc=ab+ac-1;dc=bb+bc-1 else cc=ab+ac-1 + +_c.sidebarWidth;dc=bb+bc-1 end +if + +(cc<1)or(cc>self.parent.get("width"))or(dc<1)or(dc>self.parent.get("height"))then return self.parent:setCursor(cc,dc,false)end;return self.parent:setCursor(cc,dc,cb,db)end;return self end +function _b:render()ba.render(self)local ab=self.get("height") +local bb=self:_getSidebarMetrics()local cb=bb.sidebarWidth or 12;for y=1,ab do +ba.multiBlit(self,1,y,cb,1," ",da[self.get("foreground")],da[self.get("sidebarBackground")])end +local db=self.get("activeTab") +for _c,ac in ipairs(bb.positions)do +local bc= +(ac.id==db)and self.get("activeTabBackground")or self.get("sidebarBackground")local cc=(ac.id==db)and self.get("activeTabTextColor")or +self.get("foreground")local dc= +ac.displayHeight or(ac.y2 -ac.y1 +1)for dy=0,dc-1 do +ba.multiBlit(self,1, +ac.y1 +dy,cb,1," ",da[self.get("foreground")],da[bc])end;local _d=ac.title;if#_d>cb-2 then _d=_d:sub(1, +cb-2)end +ba.textFg(self,2,ac.y1,_d,cc)end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for _c in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(_c)end end +for _c,ac in ipairs(self.get("visibleChildren")or{})do if ac==self then +error("CIRCULAR REFERENCE DETECTED!")return end;ac:render()ac:postRender()end end +function _b:sortChildrenEvents(ab) +local bb=self._values.childrenEvents and self._values.childrenEvents[ab] +if bb then local cb={}for db,_c in ipairs(bb)do +if self:isChildVisible(_c)then table.insert(cb,_c)end end +for i=2,#cb do local db=cb[i] +local _c=db.get("z")local ac=i-1 +while ac>0 do local bc=cb[ac].get("z")if bc>_c then cb[ac+1]=cb[ac] +ac=ac-1 else break end end;cb[ac+1]=db end +self._values.visibleChildrenEvents=self._values.visibleChildrenEvents or{}self._values.visibleChildrenEvents[ab]=cb end;self.set("childrenEventsSorted",true)return self end;return _b end +project["elements/Input.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"text",{default="",type="string",canTriggerRender=true}) +aa.defineProperty(aa,"cursorPos",{default=1,type="number"}) +aa.defineProperty(aa,"viewOffset",{default=0,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"maxLength",{default=nil,type="number"}) +aa.defineProperty(aa,"placeholder",{default="...",type="string"}) +aa.defineProperty(aa,"placeholderColor",{default=colors.gray,type="color"}) +aa.defineProperty(aa,"pattern",{default=nil,type="string"}) +aa.defineProperty(aa,"cursorColor",{default=nil,type="number"}) +aa.defineProperty(aa,"replaceChar",{default=nil,type="string",canTriggerRender=true})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"mouse_up")aa.defineEvent(aa,"key")aa.defineEvent(aa,"char") +aa.defineEvent(aa,"paste") +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",8)ba.set("z",3)return ba end +function aa:init(ba,ca)d.init(self,ba,ca)self.set("type","Input")return self end +function aa:setCursor(ba,ca,da,_b) +ba=math.min(self.get("width"),math.max(1,ba))return d.setCursor(self,ba,ca,da,_b)end +function aa:char(ba) +if not self:hasState("focused")then return false end;local ca=self.get("text")local da=self.get("cursorPos") +local _b=self.get("maxLength")local ab=self.get("pattern") +if _b and#ca>=_b then return false end;if ab and not ba:match(ab)then return false end +self.set("text",ca:sub(1, +da-1)..ba..ca:sub(da))self.set("cursorPos",da+1)self:updateViewport()local bb= +self.get("cursorPos")-self.get("viewOffset") +self:setCursor(bb,1,true, +self.get("cursorColor")or self.get("foreground"))d.char(self,ba)return true end +function aa:key(ba,ca) +if not self:hasState("focused")then return false end;local da=self.get("cursorPos")local _b=self.get("text") +local ab=self.get("viewOffset")local bb=self.get("width") +if ba==keys.left then +if da>1 then +self.set("cursorPos",da-1)if da-1 <=ab then +self.set("viewOffset",math.max(0,da-2))end end elseif ba==keys.right then +if da<=#_b then self.set("cursorPos",da+1)if da-ab>=bb then self.set("viewOffset", +da-bb+1)end end elseif ba==keys.backspace then if da>1 then +self.set("text",_b:sub(1,da-2).._b:sub(da))self.set("cursorPos",da-1)self:updateRender() +self:updateViewport()end end +local cb=self.get("cursorPos")-self.get("viewOffset") +self:setCursor(cb,1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))d.key(self,ba,ca)return true end +function aa:mouse_click(ba,ca,da) +if d.mouse_click(self,ba,ca,da)then +local _b,ab=self:getRelativePosition(ca,da)local bb=self.get("text")local cb=self.get("viewOffset") +local db=#bb+1;local _c=math.min(db,cb+_b)self.set("cursorPos",_c) +local ac=_c-cb +self:setCursor(ac,1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))return true end;return false end +function aa:updateViewport()local ba=self.get("width") +local ca=self.get("cursorPos")local da=self.get("viewOffset") +local _b=#self.get("text") +if ca-da>=ba then self.set("viewOffset",ca-ba+1)elseif ca<=da then self.set("viewOffset", +ca-1)end +self.set("viewOffset",math.max(0,math.min(self.get("viewOffset"),_b-ba+1)))return self end +function aa:focus()d.focus(self) +self:setCursor(self.get("cursorPos")- +self.get("viewOffset"),1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))self:updateRender()end +function aa:blur()d.blur(self) +self:setCursor(1,1,false,self.getResolved("cursorColor")or +self.getResolved("foreground"))self:updateRender()end +function aa:paste(ba) +if not self:hasState("focused")then return false end;local ca=self.get("text")local da=self.get("cursorPos") +local _b=self.get("maxLength")local ab=self.get("pattern") +local bb=ca:sub(1,da-1)..ba..ca:sub(da)if _b and#bb>_b then bb=bb:sub(1,_b)end;if +ab and not bb:match(ab)then return false end;self.set("text",bb)self.set("cursorPos",da+ +#ba)self:updateViewport()end +function aa:render()local ba=self.getResolved("text") +local ca=self.get("viewOffset")local da=self.getResolved("placeholder") +local _b=self:hasState("focused")local ab,bb=self.get("width"),self.get("height") +local cb=self.getResolved("replaceChar") +self:multiBlit(1,1,ab,bb," ",_a[self.getResolved("foreground")],_a[self.getResolved("background")])if#ba==0 and#da~=0 and not _b then +self:textFg(1,1,da:sub(1,ab),self.getResolved("placeholderColor"))return end;if(_b)then +self:setCursor( +self.get("cursorPos")-ca,1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))end +local db=ba:sub(ca+1,ca+ab)if cb and#cb>0 then db=cb:rep(#db)end +self:textFg(1,1,db,self.getResolved("foreground"))end;return aa end +project["elements/Toast.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"title",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"message",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"duration",{default=3,type="number"}) +ca.defineProperty(ca,"toastType",{default="default",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"autoHide",{default=true,type="boolean"}) +ca.defineProperty(ca,"active",{default=false,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"colorMap",{default={success=colors.green,error=colors.red,warning=colors.orange,info=colors.lightBlue,default=colors.gray},type="table"})ca.defineEvent(ca,"timer")function ca.new() +local da=setmetatable({},ca):__init()da.class=ca;da.set("width",30)da.set("height",3) +da.set("z",100)return da end;function ca:init(da,_b) +aa.init(self,da,_b)return self end +function ca:show(da,_b,ab)local bb,cb,db +if type(_b)=="string"then bb=da +cb=_b;db=ab or self.get("duration")elseif type(_b)=="number"then bb="" +cb=da;db=_b else bb=""cb=da;db=self.get("duration")end;self.set("title",bb)self.set("message",cb) +self.set("active",true)if self._hideTimerId then os.cancelTimer(self._hideTimerId) +self._hideTimerId=nil end +if +self.get("autoHide")and db>0 then self._hideTimerId=os.startTimer(db)end;return self end +function ca:hide()self.set("active",false)self.set("title","") +self.set("message","")if self._hideTimerId then os.cancelTimer(self._hideTimerId) +self._hideTimerId=nil end;return self end;function ca:success(da,_b,ab)self.set("toastType","success") +return self:show(da,_b,ab)end;function ca:error(da,_b,ab) +self.set("toastType","error")return self:show(da,_b,ab)end +function ca:warning(da,_b,ab) +self.set("toastType","warning")return self:show(da,_b,ab)end;function ca:info(da,_b,ab)self.set("toastType","info") +return self:show(da,_b,ab)end +function ca:dispatchEvent(da,...) +aa.dispatchEvent(self,da,...)if da=="timer"then local _b=select(1,...) +if _b==self._hideTimerId then self:hide()end end end +function ca:render()aa.render(self) +if not self.get("active")then return end;local da=self.get("width")local _b=self.get("height") +local ab=self.getResolved("title")local bb=self.getResolved("message") +local cb=self.getResolved("toastType")local db=self.getResolved("colorMap") +local _c=db[cb]or db.default;local ac=self.getResolved("foreground")local bc=1;local cc=1 +if ab~=""then local dc=ab:sub(1, +da-bc+1)self:textFg(bc,cc,dc,_c)cc=cc+1 end +if bb~=""and cc<=_b then local dc=da-bc+1;local _d={}for bd in bb:gmatch("%S+")do +table.insert(_d,bd)end;local ad="" +for bd,cd in ipairs(_d)do if#ad+#cd+1 >dc then if cc<=_b then +self:textFg(bc,cc,ad,ac)cc=cc+1;ad=cd else break end else +ad=ad==""and cd or ad.." "..cd end end +if ad~=""and cc<=_b then self:textFg(bc,cc,ad,ac)end end end;return ca end +project["elements/Switch.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"checked",{default=false,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"text",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"autoSize",{default=false,type="boolean"}) +ca.defineProperty(ca,"onBackground",{default=colors.green,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"offBackground",{default=colors.red,type="number",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up") +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",2)da.set("height",1)da.set("z",5) +da.set("backgroundEnabled",true)return da end +function ca:init(da,_b)aa.init(self,da,_b)self.set("type","Switch")end +function ca:mouse_click(da,_b,ab)if aa.mouse_click(self,da,_b,ab)then +self.set("checked",not self.get("checked"))return true end;return false end +function ca:render()local da=self.get("checked")local _b=self.get("text") +local ab=self.get("width")local bb=self.get("height")local cb=da and self.get("onBackground")or +self.get("offBackground") +self:multiBlit(1,1,ab,bb," ",ba[self.get("foreground")],ba[cb])local db=math.floor(ab/2)local _c=da and(ab-db+1)or 1 +self:multiBlit(_c,1,db,bb," ",ba[self.get("foreground")],ba[self.get("background")])if _b~=""then +self:textFg(ab+2,1,_b,self.get("foreground"))end end;return ca end +project["elements/Frame.lua"] = function(...) local aa=require("elementManager") +local ba=aa.getElement("VisualElement")local ca=aa.getElement("Container")local da=setmetatable({},ca) +da.__index=da +da.defineProperty(da,"draggable",{default=false,type="boolean"}) +da.defineProperty(da,"draggingMap",{default={{x=1,y=1,width="width",height=1}},type="table"}) +da.defineProperty(da,"scrollable",{default=false,type="boolean"})da.defineEvent(da,"mouse_click") +da.defineEvent(da,"mouse_drag")da.defineEvent(da,"mouse_up") +da.defineEvent(da,"mouse_scroll") +function da.new()local ab=setmetatable({},da):__init() +ab.class=da;ab.set("width",12)ab.set("height",6) +ab.set("background",colors.gray)ab.set("z",10)return ab end;function da:init(ab,bb)ca.init(self,ab,bb)self.set("type","Frame") +return self end +function da:mouse_click(ab,bb,cb) +if self:isInBounds(bb,cb)then +if +self.get("draggable")then local db,_c=self:getRelativePosition(bb,cb) +local ac=self.get("draggingMap") +for bc,cc in ipairs(ac)do local dc=cc.width or 1;local _d=cc.height or 1;if +type(dc)=="string"and dc=="width"then dc=self.get("width")elseif +type(dc)=="function"then dc=dc(self)end +if type(_d)== +"string"and _d=="height"then _d=self.get("height")elseif +type(_d)=="function"then _d=_d(self)end;local ad=cc.y or 1 +if +db>=cc.x and db<=cc.x+dc-1 and _c>=ad and _c<=ad+_d-1 then +self.dragStartX=bb-self.get("x")self.dragStartY=cb-self.get("y")self.dragging=true +return true end end end;return ca.mouse_click(self,ab,bb,cb)end;return false end +function da:mouse_up(ab,bb,cb)if self.dragging then self.dragging=false;self.dragStartX=nil +self.dragStartY=nil;return true end;return +ca.mouse_up(self,ab,bb,cb)end +function da:mouse_drag(ab,bb,cb) +if self.dragging then local db=bb-self.dragStartX +local _c=cb-self.dragStartY;self.set("x",db)self.set("y",_c)return true end;return ca.mouse_drag(self,ab,bb,cb)end +function da:getChildrenHeight()local ab=0;local bb=self.get("children") +for cb,db in ipairs(bb)do if +db.get("visible")then local _c=db.get("y")local ac=db.get("height")local bc=_c+ac-1 +if bc>ab then ab=bc end end end;return ab end +local function _b(ab,bb,...)local cb={...} +if bb and bb:find("mouse_")then local db,_c,ac=... +local bc,cc=ab.get("offsetX"),ab.get("offsetY")local dc,_d=ab:getRelativePosition(_c+bc,ac+cc) +cb={db,dc,_d}end;return cb end +function da:mouse_scroll(ab,bb,cb) +if(ba.mouse_scroll(self,ab,bb,cb))then +local db=_b(self,"mouse_scroll",ab,bb,cb) +local _c,ac=self:callChildrenEvent(true,"mouse_scroll",table.unpack(db))if _c then return true end +if self.get("scrollable")then +local bc=self.get("height")local cc=self:getChildrenHeight() +local dc=self.get("offsetY")local _d=math.max(0,cc-bc)local ad=dc+ab +ad=math.max(0,math.min(_d,ad))self.set("offsetY",ad)return true end end;return false end;return da end +project["elements/Container.lua"] = function(...) local _b=require("elementManager") +local ab=require("errorManager")local bb=_b.getElement("VisualElement") +local cb=require("layoutManager")local db=require("libraries/expect") +local _c=require("libraries/utils").split;local ac=setmetatable({},bb)ac.__index=ac +ac.defineProperty(ac,"children",{default={},type="table"}) +ac.defineProperty(ac,"childrenSorted",{default=true,type="boolean"}) +ac.defineProperty(ac,"childrenEventsSorted",{default=true,type="boolean"}) +ac.defineProperty(ac,"childrenEvents",{default={},type="table"}) +ac.defineProperty(ac,"eventListenerCount",{default={},type="table"}) +ac.defineProperty(ac,"focusedChild",{default=nil,type="table",allowNil=true,setter=function(dc,_d,ad)local bd=dc._values.focusedChild +if _d==bd then return _d end +if bd then +if bd:isType("Container")then bd.set("focusedChild",nil,true)end;bd:setFocused(false,true)end;if _d and not ad then _d:setFocused(true,true)if dc.parent then +dc.parent:setFocusedChild(dc)end end;return +_d end}) +ac.defineProperty(ac,"visibleChildren",{default={},type="table"}) +ac.defineProperty(ac,"visibleChildrenEvents",{default={},type="table"}) +ac.defineProperty(ac,"offsetX",{default=0,type="number",canTriggerRender=true,setter=function(dc,_d)dc.set("childrenSorted",false) +dc.set("childrenEventsSorted",false)return _d end}) +ac.defineProperty(ac,"offsetY",{default=0,type="number",canTriggerRender=true,setter=function(dc,_d)dc.set("childrenSorted",false) +dc.set("childrenEventsSorted",false)return _d end}) +ac.combineProperties(ac,"offset","offsetX","offsetY") +for dc,_d in pairs(_b:getElementList())do +local ad=dc:sub(1,1):upper()..dc:sub(2) +if ad~="BaseFrame"then +ac["add"..ad]=function(bd,...)db(1,bd,"table") +local cd=bd.basalt.create(dc,...)bd:addChild(cd)return cd end +ac["addDelayed"..ad]=function(bd,cd)db(1,bd,"table") +local dd=bd.basalt.create(dc,cd,true,bd)return dd end end end;function ac.new()local dc=setmetatable({},ac):__init() +dc.class=ac;return dc end +function ac:init(dc,_d) +bb.init(self,dc,_d)self.set("type","Container") +self:observe("width",function() +self.set("childrenSorted",false)self.set("childrenEventsSorted",false) +self:updateRender()end) +self:observe("height",function()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)self:updateRender()end)end +function ac:isChildVisible(dc) +if not dc:isType("VisualElement")then return false end;if(dc.get("visible")==false)then return false end;if(dc._destroyed)then return +false end +local _d,ad=self.get("width"),self.get("height")local bd,cd=self.get("offsetX"),self.get("offsetY") +local dd,__a=dc.get("x"),dc.get("y")local a_a,b_a=dc.get("width"),dc.get("height")local c_a;local d_a;if +(dc.get("ignoreOffset"))then c_a=dd;d_a=__a else c_a=dd-bd;d_a=__a-cd end;return +(c_a+ +a_a>0)and(c_a<=_d)and(d_a+b_a>0)and(d_a<=ad)end +function ac:addChild(dc) +if dc==self then error("Cannot add container to itself")end;if(dc~=nil)then table.insert(self._values.children,dc) +dc.parent=self;dc:postInit()self.set("childrenSorted",false) +self:registerChildrenEvents(dc)end;return +self end +local function bc(dc,_d)local ad={}for bd,cd in ipairs(_d)do +if dc:isChildVisible(cd)and cd.get("visible")and not +cd._destroyed then table.insert(ad,cd)end end +for i=2,#ad do +local bd=ad[i]local cd=bd.get("z")local dd=i-1 +while dd>0 do local __a=ad[dd].get("z")if __a>cd then +ad[dd+1]=ad[dd]dd=dd-1 else break end end;ad[dd+1]=bd end;return ad end +function ac:clear()self.set("children",{}) +self.set("childrenEvents",{})self.set("visibleChildren",{}) +self.set("visibleChildrenEvents",{})self.set("childrenSorted",true) +self.set("childrenEventsSorted",true)return self end +function ac:sortChildren()self.set("childrenSorted",true)if self._layoutInstance then +self:updateLayout()end +self.set("visibleChildren",bc(self,self._values.children))return self end +function ac:sortChildrenEvents(dc)if self._values.childrenEvents[dc]then +self._values.visibleChildrenEvents[dc]=bc(self,self._values.childrenEvents[dc])end +self.set("childrenEventsSorted",true)return self end +function ac:registerChildrenEvents(dc)if(dc._registeredEvents==nil)then return end +for _d in +pairs(dc._registeredEvents)do self:registerChildEvent(dc,_d)end;return self end +function ac:registerChildEvent(dc,_d) +if not self._values.childrenEvents[_d]then +self._values.childrenEvents[_d]={}self._values.eventListenerCount[_d]=0;if self.parent then +self.parent:registerChildEvent(self,_d)end end +for ad,bd in ipairs(self._values.childrenEvents[_d])do if bd.get("id")== +dc.get("id")then return self end end;self.set("childrenEventsSorted",false) +table.insert(self._values.childrenEvents[_d],dc)self._values.eventListenerCount[_d]= +self._values.eventListenerCount[_d]+1;return self end +function ac:removeChildrenEvents(dc) +if dc~=nil then +if(dc._registeredEvents==nil)then return self end;for _d in pairs(dc._registeredEvents)do +self:unregisterChildEvent(dc,_d)end end;return self end +function ac:unregisterChildEvent(dc,_d) +if self._values.childrenEvents[_d]then +for ad,bd in +ipairs(self._values.childrenEvents[_d])do +if bd.get("id")==dc.get("id")then +table.remove(self._values.childrenEvents[_d],ad)self._values.eventListenerCount[_d]= +self._values.eventListenerCount[_d]-1 +if +self._values.eventListenerCount[_d]<=0 then +self._values.childrenEvents[_d]=nil;self._values.eventListenerCount[_d]=nil;if self.parent then +self.parent:unregisterChildEvent(self,_d)end end;self.set("childrenEventsSorted",false)break end end end;return self end +function ac:removeChild(dc)if dc==nil then return self end +for _d,ad in ipairs(self._values.children)do if +ad.get("id")==dc.get("id")then +table.remove(self._values.children,_d)dc.parent=nil;break end end;self:removeChildrenEvents(dc)self:updateRender() +self.set("childrenSorted",false)return self end +function ac:getChild(dc) +if type(dc)=="string"then local _d=_c(dc,"/") +for ad,bd in +pairs(self._values.children)do if bd.get("name")==_d[1]then +if#_d==1 then return bd else if(bd:isType("Container"))then return +bd:find(table.concat(_d,"/",2))end end end end end;return nil end +local function cc(dc,_d,...)local ad={...} +if _d and _d:find("mouse_")then local bd,cd,dd=... +local __a,a_a=dc.get("offsetX"),dc.get("offsetY")local b_a,c_a=dc:getRelativePosition(cd+__a,dd+a_a) +ad={bd,b_a,c_a}end;return ad end +function ac:callChildrenEvent(dc,_d,...) +if +dc and not self.get("childrenEventsSorted")then for bd in pairs(self._values.childrenEvents)do +self:sortChildrenEvents(bd)end end;local ad=dc and self.get("visibleChildrenEvents")or +self.get("childrenEvents") +if +ad[_d]then local bd=ad[_d]for i=#bd,1,-1 do local cd=bd[i] +if(cd:dispatchEvent(_d,...))then return true,cd end end end +if(ad["*"])then local bd=ad["*"]for i=#bd,1,-1 do local cd=bd[i] +if(cd:dispatchEvent(_d,...))then return true,cd end end end;return false end +function ac:handleEvent(dc,...)bb.handleEvent(self,dc,...)local _d=cc(self,dc,...)return +self:callChildrenEvent(false,dc,table.unpack(_d))end +function ac:mouse_click(dc,_d,ad) +if bb.mouse_click(self,dc,_d,ad)then +local bd=cc(self,"mouse_click",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_click",table.unpack(bd)) +if(cd)then self.set("focusedChild",dd)return true end;self.set("focusedChild",nil)return true end;return false end +function ac:mouse_up(dc,_d,ad)self:mouse_release(dc,_d,ad) +if bb.mouse_up(self,dc,_d,ad)then +local bd=cc(self,"mouse_up",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_up",table.unpack(bd))if(cd)then return true end end;return false end +function ac:mouse_release(dc,_d,ad)bb.mouse_release(self,dc,_d,ad) +local bd=cc(self,"mouse_release",dc,_d,ad) +self:callChildrenEvent(false,"mouse_release",table.unpack(bd))end +function ac:mouse_move(dc,_d,ad) +if bb.mouse_move(self,dc,_d,ad)then +local bd=cc(self,"mouse_move",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_move",table.unpack(bd))if(cd)then return true end end;return false end +function ac:mouse_drag(dc,_d,ad) +if bb.mouse_drag(self,dc,_d,ad)then +local bd=cc(self,"mouse_drag",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_drag",table.unpack(bd))if(cd)then return true end end;return false end +function ac:mouse_scroll(dc,_d,ad) +if(bb.mouse_scroll(self,dc,_d,ad))then +local bd=cc(self,"mouse_scroll",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_scroll",table.unpack(bd))return true end;return false end;function ac:key(dc)if self.get("focusedChild")then return +self.get("focusedChild"):dispatchEvent("key",dc)end +return true end +function ac:char(dc)if +self.get("focusedChild")then +return self.get("focusedChild"):dispatchEvent("char",dc)end;return true end;function ac:key_up(dc) +if self.get("focusedChild")then return +self.get("focusedChild"):dispatchEvent("key_up",dc)end;return true end +function ac:multiBlit(dc,_d,ad,bd,cd,dd,__a) +local a_a,b_a=self.get("width"),self.get("height")ad=dc<1 and math.min(ad+dc-1,a_a)or +math.min(ad,math.max(0,a_a-dc+1))bd=_d<1 and math.min( +bd+_d-1,b_a)or +math.min(bd,math.max(0,b_a-_d+1))if ad<=0 or +bd<=0 then return self end +bb.multiBlit(self,math.max(1,dc),math.max(1,_d),ad,bd,cd,dd,__a)return self end +function ac:textFg(dc,_d,ad,bd)local cd,dd=self.get("width"),self.get("height")if +_d<1 or _d>dd then return self end;local __a=dc<1 and(2 -dc)or 1 +local a_a=math.min(#ad- +__a+1,cd-math.max(1,dc)+1)if a_a<=0 then return self end +bb.textFg(self,math.max(1,dc),math.max(1,_d),ad:sub(__a, +__a+a_a-1),bd)return self end +function ac:textBg(dc,_d,ad,bd)local cd,dd=self.get("width"),self.get("height")if +_d<1 or _d>dd then return self end;local __a=dc<1 and(2 -dc)or 1 +local a_a=math.min(#ad- +__a+1,cd-math.max(1,dc)+1)if a_a<=0 then return self end +bb.textBg(self,math.max(1,dc),math.max(1,_d),ad:sub(__a, +__a+a_a-1),bd)return self end +function ac:drawText(dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if _d<1 or +_d>cd then return self end;local dd=dc<1 and(2 -dc)or 1 +local __a=math.min( +#ad-dd+1,bd-math.max(1,dc)+1)if __a<=0 then return self end +bb.drawText(self,math.max(1,dc),math.max(1,_d),ad:sub(dd, +dd+__a-1))return self end +function ac:drawFg(dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if +_d<1 or _d>cd then return self end;local dd=dc<1 and(2 -dc)or 1 +local __a=math.min(#ad- +dd+1,bd-math.max(1,dc)+1)if __a<=0 then return self end +bb.drawFg(self,math.max(1,dc),math.max(1,_d),ad:sub(dd,dd+__a-1))return self end +function ac:drawBg(dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if +_d<1 or _d>cd then return self end;local dd=dc<1 and(2 -dc)or 1 +local __a=math.min(#ad- +dd+1,bd-math.max(1,dc)+1)if __a<=0 then return self end +bb.drawBg(self,math.max(1,dc),math.max(1,_d),ad:sub(dd,dd+__a-1))return self end +function ac:blit(dc,_d,ad,bd,cd)local dd,__a=self.get("width"),self.get("height")if +_d<1 or _d>__a then return self end;local a_a=dc<1 and(2 -dc)or 1 +local b_a=math.min( +#ad-a_a+1,dd-math.max(1,dc)+1) +local c_a=math.min(#bd-a_a+1,dd-math.max(1,dc)+1) +local d_a=math.min(#cd-a_a+1,dd-math.max(1,dc)+1)if b_a<=0 then return self end;local _aa=ad:sub(a_a,a_a+b_a-1)local aaa=bd:sub(a_a, +a_a+c_a-1) +local baa=cd:sub(a_a,a_a+d_a-1) +bb.blit(self,math.max(1,dc),math.max(1,_d),_aa,aaa,baa)return self end +function ac:render()bb.render(self)if not self.get("childrenSorted")then +self:sortChildren()end +if +not self.get("childrenEventsSorted")then for dc in pairs(self._values.childrenEvents)do +self:sortChildrenEvents(dc)end end;for dc,_d in ipairs(self.get("visibleChildren"))do if _d==self then +ab.error("CIRCULAR REFERENCE DETECTED!")return end;_d:render() +_d:postRender()end end +function ac:applyLayout(dc,_d) +if self._layoutInstance then cb.destroy(self._layoutInstance)end;self._layoutInstance=cb.apply(self,dc)if _d then +self._layoutInstance.options=_d end;return self end;function ac:updateLayout() +if self._layoutInstance then cb.update(self._layoutInstance)end;return self end +function ac:clearLayout() +if +self._layoutInstance then local dc=require("layoutManager") +dc.destroy(self._layoutInstance)self._layoutInstance=nil end;return self end +function ac:destroy() +if not self:isType("BaseFrame")then +for dc,_d in +ipairs(self._values.children)do if _d.destroy then _d:destroy()end end;self:removeAllObservers()bb.destroy(self)return self else +ab.header="Basalt Error"ab.error("Cannot destroy a BaseFrame.")end end;return ac end +project["elements/Dialog.lua"] = function(...) local d=require("elementManager") +local _a=d.getElement("Frame")local aa=setmetatable({},_a)aa.__index=aa +aa.defineProperty(aa,"title",{default="",type="string",canTriggerRender=true}) +aa.defineProperty(aa,"primaryColor",{default=colors.lime,type="color"}) +aa.defineProperty(aa,"secondaryColor",{default=colors.lightGray,type="color"}) +aa.defineProperty(aa,"buttonForeground",{default=colors.black,type="color"}) +aa.defineProperty(aa,"modal",{default=true,type="boolean"})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"close") +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("z",100)ba.set("width",30) +ba.set("height",10)ba.set("background",colors.gray) +ba.set("foreground",colors.white)ba.set("borderColor",colors.cyan)return ba end +function aa:init(ba,ca)_a.init(self,ba,ca) +self:addBorder({left=true,right=true,top=true,bottom=true})self.set("type","Dialog")return self end +function aa:show()self:center()self.set("visible",true)if +self.get("modal")then self:setFocused(true)end;return self end;function aa:close()self.set("visible",false) +self:fireEvent("close")return self end +function aa:alert(ba,ca,da)self:clear() +self.set("title",ba)self.set("height",8) +self:addLabel({text=ca,x=2,y=3,width=self.get("width")-3,height=3,foreground=colors.white})local _b=10 +local ab=math.floor((self.get("width")-_b)/2)+1 +self:addButton({text="OK",x=ab,y=self.get("height")-2,width=_b,height=1,background=self.get("primaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +da then da()end;self:close()end)return self:show()end +function aa:confirm(ba,ca,da)self:clear()self.set("title",ba) +self.set("height",8) +self:addLabel({text=ca,x=2,y=3,width=self.get("width")-3,height=3,foreground=colors.white})local _b=10;local ab=2;local bb=_b*2 +ab;local cb= +math.floor((self.get("width")-bb)/2)+1 +self:addButton({text="Cancel",x=cb,y= +self.get("height")-2,width=_b,height=1,background=self.get("secondaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +da then da(false)end;self:close()end) +self:addButton({text="OK",x=cb+_b+ab,y=self.get("height")-2,width=_b,height=1,background=self.get("primaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +da then da(true)end;self:close()end)return self:show()end +function aa:prompt(ba,ca,da,_b)self:clear()self.set("title",ba) +self.set("height",11) +self:addLabel({text=ca,x=2,y=3,foreground=colors.white}) +local ab=self:addInput({x=2,y=5,width=self.get("width")-3,height=1,defaultText=da or"",background=colors.white,foreground=colors.black})local bb=10;local cb=2;local db=bb*2 +cb;local _c= +math.floor((self.get("width")-db)/2)+1 +self:addButton({text="Cancel",x=_c,y= +self.get("height")-2,width=bb,height=1,background=self.get("secondaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +_b then _b(nil)end;self:close()end) +self:addButton({text="OK",x=_c+bb+cb,y=self.get("height")-2,width=bb,height=1,background=self.get("primaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +_b then _b(ab.get("text")or"")end +self:close()end)return self:show()end +function aa:render()_a.render(self)local ba=self.get("title")if ba~=""then +local ca=self.get("width")local da=ba:sub(1,ca-4) +self:textFg(2,2,da,colors.white)end end +function aa:mouse_click(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then return +_a.mouse_click(self,ba,ca,da)end;return true end;return _a.mouse_click(self,ba,ca,da)end +function aa:mouse_drag(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then +return _a.mouse_drag and +_a.mouse_drag(self,ba,ca,da)or false end;return true end;return +_a.mouse_drag and _a.mouse_drag(self,ba,ca,da)or false end +function aa:mouse_up(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then +return _a.mouse_up and +_a.mouse_up(self,ba,ca,da)or false end;return true end;return +_a.mouse_up and _a.mouse_up(self,ba,ca,da)or false end +function aa:mouse_scroll(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then +return _a.mouse_scroll and +_a.mouse_scroll(self,ba,ca,da)or false end;return true end;return +_a.mouse_scroll and _a.mouse_scroll(self,ba,ca,da)or false end;return aa end +project["elements/Tree.lua"] = function(...) local aa=require("elements/VisualElement")local ba=string.sub +local ca=require("libraries/colorHex") +local function da(ab,bb,cb,db)db=db or{}cb=cb or 0;for _c,ac in ipairs(ab)do +table.insert(db,{node=ac,level=cb}) +if bb[ac]and ac.children then da(ac.children,bb,cb+1,db)end end;return db end;local _b=setmetatable({},aa)_b.__index=_b +_b.defineProperty(_b,"nodes",{default={},type="table",canTriggerRender=true,setter=function(ab,bb)if#bb>0 then +ab.get("expandedNodes")[bb[1]]=true end;return bb end}) +_b.defineProperty(_b,"selectedNode",{default=nil,type="table",canTriggerRender=true}) +_b.defineProperty(_b,"expandedNodes",{default={},type="table",canTriggerRender=true}) +_b.defineProperty(_b,"offset",{default=0,type="number",canTriggerRender=true,setter=function(ab,bb)return math.max(0,bb)end}) +_b.defineProperty(_b,"horizontalOffset",{default=0,type="number",canTriggerRender=true,setter=function(ab,bb)return math.max(0,bb)end}) +_b.defineProperty(_b,"selectedForegroundColor",{default=colors.white,type="color"}) +_b.defineProperty(_b,"selectedBackgroundColor",{default=colors.lightBlue,type="color"}) +_b.defineProperty(_b,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarBackground",{default="\127",type="string",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +_b.defineEvent(_b,"mouse_drag")_b.defineEvent(_b,"mouse_up") +_b.defineEvent(_b,"mouse_scroll")function _b.new()local ab=setmetatable({},_b):__init() +ab.class=_b;ab.set("width",30)ab.set("height",10)ab.set("z",5) +return ab end +function _b:init(ab,bb) +aa.init(self,ab,bb)self.set("type","Tree")return self end;function _b:expandNode(ab)self.get("expandedNodes")[ab]=true +self:updateRender()return self end +function _b:collapseNode(ab)self.get("expandedNodes")[ab]= +nil;self:updateRender()return self end;function _b:toggleNode(ab)if self.get("expandedNodes")[ab]then +self:collapseNode(ab)else self:expandNode(ab)end +return self end +function _b:mouse_click(ab,bb,cb) +if +aa.mouse_click(self,ab,bb,cb)then local db,_c=self:getRelativePosition(bb,cb) +local ac=self.get("width")local bc=self.get("height") +local cc=da(self.get("nodes"),self.get("expandedNodes"))local dc=self.get("showScrollBar") +local _d,ad=self:getNodeSize()local bd=dc and _d>ac;local cd=bd and bc-1 or bc +local dd=dc and#cc>cd +if dd and db==ac and(not bd or _c0 and(self.get("offset")/c_a*100)or 0;local _aa= +math.floor((d_a/100)* (a_a-b_a))+1 +if _c>=_aa and _c<_aa+b_a then +self._scrollBarDragging=true;self._scrollBarDragOffset=_c-_aa else +local aaa=( (_c-1)/ (a_a-b_a))*100;local baa=math.floor((aaa/100)*c_a+0.5) +self.set("offset",math.max(0,math.min(c_a,baa)))end;return true end +if bd and _c==bc and(not dd or db0 and +(self.get("horizontalOffset")/c_a*100)or 0 +local _aa=math.floor((d_a/100)* (a_a-b_a))+1 +if db>=_aa and db<_aa+b_a then self._hScrollBarDragging=true;self._hScrollBarDragOffset= +db-_aa else local aaa=( (db-1)/ (a_a-b_a))*100;local baa=math.floor(( +aaa/100)*c_a+0.5) +self.set("horizontalOffset",math.max(0,math.min(c_a,baa)))end;return true end;local __a=_c+self.get("offset") +if cc[__a]then local a_a=cc[__a] +local b_a=a_a.node +if db<=a_a.level*2 +2 then self:toggleNode(b_a)end;self.set("selectedNode",b_a) +self:fireEvent("node_select",b_a)end;return true end;return false end +function _b:onSelect(ab)self:registerCallback("node_select",ab)return self end +function _b:mouse_drag(ab,bb,cb) +if self._scrollBarDragging then local db,_c=self:getRelativePosition(bb,cb) +local ac=da(self.get("nodes"),self.get("expandedNodes"))local bc=self.get("height")local cc,dc=self:getNodeSize() +local _d= +self.get("showScrollBar")and cc>self.get("width")local ad=_d and bc-1 or bc;local bd=ad +local cd=math.max(1,math.floor((ad/#ac)*bd))local dd=#ac-ad;_c=math.max(1,math.min(bd,_c))local __a=_c- ( +self._scrollBarDragOffset or 0)local a_a= +( (__a-1)/ (bd-cd))*100 +local b_a=math.floor((a_a/100)*dd+0.5) +self.set("offset",math.max(0,math.min(dd,b_a)))return true end +if self._hScrollBarDragging then local db,_c=self:getRelativePosition(bb,cb) +local ac=self.get("width")local bc,cc=self:getNodeSize() +local dc=da(self.get("nodes"),self.get("expandedNodes"))local _d=self.get("height") +local ad=self.get("showScrollBar")and bc>ac;local bd=ad and _d-1 or _d +local cd=self.get("showScrollBar")and#dc>bd;local dd=cd and ac-1 or ac +local __a=math.max(1,math.floor((dd/bc)*dd))local a_a=bc-dd;db=math.max(1,math.min(dd,db))local b_a=db- ( +self._hScrollBarDragOffset or 0)local c_a= +( (b_a-1)/ (dd-__a))*100 +local d_a=math.floor((c_a/100)*a_a+0.5) +self.set("horizontalOffset",math.max(0,math.min(a_a,d_a)))return true end;return +aa.mouse_drag and aa.mouse_drag(self,ab,bb,cb)or false end +function _b:mouse_up(ab,bb,cb)if self._scrollBarDragging then self._scrollBarDragging=false +self._scrollBarDragOffset=nil;return true end +if self._hScrollBarDragging then +self._hScrollBarDragging=false;self._hScrollBarDragOffset=nil;return true end;return +aa.mouse_up and aa.mouse_up(self,ab,bb,cb)or false end +function _b:mouse_scroll(ab,bb,cb) +if aa.mouse_scroll(self,ab,bb,cb)then +local db=da(self.get("nodes"),self.get("expandedNodes"))local _c=self.get("height")local ac=self.get("width") +local bc=self.get("showScrollBar")local cc,dc=self:getNodeSize()local _d=bc and cc>ac +local ad=_d and _c-1 or _c;local bd=math.max(0,#db-ad) +local cd=math.min(bd,math.max(0,self.get("offset")+ab))self.set("offset",cd)return true end;return false end +function _b:getNodeSize()local ab,bb=0,0 +local cb=da(self.get("nodes"),self.get("expandedNodes"))local db=self.get("expandedNodes") +for _c,ac in ipairs(cb)do local bc=ac.node +local cc=ac.level;local dc=string.rep(" ",cc)local _d=" "if +bc.children and#bc.children>0 then _d=db[bc]and"\31"or"\16"end +local ad=dc.._d.. +" ".. (bc.text or"Node")ab=math.max(ab,#ad)end;bb=#cb;return ab,bb end +function _b:render()aa.render(self) +local ab=da(self.get("nodes"),self.get("expandedNodes"))local bb=self.get("height")local cb=self.get("width") +local db=self.get("selectedNode")local _c=self.get("expandedNodes") +local ac=self.get("offset")local bc=self.get("horizontalOffset") +local cc=self.get("showScrollBar")local dc,_d=self:getNodeSize()local ad=cc and dc>cb +local bd=ad and bb-1 or bb;local cd=cc and#ab>bd;local dd=cd and cb-1 or cb +for y=1,bd do +local _aa=ab[y+ac] +if _aa then local aaa=_aa.node;local baa=_aa.level;local caa=string.rep(" ",baa) +local daa=" "if aaa.children and#aaa.children>0 then +daa=_c[aaa]and"\31"or"\16"end;local _ba=aaa==db +local aba=_ba and +self.get("selectedBackgroundColor")or +(aaa.background or aaa.bg or self.get("background")) +local bba=_ba and self.get("selectedForegroundColor")or( +aaa.foreground or aaa.fg or self.get("foreground")) +local cba=caa..daa.." ".. (aaa.text or"Node")local dba=ba(cba,bc+1,bc+dd) +local _ca=dba..string.rep(" ",dd-#dba) +local aca=ca[aba]:rep(#_ca)or ca[colors.black]:rep(#_ca) +local bca=ca[bba]:rep(#_ca)or ca[colors.white]:rep(#_ca)self:blit(1,y,_ca,bca,aca)else +self:blit(1,y,string.rep(" ",dd),ca[self.get("foreground")]:rep(dd),ca[self.get("background")]:rep(dd))end end;local __a=self.getResolved("scrollBarSymbol") +local a_a=self.getResolved("scrollBarBackground")local b_a=self.getResolved("scrollBarColor") +local c_a=self.getResolved("scrollBarBackgroundColor")local d_a=self.getResolved("foreground") +if cd then +local _aa=ad and bb-1 or bb +local aaa=math.max(1,math.floor((bd/#ab)*_aa))local baa=#ab-bd;local caa=baa>0 and(ac/baa*100)or 0 +local daa=math.floor(( +caa/100)* (_aa-aaa))+1 +for i=1,_aa do self:blit(cb,i,a_a,ca[d_a],ca[c_a])end;for i=daa,math.min(_aa,daa+aaa-1)do +self:blit(cb,i,__a,ca[b_a],ca[c_a])end end +if ad then local _aa=cd and cb-1 or cb +local aaa=math.max(1,math.floor((_aa/dc)*_aa))local baa=dc-dd;local caa=baa>0 and(bc/baa*100)or 0 +local daa=math.floor(( +caa/100)* (_aa-aaa))+1 +for i=1,_aa do self:blit(i,bb,a_a,ca[d_a],ca[c_a])end;for i=daa,math.min(_aa,daa+aaa-1)do +self:blit(i,bb,__a,ca[b_a],ca[c_a])end end;if cd and ad then +self:blit(cb,bb," ",ca[d_a],ca[self.get("background")])end end;return _b end +project["elements/Breadcrumb.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"path",{default={},type="table",canTriggerRender=true}) +ca.defineProperty(ca,"separator",{default=" > ",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"clickable",{default=true,type="boolean"}) +ca.defineProperty(ca,"autoSize",{default=true,type="boolean"})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up") +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("z",5)da.set("height",1) +da.set("backgroundEnabled",false)return da end;function ca:init(da,_b)aa.init(self,da,_b) +self.set("type","Breadcrumb")end +function ca:mouse_click(da,_b,ab)if +not self.get("clickable")then return false end +if aa.mouse_click(self,da,_b,ab)then +local bb=self.get("path")local cb=self.get("separator")local db=1 +for _c,ac in ipairs(bb)do local bc=#ac;if +_b>=db and _bcb then local bc="... > "local cc=cb- +#bc +if cc>0 then db=bc..db:sub(-cc)else db=bc:sub(1,cb)end end end;local _c=1;local ac +for bc in db:gmatch("[^".._b.."]+")do ac=ab +self:textFg(_c,1,bc,ac)_c=_c+#bc;local cc=db:find(_b,_c,true)if cc then +self:textFg(_c,1,_b,bb and colors.gray or +colors.lightGray)_c=_c+#_b end end end;return ca end +project["elements/Table.lua"] = function(...) local _a=require("elements/Collection") +local aa=require("libraries/colorHex")local ba=setmetatable({},_a)ba.__index=ba +ba.defineProperty(ba,"columns",{default={},type="table",canTriggerRender=true,setter=function(da,_b)local ab={} +for bb,cb in +ipairs(_b)do +if type(cb)=="string"then ab[bb]={name=cb,width=#cb+1}elseif type(cb)=="table"then +ab[bb]={name= +cb.name or"",width=cb.width,minWidth=cb.minWidth or 3,maxWidth=cb.maxWidth or nil}end end;return ab end}) +ba.defineProperty(ba,"headerColor",{default=colors.blue,type="color"}) +ba.defineProperty(ba,"gridColor",{default=colors.gray,type="color"}) +ba.defineProperty(ba,"sortColumn",{default=nil,type="number",canTriggerRender=true}) +ba.defineProperty(ba,"sortDirection",{default="asc",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"customSortFunction",{default={},type="table"}) +ba.defineProperty(ba,"offset",{default=0,type="number",canTriggerRender=true,setter=function(da,_b)local ab=math.max(0,#da.get("items")- +(da.get("height")-1))return +math.min(ab,math.max(0,_b))end}) +ba.defineProperty(ba,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackground",{default="\127",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true})ba.defineEvent(ba,"mouse_click") +ba.defineEvent(ba,"mouse_drag")ba.defineEvent(ba,"mouse_up") +ba.defineEvent(ba,"mouse_scroll") +local ca={cells={type="table",default={}},_sortValues={type="table",default={}},selected={type="boolean",default=false},text={type="string",default=""}}function ba.new()local da=setmetatable({},ba):__init() +da.class=ba;da.set("width",30)da.set("height",10)da.set("z",5) +return da end +function ba:init(da,_b) +_a.init(self,da,_b)self._entrySchema=ca;self.set("type","Table") +self:observe("sortColumn",function() +if +self.get("sortColumn")then self:sortByColumn(self.get("sortColumn"))end end)return self end;function ba:addRow(...)local da={...} +_a.addItem(self,{cells=da,_sortValues=da,text=table.concat(da," ")})return self end;function ba:removeRow(da) +local _b=self.get("items") +if _b[da]then table.remove(_b,da)self.set("items",_b)end;return self end;function ba:getRow(da) +local _b=self.get("items")return _b[da]end +function ba:updateCell(da,_b,ab) +local bb=self.get("items")if bb[da]and bb[da].cells then bb[da].cells[_b]=ab +self.set("items",bb)end;return self end +function ba:getSelectedRow()local da=self.get("items")for _b,ab in ipairs(da)do local bb= +ab._data and ab._data.selected or ab.selected +if bb then return ab end end;return nil end;function ba:clearData()self.set("items",{})return self end;function ba:addColumn(da,_b) +local ab=self.get("columns")table.insert(ab,{name=da,width=_b}) +self.set("columns",ab)return self end +function ba:setColumnSortFunction(da,_b) +local ab=self.get("customSortFunction")ab[da]=_b;self.set("customSortFunction",ab)return self end +function ba:setData(da,_b)self:clearData() +for ab,bb in ipairs(da)do local cb={}local db={} +for _c,ac in ipairs(bb)do db[_c]=ac;if _b and +_b[_c]then cb[_c]=_b[_c](ac)else cb[_c]=ac end end +_a.addItem(self,{cells=cb,_sortValues=db,text=table.concat(cb," ")})end;return self end +function ba:getData()local da=self.get("items")local _b={}for ab,bb in ipairs(da)do local cb= +bb._data and bb._data.cells or bb.cells;if cb then +table.insert(_b,cb)end end +return _b end +function ba:calculateColumnWidths(da,_b)local ab={}local bb=_b;local cb={}local db=0 +for ac,bc in ipairs(da)do +ab[ac]={name=bc.name,width=bc.width,minWidth=bc.minWidth or 3,maxWidth=bc.maxWidth} +if type(bc.width)=="number"then +ab[ac].visibleWidth=math.max(bc.width,ab[ac].minWidth)if ab[ac].maxWidth then +ab[ac].visibleWidth=math.min(ab[ac].visibleWidth,ab[ac].maxWidth)end +bb=bb-ab[ac].visibleWidth;db=db+ab[ac].visibleWidth elseif type(bc.width)=="string"and +bc.width:match("%%$")then +local cc=tonumber(bc.width:match("(%d+)%%")) +if cc then ab[ac].visibleWidth=math.floor(_b*cc/100) +ab[ac].visibleWidth=math.max(ab[ac].visibleWidth,ab[ac].minWidth)if ab[ac].maxWidth then +ab[ac].visibleWidth=math.min(ab[ac].visibleWidth,ab[ac].maxWidth)end +bb=bb-ab[ac].visibleWidth;db=db+ab[ac].visibleWidth else table.insert(cb,ac)end else table.insert(cb,ac)end end +if#cb>0 and bb>0 then local ac=math.floor(bb/#cb) +for bc,cc in ipairs(cb)do +ab[cc].visibleWidth=math.max(ac,ab[cc].minWidth)if ab[cc].maxWidth then +ab[cc].visibleWidth=math.min(ab[cc].visibleWidth,ab[cc].maxWidth)end end end;local _c=0 +for ac,bc in ipairs(ab)do _c=_c+ (bc.visibleWidth or 0)end;if _c>_b then local ac=_b/_c +for bc,cc in ipairs(ab)do if cc.visibleWidth then +cc.visibleWidth=math.max(1,math.floor(cc.visibleWidth*ac))end end end +return ab end +function ba:sortByColumn(da,_b)local ab=self.get("items") +local bb=self.get("sortDirection")local cb=self.get("customSortFunction")local db=_b or cb[da] +if db then +table.sort(ab,function(_c,ac)return +db(_c,ac,bb)end)else +table.sort(ab,function(_c,ac) +local bc=_c._data and _c._data.cells or _c.cells +local cc=ac._data and ac._data.cells or ac.cells +local dc=_c._data and _c._data._sortValues or _c._sortValues +local _d=ac._data and ac._data._sortValues or ac._sortValues +if not _c or not ac or not bc or not cc then return false end;local ad,bd;if dc and dc[da]then ad=dc[da]else ad=bc[da]end;if _d and _d[da]then +bd=_d[da]else bd=cc[da]end +if +type(ad)=="number"and type(bd)=="number"then if bb=="asc"then return adbd end else +local cd=tostring(ad or"")local dd=tostring(bd or"") +if bb=="asc"then return cd
dd end end end)end;self.set("items",ab)return self end +function ba:onRowSelect(da)self:registerCallback("rowSelect",da)return self end +function ba:mouse_click(da,_b,ab) +if not _a.mouse_click(self,da,_b,ab)then return false end;local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("width")local _c=self.get("height")local ac=self.get("items") +local bc=self.get("showScrollBar")local cc=_c-1 +if bc and#ac>cc and bb==db and cb>1 then local dc=_c-1 +local _d=#ac-cc +local ad=math.max(1,math.floor((cc/#ac)*dc)) +local bd=_d>0 and(self.get("offset")/_d*100)or 0 +local cd=math.floor((bd/100)* (dc-ad))+1;local dd=cb-1 +if dd>=cd and dd=ad and bb1 then local dc=cb-2 +self.get("offset") +if dc>=0 and dc<#ac then +local _d=dc+1;for ad,bd in ipairs(ac)do +if bd._data then bd._data.selected=false else bd.selected=false end end +if ac[_d]then if ac[_d]._data then +ac[_d]._data.selected=true else ac[_d].selected=true end +self:fireEvent("rowSelect",_d,ac[_d])self:updateRender()end end;return true end;return true end +function ba:mouse_drag(da,_b,ab) +if self._scrollBarDragging then local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("items")local _c=self.get("height")local ac=_c-1;local bc=_c-1 +local cc=math.max(1,math.floor((ac/#db)*bc))local dc=#db-ac;local _d=cb-1 +_d=math.max(1,math.min(bc,_d))local ad=_d- (self._scrollBarDragOffset or 0)local bd=( +(ad-1)/ (bc-cc))*100 +local cd=math.floor((bd/100)*dc+0.5) +self.set("offset",math.max(0,math.min(dc,cd)))return true end;return +_a.mouse_drag and _a.mouse_drag(self,da,_b,ab)or false end +function ba:mouse_up(da,_b,ab)if self._scrollBarDragging then self._scrollBarDragging=false +self._scrollBarDragOffset=nil;return true end +return _a.mouse_up and +_a.mouse_up(self,da,_b,ab)or false end +function ba:mouse_scroll(da,_b,ab) +if _a.mouse_scroll(self,da,_b,ab)then local bb=self.get("items") +local cb=self.get("height")local db=cb-1;local _c=math.max(0,#bb-db) +local ac=math.min(_c,math.max(0, +self.get("offset")+da))self.set("offset",ac)self:updateRender()return true end;return false end +function ba:render()_a.render(self)local da=self.getResolved("columns") +local _b=self.getResolved("items")local ab=self.getResolved("sortColumn") +local bb=self.getResolved("offset")local cb=self.get("height")local db=self.get("width") +local _c=self.getResolved("showScrollBar")local ac=cb-1;local bc=_c and#_b>ac;local cc=bc and db-1 or db +local dc=self:calculateColumnWidths(da,cc)local _d=0;local ad=#dc +for cd,dd in ipairs(dc)do +if _d+dd.visibleWidth>cc then ad=cd-1;break end;_d=_d+dd.visibleWidth end;local bd=1 +for cd,dd in ipairs(dc)do if cd>ad then break end;local __a=dd.name;if cd==ab then +__a=__a.. ( +self.get("sortDirection")=="asc"and"\30"or"\31")end +self:textFg(bd,1,__a:sub(1,dd.visibleWidth),self.get("headerColor"))bd=bd+dd.visibleWidth end;if bd<=cc then +self:textBg(bd,1,string.rep(" ",cc-bd+1),self.get("background"))end +for y=2,cb do local cd=y-2 +bb;local dd=_b[cd+1] +if +dd then +local __a=dd._data and dd._data.cells or dd.cells +local a_a=dd._data and dd._data.selected or dd.selected +if __a then bd=1;local b_a=a_a and self.get("selectedBackground")or +self.get("background") +for c_a,d_a in +ipairs(dc)do if c_a>ad then break end;local _aa=tostring(__a[c_a]or"") +local aaa=_aa..string.rep(" ", +d_a.visibleWidth-#_aa)if c_a0 and(bb/__a*100)or 0 +local b_a=math.floor(( +a_a/100)* (cd-dd))+1;local c_a=self.getResolved("scrollBarSymbol") +local d_a=self.getResolved("scrollBarBackground")local _aa=self.getResolved("scrollBarColor") +local aaa=self.getResolved("scrollBarBackgroundColor")local baa=self.getResolved("foreground")for i=2,cb do +self:blit(db,i,d_a,aa[baa],aa[aaa])end;for i=b_a,math.min(cd,b_a+dd-1)do +self:blit(db,i+1,c_a,aa[_aa],aa[aaa])end end end;return ba end +project["elements/Menu.lua"] = function(...) local _a=require("elements/VisualElement") +local aa=require("elements/List")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"separatorColor",{default=colors.gray,type="color"}) +ca.defineProperty(ca,"spacing",{default=1,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"horizontalOffset",{default=0,type="number",canTriggerRender=true,setter=function(da,_b) +local ab=math.max(0,da:getTotalWidth()-da.get("width"))return math.min(ab,math.max(0,_b))end}) +ca.defineProperty(ca,"maxWidth",{default=nil,type="number",canTriggerRender=true}) +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",30)da.set("height",1) +da.set("background",colors.gray)return da end +function ca:init(da,_b)aa.init(self,da,_b)self.set("type","Menu") +self:observe("items",function() +local ab=self.get("maxWidth")if ab then +self.set("width",math.min(ab,self:getTotalWidth()),true)else +self.set("width",self:getTotalWidth(),true)end end)return self end +function ca:getTotalWidth()local da=self.get("items")local _b=self.get("spacing") +local ab=0;for bb,cb in ipairs(da)do if type(cb)=="table"then ab=ab+#cb.text else ab= +ab+#tostring(cb)+2 end +if bb<#da then ab=ab+_b end end;return ab end +function ca:render()_a.render(self)local da=self.get("width") +local _b=self.get("spacing")local ab=self.get("horizontalOffset") +local bb=self.get("items")local cb={}local db=1 +for _c,ac in ipairs(bb)do if type(ac)=="string"then +ac={text=" "..ac.." "}bb[_c]=ac end +cb[_c]={startX=db,endX=db+#ac.text-1,text=ac.text,item=ac}db=db+#ac.text;if _c<#bb and _b>0 then db=db+_b end end +for _c,ac in ipairs(cb)do local bc=ac.item;local cc=ac.startX-ab;local dc=ac.endX-ab +if cc>da then break end +if dc>=1 then local _d=math.max(1,cc)local ad=math.min(da,dc) +local bd=math.max(1,1 -cc+1) +local cd=math.min(#ac.text,#ac.text- (dc-da))local dd=ac.text:sub(bd,cd) +if#dd>0 then local __a=bc.selected +local a_a= +bc.selectable==false and self.get("separatorColor")or(__a and(bc.selectedForeground or +self.get("selectedForeground"))or(bc.foreground or +self.get("foreground"))) +local b_a= +__a and(bc.selectedBackground or self.get("selectedBackground"))or(bc.background or self.get("background")) +self:blit(_d,1,dd,string.rep(ba[a_a],#dd),string.rep(ba[b_a],#dd))end +if _c<#bb and _b>0 then local __a=ac.endX+1 -ab;local a_a=__a+_b-1 +if a_a>=1 and +__a<=da then local b_a=math.max(1,__a)local c_a=math.min(da,a_a) +local d_a=c_a-b_a+1 +if d_a>0 then local _aa=string.rep(" ",d_a) +self:blit(b_a,1,_aa,string.rep(ba[self.get("foreground")],d_a),string.rep(ba[self.get("background")],d_a))end end end end end end +function ca:mouse_click(da,_b,ab) +if not _a.mouse_click(self,da,_b,ab)then return false end +if(self.get("selectable")==false)then return false end +local bb=select(1,self:getRelativePosition(_b,ab))local cb=self.get("horizontalOffset") +local db=self.get("spacing")local _c=self.get("items")local ac=bb+cb;local bc=1 +for cc,dc in ipairs(_c)do local _d=#dc.text +if ac>= +bc and ac0 then bc=bc+db end end;return false end +function ca:mouse_scroll(da,_b,ab) +if _a.mouse_scroll(self,da,_b,ab)then +local bb=self.get("horizontalOffset") +local cb=math.max(0,self:getTotalWidth()-self.get("width"))bb=math.min(cb,math.max(0,bb+ (da*3))) +self.set("horizontalOffset",bb)return true end;return false end;return ca end +project["elements/Slider.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"step",{default=1,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"max",{default=100,type="number"}) +aa.defineProperty(aa,"horizontal",{default=true,type="boolean",canTriggerRender=true,setter=function(ba,ca)if ca then ba.set("backgroundEnabled",false)else +ba.set("backgroundEnabled",true)end end}) +aa.defineProperty(aa,"barColor",{default=colors.gray,type="color",canTriggerRender=true}) +aa.defineProperty(aa,"sliderColor",{default=colors.blue,type="color",canTriggerRender=true})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"mouse_drag")aa.defineEvent(aa,"mouse_up") +aa.defineEvent(aa,"mouse_scroll") +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",8)ba.set("height",1) +ba.set("backgroundEnabled",false)return ba end +function aa:init(ba,ca)d.init(self,ba,ca)self.set("type","Slider")end +function aa:getValue()local ba=self.get("step")local ca=self.get("max") +local da= +self.get("horizontal")and self.get("width")or self.get("height")return math.floor((ba-1)* (ca/ (da-1)))end +function aa:mouse_click(ba,ca,da) +if self:isInBounds(ca,da)then +local _b,ab=self:getRelativePosition(ca,da) +local bb=self.get("horizontal")and _b or ab;local cb=self.get("horizontal")and self.get("width")or +self.get("height") +self.set("step",math.min(cb,math.max(1,bb)))self:updateRender()return true end;return false end;aa.mouse_drag=aa.mouse_click +function aa:mouse_scroll(ba,ca,da) +if self:isInBounds(ca,da)then +local _b=self.get("step")local ab=self.get("horizontal")and self.get("width")or +self.get("height") +self.set("step",math.min(ab,math.max(1, +_b+ba)))self:updateRender()return true end;return false end +function aa:render()d.render(self)local ba=self.get("width") +local ca=self.get("height")local da=self.get("horizontal")local _b=self.get("step")local ab= +da and"\140"or" " +local bb=string.rep(ab,da and ba or ca) +if da then self:textFg(1,1,bb,self.get("barColor")) +self:textBg(_b,1," ",self.get("sliderColor"))else local cb=self.get("background") +for y=1,ca do self:textBg(1,y," ",cb)end +self:textBg(1,_b," ",self.get("sliderColor"))end end;return aa end +project["elements/ScrollBar.lua"] = function(...) local aa=require("elements/VisualElement") +local ba=require("libraries/colorHex")local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"value",{default=0,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"min",{default=0,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"max",{default=100,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"step",{default=10,type="number"}) +ca.defineProperty(ca,"dragMultiplier",{default=1,type="number"}) +ca.defineProperty(ca,"symbol",{default=" ",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"symbolColor",{default=colors.gray,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"symbolBackgroundColor",{default=colors.black,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"backgroundSymbol",{default="\127",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"attachedElement",{default=nil,type="table"}) +ca.defineProperty(ca,"attachedProperty",{default=nil,type="string"}) +ca.defineProperty(ca,"minValue",{default=0,type="number"}) +ca.defineProperty(ca,"maxValue",{default=100,type="number"}) +ca.defineProperty(ca,"orientation",{default="vertical",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"handleSize",{default=2,type="number",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_release")ca.defineEvent(ca,"mouse_drag") +ca.defineEvent(ca,"mouse_scroll") +function ca.new()local ab=setmetatable({},ca):__init() +ab.class=ca;ab.set("width",1)ab.set("height",10)return ab end;function ca:init(ab,bb)aa.init(self,ab,bb)self.set("type","ScrollBar")return +self end +function ca:attach(ab,bb) +self.set("attachedElement",ab)self.set("attachedProperty",bb.property)self.set("minValue", +bb.min or 0) +self.set("maxValue",bb.max or 100) +ab:observe(bb.property,function(cb,db) +if db then local _c=self.get("minValue") +local ac=self.get("maxValue")if _c==ac then return end +self.set("value",math.floor((db-_c)/ (ac-_c)*100 +0.5))end end)return self end +function ca:updateAttachedElement()local ab=self.get("attachedElement") +if not ab then return end;local bb=self.get("value")local cb=self.get("minValue") +local db=self.get("maxValue")if type(cb)=="function"then cb=cb()end;if type(db)=="function"then +db=db()end;local _c=cb+ (bb/100)* (db-cb)ab.set(self.get("attachedProperty"),math.floor( +_c+0.5)) +return self end;local function da(ab) +return +ab.get("orientation")=="vertical"and ab.get("height")or ab.get("width")end +local function _b(ab,bb,cb) +local db,_c=ab:getRelativePosition(bb,cb)return +ab.get("orientation")=="vertical"and _c or db end +function ca:mouse_click(ab,bb,cb) +if aa.mouse_click(self,ab,bb,cb)then local db=da(self) +local _c=self.get("value")local ac=self.get("handleSize")local bc= +math.floor((_c/100)* (db-ac))+1;local cc=_b(self,bb,cb) +if +cc>=bc and cc0 and-1 or 1;local db=self.get("step") +local _c=self.get("value")local ac=_c-ab*db +self.set("value",math.min(100,math.max(0,ac)))self:updateAttachedElement()return true end +function ca:render()aa.render(self)local ab=da(self)local bb=self.get("value") +local cb=self.get("handleSize")local db=self.get("symbol")local _c=self.get("symbolColor") +local ac=self.get("symbolBackgroundColor")local bc=self.get("backgroundSymbol")local cc=self.get("orientation")== +"vertical"local dc= +math.floor((bb/100)* (ab-cb))+1 +for i=1,ab do +if cc then +self:blit(1,i,bc,ba[self.get("foreground")],ba[self.get("background")])else +self:blit(i,1,bc,ba[self.get("foreground")],ba[self.get("background")])end end +for i=dc,dc+cb-1 do if cc then self:blit(1,i,db,ba[_c],ba[ac])else +self:blit(i,1,db,ba[_c],ba[ac])end end end;return ca end +project["elements/VisualElement.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("BaseElement")local da=require("libraries/colorHex") +local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"x",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"y",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"z",{default=1,type="number",canTriggerRender=true,setter=function(cb,db) +if cb.parent then cb.parent:sortChildren()end;return db end}) +_b.defineProperty(_b,"constraints",{default={},type="table"}) +_b.defineProperty(_b,"width",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"height",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"background",{default=colors.black,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"foreground",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"backgroundEnabled",{default=true,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderTop",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderBottom",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderLeft",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderRight",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderColor",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"visible",{default=true,type="boolean",canTriggerRender=true,setter=function(cb,db) +if(cb.parent~=nil)then +cb.parent.set("childrenSorted",false)cb.parent.set("childrenEventsSorted",false)end;if(db==false)then cb:unsetState("clicked")end;return db end}) +_b.defineProperty(_b,"ignoreOffset",{default=false,type="boolean"}) +_b.defineProperty(_b,"layoutConfig",{default={},type="table"})_b.combineProperties(_b,"position","x","y") +_b.combineProperties(_b,"size","width","height") +_b.combineProperties(_b,"color","foreground","background")_b.defineEvent(_b,"focus") +_b.defineEvent(_b,"blur") +_b.registerEventCallback(_b,"Click","mouse_click","mouse_up") +_b.registerEventCallback(_b,"ClickUp","mouse_up","mouse_click") +_b.registerEventCallback(_b,"Drag","mouse_drag","mouse_click","mouse_up") +_b.registerEventCallback(_b,"Scroll","mouse_scroll") +_b.registerEventCallback(_b,"Enter","mouse_enter","mouse_move") +_b.registerEventCallback(_b,"LeEave","mouse_leave","mouse_move")_b.registerEventCallback(_b,"Focus","focus","blur") +_b.registerEventCallback(_b,"Blur","blur","focus")_b.registerEventCallback(_b,"Key","key","key_up") +_b.registerEventCallback(_b,"Char","char")_b.registerEventCallback(_b,"KeyUp","key_up","key") +local ab,bb=math.max,math.min;function _b.new()local cb=setmetatable({},_b):__init() +cb.class=_b;return cb end +function _b:init(cb,db) +ca.init(self,cb,db)self.set("type","VisualElement") +self:registerState("disabled",nil,1000)self:registerState("clicked",nil,500) +self:registerState("hover",nil,400)self:registerState("focused",nil,300) +self:registerState("dragging",nil,600) +self:observe("x",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("y",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("width",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("height",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("visible",function()if self.parent then +self.parent.set("childrenSorted",false)end end)end +function _b:setConstraint(cb,db,_c,ac)local bc=self.get("constraints")if bc[cb]then +self:_removeConstraintObservers(cb,bc[cb])end +bc[cb]={element=db,property=_c,offset=ac or 0}self.set("constraints",bc) +self:_addConstraintObservers(cb,bc[cb])self._constraintsDirty=true;self:updateRender()return self end;function _b:setLayoutConfigProperty(cb,db)local _c=self.get("layoutConfig")_c[cb]=db +self.set("layoutConfig",_c)return self end;function _b:getLayoutConfigProperty(cb) +local db=self.get("layoutConfig")return db[cb]end +function _b:resolveAllConstraints()if not +self._constraintsDirty then return self end +local cb=self.get("constraints")if not cb or not next(cb)then return self end +local db={"width","height","left","right","top","bottom","x","y","centerX","centerY"} +for _c,ac in ipairs(db)do if cb[ac]then local bc=self:_resolveConstraint(ac,cb[ac]) +self:_applyConstraintValue(ac,bc,cb)end end;self._constraintsDirty=false;return self end +function _b:_applyConstraintValue(cb,db,_c) +if cb=="x"or cb=="left"then self.set("x",db)elseif cb=="y"or +cb=="top"then self.set("y",db)elseif cb=="right"then +if _c.left then +local ac=self:_resolveConstraint("left",_c.left)local bc=db-ac+1;self.set("width",bc)self.set("x",ac)else +local ac=self.get("width")self.set("x",db-ac+1)end elseif cb=="bottom"then +if _c.top then +local ac=self:_resolveConstraint("top",_c.top)local bc=db-ac+1;self.set("height",bc)self.set("y",ac)else +local ac=self.get("height")self.set("y",db-ac+1)end elseif cb=="centerX"then local ac=self.get("width") +self.set("x",db-math.floor(ac/2))elseif cb=="centerY"then local ac=self.get("height") +self.set("y",db-math.floor(ac/2))elseif cb=="width"then self.set("width",db)elseif cb=="height"then +self.set("height",db)end end +function _b:_addConstraintObservers(cb,db)local _c=db.element;local ac=db.property +if _c=="parent"then _c=self.parent end;if not _c then return end +local bc=function()self._constraintsDirty=true +self:resolveAllConstraints()self:updateRender()end +if not self._constraintObserverCallbacks then self._constraintObserverCallbacks={}end;if not self._constraintObserverCallbacks[cb]then +self._constraintObserverCallbacks[cb]={}end;local cc={} +if +ac=="left"or ac=="x"then cc={"x"}elseif ac=="right"then cc={"x","width"}elseif ac=="top"or ac=="y"then cc={"y"}elseif ac== +"bottom"then cc={"y","height"}elseif ac=="centerX"then cc={"x","width"}elseif ac=="centerY"then +cc={"y","height"}elseif ac=="width"then cc={"width"}elseif ac=="height"then cc={"height"}end;for dc,_d in ipairs(cc)do _c:observe(_d,bc) +table.insert(self._constraintObserverCallbacks[cb],{element=_c,property=_d,callback=bc})end end +function _b:_removeConstraintObservers(cb,db) +if not self._constraintObserverCallbacks or not +self._constraintObserverCallbacks[cb]then return end;for _c,ac in ipairs(self._constraintObserverCallbacks[cb])do +ac.element:removeObserver(ac.property,ac.callback)end;self._constraintObserverCallbacks[cb]= +nil end +function _b:_removeAllConstraintObservers() +if not self._constraintObserverCallbacks then return end +for cb,db in pairs(self._constraintObserverCallbacks)do for _c,ac in ipairs(db)do +ac.element:removeObserver(ac.property,ac.callback)end end;self._constraintObserverCallbacks=nil end +function _b:removeConstraint(cb)local db=self.get("constraints")db[cb]=nil +self.set("constraints",db)self:updateConstraints()return self end +function _b:updateConstraints()local cb=self.get("constraints") +for db,_c in pairs(cb)do +local ac=self:_resolveConstraint(db,_c) +if db=="x"or db=="left"then self.set("x",ac)elseif db=="y"or db=="top"then +self.set("y",ac)elseif db=="right"then local bc=self.get("width") +self.set("x",ac-bc+1)elseif db=="bottom"then local bc=self.get("height") +self.set("y",ac-bc+1)elseif db=="centerX"then local bc=self.get("width") +self.set("x",ac-math.floor(bc/2))elseif db=="centerY"then local bc=self.get("height") +self.set("y",ac-math.floor(bc/2))elseif db=="width"then self.set("width",ac)elseif db=="height"then +self.set("height",ac)end end end +function _b:_resolveConstraint(cb,db)local _c=db.element;local ac=db.property;local bc=db.offset;if _c=="parent"then +_c=self.parent end +if not _c then return self.get(cb)or 1 end;local cc +if ac=="left"or ac=="x"then cc=_c.get("x")elseif ac=="right"then cc=_c.get("x")+ +_c.get("width")-1 elseif ac=="top"or ac=="y"then +cc=_c.get("y")elseif ac=="bottom"then +cc=_c.get("y")+_c.get("height")-1 elseif ac=="centerX"then +cc=_c.get("x")+math.floor(_c.get("width")/2)elseif ac=="centerY"then +cc=_c.get("y")+math.floor(_c.get("height")/2)elseif ac=="width"then cc=_c.get("width")elseif ac=="height"then cc=_c.get("height")end +if type(bc)=="number"then if bc>-1 and bc<1 and bc~=0 then +return math.floor(cc*bc)else return cc+bc end end;return cc end;function _b:alignRight(cb,db)db=db or 0 +return self:setConstraint("right",cb,"right",db)end;function _b:alignLeft(cb,db)db=db or 0;return +self:setConstraint("left",cb,"left",db)end +function _b:alignTop(cb,db)db= +db or 0;return self:setConstraint("top",cb,"top",db)end;function _b:alignBottom(cb,db)db=db or 0 +return self:setConstraint("bottom",cb,"bottom",db)end +function _b:centerHorizontal(cb,db)db=db or 0;return +self:setConstraint("centerX",cb,"centerX",db)end;function _b:centerVertical(cb,db)db=db or 0 +return self:setConstraint("centerY",cb,"centerY",db)end;function _b:centerIn(cb)return +self:centerHorizontal(cb):centerVertical(cb)end +function _b:rightOf(cb,db) +db=db or 0;return self:setConstraint("left",cb,"right",db)end;function _b:leftOf(cb,db)db=db or 0 +return self:setConstraint("right",cb,"left",-db)end;function _b:below(cb,db)db=db or 0;return +self:setConstraint("top",cb,"bottom",db)end +function _b:above(cb,db) +db=db or 0;return self:setConstraint("bottom",cb,"top",-db)end;function _b:stretchWidth(cb,db)db=db or 0 +return self:setConstraint("left",cb,"left",db):setConstraint("right",cb,"right", +-db)end;function _b:stretchHeight(cb,db)db= +db or 0 +return self:setConstraint("top",cb,"top",db):setConstraint("bottom",cb,"bottom", +-db)end;function _b:stretch(cb,db)return +self:stretchWidth(cb,db):stretchHeight(cb,db)end +function _b:widthPercent(cb,db)return self:setConstraint("width",cb,"width", +db/100)end;function _b:heightPercent(cb,db) +return self:setConstraint("height",cb,"height",db/100)end;function _b:matchWidth(cb,db)db=db or 0;return +self:setConstraint("width",cb,"width",db)end;function _b:matchHeight(cb,db)db= +db or 0 +return self:setConstraint("height",cb,"height",db)end;function _b:fillParent(cb)return +self:stretch("parent",cb)end;function _b:fillWidth(cb)return +self:stretchWidth("parent",cb)end;function _b:fillHeight(cb)return +self:stretchHeight("parent",cb)end;function _b:center()return +self:centerIn("parent")end;function _b:toRight(cb)return +self:alignRight("parent",- (cb or 0))end;function _b:toLeft(cb)return self:alignLeft("parent", +cb or 0)end;function _b:toTop(cb)return self:alignTop("parent", +cb or 0)end +function _b:toBottom(cb)return self:alignBottom("parent", +- (cb or 0))end +function _b:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d,ad=self:calculatePosition()cb=cb+_d-1 +db=db+ad-1;self.parent:multiBlit(cb,db,_c,ac,bc,cc,dc)end +function _b:textFg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 +db=db+cc-1;self.parent:textFg(cb,db,_c,ac)end +function _b:textBg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 +db=db+cc-1;self.parent:textBg(cb,db,_c,ac)end +function _b:drawText(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawText(cb,db,_c)end +function _b:drawFg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawFg(cb,db,_c)end +function _b:drawBg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawBg(cb,db,_c)end +function _b:blit(cb,db,_c,ac,bc)local cc,dc=self:calculatePosition()cb=cb+cc-1 +db=db+dc-1;self.parent:blit(cb,db,_c,ac,bc)end +function _b:isInBounds(cb,db)local _c,ac=self.get("x"),self.get("y") +local bc,cc=self.get("width"),self.get("height")if(self.get("ignoreOffset"))then +if(self.parent)then +cb=cb-self.parent.get("offsetX")db=db-self.parent.get("offsetY")end end;return +cb>=_c and cb<= +_c+bc-1 and db>=ac and db<=ac+cc-1 end +function _b:mouse_click(cb,db,_c)if self:isInBounds(db,_c)then self:setState("clicked") +self:fireEvent("mouse_click",cb,self:getRelativePosition(db,_c))return true end;return +false end +function _b:mouse_up(cb,db,_c) +if self:isInBounds(db,_c)then self:unsetState("clicked") +self:unsetState("dragging") +self:fireEvent("mouse_up",cb,self:getRelativePosition(db,_c))return true end;return false end +function _b:mouse_release(cb,db,_c) +self:fireEvent("mouse_release",cb,self:getRelativePosition(db,_c))self:unsetState("clicked") +self:unsetState("dragging")end +function _b:mouse_move(cb,db,_c)if(db==nil)or(_c==nil)then return false end +local ac=self.get("hover") +if(self:isInBounds(db,_c))then if(not ac)then self.set("hover",true) +self:fireEvent("mouse_enter",self:getRelativePosition(db,_c))end;return true else if(ac)then +self.set("hover",false) +self:fireEvent("mouse_leave",self:getRelativePosition(db,_c))end end;return false end +function _b:mouse_scroll(cb,db,_c)if(self:isInBounds(db,_c))then +self:fireEvent("mouse_scroll",cb,self:getRelativePosition(db,_c))return true end;return false end +function _b:mouse_drag(cb,db,_c)if(self:hasState("clicked"))then +self:fireEvent("mouse_drag",cb,self:getRelativePosition(db,_c))return true end;return false end +function _b:setFocused(cb,db)local _c=self:hasState("focused") +if cb==_c then return self end +if cb then self:setState("focused")self:focus() +if +not db and self.parent then self.parent:setFocusedChild(self)end else self:unsetState("focused")self:blur() +if +not db and self.parent then self.parent:setFocusedChild(nil)end end;return self end +function _b:isFocused()return self:hasState("focused")end;function _b:focus()self:fireEvent("focus")end;function _b:blur() +self:fireEvent("blur") +pcall(function() +self:setCursor(1,1,false,self.get and self.getResolved("foreground"))end)end;function _b:isFocused()return +self:hasState("focused")end +function _b:addBorder(cb,db)local _c=nil;local ac=nil +if +type(cb)== +"table"and(cb.color or cb.top~=nil or cb.left~=nil)then _c=cb.color;ac=cb else _c=cb;ac=db end +if ac then +if ac.top~=nil then self.set("borderTop",ac.top)end +if ac.bottom~=nil then self.set("borderBottom",ac.bottom)end +if ac.left~=nil then self.set("borderLeft",ac.left)end +if ac.right~=nil then self.set("borderRight",ac.right)end else self.set("borderTop",true) +self.set("borderBottom",true)self.set("borderLeft",true) +self.set("borderRight",true)end;if _c then self.set("borderColor",_c)end;return self end +function _b:removeBorder()self.set("borderTop",false) +self.set("borderBottom",false)self.set("borderLeft",false) +self.set("borderRight",false)return self end;function _b:key(cb,db) +if(self:hasState("focused"))then self:fireEvent("key",cb,db)end end +function _b:key_up(cb)if +(self:hasState("focused"))then self:fireEvent("key_up",cb)end end;function _b:char(cb) +if(self:hasState("focused"))then self:fireEvent("char",cb)end end +function _b:calculatePosition() +self:resolveAllConstraints()local cb,db=self.get("x"),self.get("y") +if +not self.get("ignoreOffset")then if self.parent~=nil then +local _c,ac=self.parent.get("offsetX"),self.parent.get("offsetY")cb=cb-_c;db=db-ac end end;return cb,db end +function _b:getAbsolutePosition(cb,db)local _c,ac=self.get("x"),self.get("y")if(cb~=nil)then +_c=_c+cb-1 end;if(db~=nil)then ac=ac+db-1 end;local bc=self.parent +while bc do +local cc,dc=bc.get("x"),bc.get("y")_c=_c+cc-1;ac=ac+dc-1;bc=bc.parent end;return _c,ac end +function _b:getRelativePosition(cb,db)if(cb==nil)or(db==nil)then +cb,db=self.get("x"),self.get("y")end;local _c,ac=1,1;if self.parent then +_c,ac=self.parent:getRelativePosition()end +local bc,cc=self.get("x"),self.get("y")return cb- (bc-1)- (_c-1),db- (cc-1)- (ac-1)end +function _b:setCursor(cb,db,_c,ac) +if self.parent then local bc,cc=self:calculatePosition() +if +(cb+bc-1 <1)or( +cb+bc-1 >self.parent.get("width"))or(db+cc-1 <1)or(db+cc-1 > +self.parent.get("height"))then return self.parent:setCursor( +cb+bc-1,db+cc-1,false)end +return self.parent:setCursor(cb+bc-1,db+cc-1,_c,ac)end;return self end +function _b:prioritize() +if(self.parent)then local cb=self.parent;cb:removeChild(self) +cb:addChild(self)self:updateRender()end;return self end +function _b:render() +if(not self.getResolved("backgroundEnabled"))then return end;local cb,db=self.get("width"),self.get("height") +local _c=da[self.getResolved("foreground")]local ac=da[self.getResolved("background")] +local bc,cc,dc,_d=self.getResolved("borderTop"),self.getResolved("borderBottom"),self.getResolved("borderLeft"),self.getResolved("borderRight")self:multiBlit(1,1,cb,db," ",_c,ac) +if +(bc or cc or dc or _d)then +local ad=self.getResolved("borderColor")or self.getResolved("foreground")local bd=da[ad]or _c;if bc then +self:textFg(1,1,("\131"):rep(cb),ad)end;if cc then +self:multiBlit(1,db,cb,1,"\143",ac,bd)end;if dc then +self:multiBlit(1,1,1,db,"\149",bd,ac)end;if _d then +self:multiBlit(cb,1,1,db,"\149",ac,bd)end +if bc and dc then self:blit(1,1,"\151",bd,ac)end;if bc and _d then self:blit(cb,1,"\148",ac,bd)end;if +cc and dc then self:blit(1,db,"\138",ac,bd)end;if cc and _d then +self:blit(cb,db,"\133",ac,bd)end end end;function _b:postRender()end +function _b:destroy() +self:_removeAllConstraintObservers()self.set("visible",false)ca.destroy(self)end;return _b end +project["elements/ProgressBar.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"progress",{default=0,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"showPercentage",{default=false,type="boolean"}) +aa.defineProperty(aa,"progressColor",{default=colors.black,type="color"}) +aa.defineProperty(aa,"direction",{default="right",type="string"}) +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",25)ba.set("height",3)return ba end;function aa:init(ba,ca)d.init(self,ba,ca) +self.set("type","ProgressBar")end +function aa:render()d.render(self) +local ba=self.get("width")local ca=self.get("height") +local da=math.min(100,math.max(0,self.get("progress")))local _b=math.floor((ba*da)/100) +local ab=math.floor((ca*da)/100)local bb=self.get("direction") +local cb=self.get("progressColor") +if bb=="right"then +self:multiBlit(1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="left"then +self:multiBlit(ba-_b+1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="up"then +self:multiBlit(1,ca-ab+1,ba,ab," ",_a[self.get("foreground")],_a[cb])elseif bb=="down"then +self:multiBlit(1,1,ba,ab," ",_a[self.get("foreground")],_a[cb])end +if self.get("showPercentage")then local db=tostring(da).."%"local _c=math.floor( +(ba-#db)/2)+1 +local ac=math.floor((ca-1)/2)+1 +self:textFg(_c,ac,db,self.get("foreground"))end end;return aa end +project["elements/CheckBox.lua"] = function(...) local c=require("elements/VisualElement") +local d=setmetatable({},c)d.__index=d +d.defineProperty(d,"checked",{default=false,type="boolean",canTriggerRender=true}) +d.defineProperty(d,"text",{default=" ",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("checkedText") +local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) +d.defineProperty(d,"checkedText",{default="x",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("text") +local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) +d.defineProperty(d,"autoSize",{default=true,type="boolean"})d.defineEvent(d,"mouse_click") +d.defineEvent(d,"mouse_up")function d.new()local _a=setmetatable({},d):__init()_a.class=d +_a.set("backgroundEnabled",false)return _a end +function d:init(_a,aa) +c.init(self,_a,aa)self.set("type","CheckBox")end +function d:mouse_click(_a,aa,ba)if c.mouse_click(self,_a,aa,ba)then +self.set("checked",not self.get("checked"))return true end;return false end +function d:render()c.render(self)local _a=self.getResolved("checked") +local aa=self.getResolved("text")local ba=self.getResolved("checkedText") +local ca=string.sub(_a and ba or aa,1,self.get("width")) +self:textFg(1,1,ca,self.getResolved("foreground"))end;return d end +project["elements/BaseElement.lua"] = function(...) local _a=require("propertySystem") +local aa=require("libraries/utils").uuid;local ba=require("errorManager")local ca=setmetatable({},_a) +ca.__index=ca +ca.defineProperty(ca,"type",{default={"BaseElement"},type="string",setter=function(da,_b)if type(_b)=="string"then +table.insert(da._values.type,1,_b)return da._values.type end;return _b end,getter=function(da,_b,ab)if +ab~=nil and ab<1 then return da._values.type end;return da._values.type[ +ab or 1]end}) +ca.defineProperty(ca,"id",{default="",type="string",readonly=true}) +ca.defineProperty(ca,"name",{default="",type="string"}) +ca.defineProperty(ca,"eventCallbacks",{default={},type="table"}) +ca.defineProperty(ca,"enabled",{default=true,type="boolean"}) +ca.defineProperty(ca,"states",{default={},type="table",canTriggerRender=true}) +function ca.defineEvent(da,_b,ab) +if not rawget(da,'_eventConfigs')then da._eventConfigs={}end;da._eventConfigs[_b]={requires=ab and ab or _b}end +function ca.registerEventCallback(da,_b,...) +local ab=_b:match("^on")and _b or"on".._b;local bb={...}local cb=bb[1] +da[ab]=function(db,...) +for _c,ac in ipairs(bb)do if not db._registeredEvents[ac]then +db:listenEvent(ac,true)end end;db:registerCallback(cb,...)return db end end;function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;return da end +function ca:init(da,_b) +if self._initialized then return self end;self._initialized=true;self._props=da;self._values.id=aa() +self.basalt=_b;self._registeredEvents={}self._registeredStates={} +local ab=getmetatable(self).__index;local bb={}ab=self.class +while ab do +if type(ab)=="table"and ab._eventConfigs then for cb,db in +pairs(ab._eventConfigs)do if not bb[cb]then bb[cb]=db end end end +ab=getmetatable(ab)and getmetatable(ab).__index end +for cb,db in pairs(bb)do self._registeredEvents[db.requires]=true end;if self._callbacks then +for cb,db in pairs(self._callbacks)do self[db]=function(_c,...) +_c:registerCallback(cb,...)return _c end end end +return self end +function ca:postInit()if self._postInitialized then return self end +self._postInitialized=true;if(self._props)then +for da,_b in pairs(self._props)do self.set(da,_b)end end;self._props=nil;return self end;function ca:isType(da) +for _b,ab in ipairs(self._values.type)do if ab==da then return true end end;return false end +function ca:listenEvent(da,_b)_b= +_b~=false +if +_b~= (self._registeredEvents[da]or false)then +if _b then self._registeredEvents[da]=true;if self.parent then +self.parent:registerChildEvent(self,da)end else self._registeredEvents[da]=nil +if +self.parent then self.parent:unregisterChildEvent(self,da)end end end;return self end +function ca:registerCallback(da,_b)if not self._registeredEvents[da]then +self:listenEvent(da,true)end +if +not self._values.eventCallbacks[da]then self._values.eventCallbacks[da]={}end +table.insert(self._values.eventCallbacks[da],_b)return self end;function ca:registerState(da,_b,ab) +self._registeredStates[da]={condition=_b,priority=ab or 0}return self end +function ca:setState(da,_b) +local ab=self.get("states")if not _b and self._registeredStates[da]then +_b=self._registeredStates[da].priority end;ab[da]=_b or 0 +self.set("states",ab)return self end +function ca:unsetState(da)local _b=self.get("states")if _b[da]~=nil then _b[da]=nil +self.set("states",_b)end;return self end +function ca:hasState(da)local _b=self.get("states")return _b[da]~=nil end +function ca:getCurrentState()local da=self.get("states")local _b=-math.huge;local ab=nil;for bb,cb in +pairs(da)do if cb>_b then _b=cb;ab=bb end end;return ab end +function ca:getActiveStates()local da=self.get("states")local _b={}for ab,bb in pairs(da)do +table.insert(_b,{name=ab,priority=bb})end +table.sort(_b,function(ab,bb) +return ab.priority>bb.priority end)return _b end +function ca:updateConditionalStates() +for da,_b in pairs(self._registeredStates)do +if _b.condition then if _b.condition(self)then +self:setState(da,_b.priority)else self:unsetState(da)end end end;return self end;function ca:unregisterState(da)self._stateRegistry[da]=nil +self:unsetState(da)return self end +function ca:fireEvent(da,...) +if +self.get("eventCallbacks")[da]then local _b;for ab,bb in ipairs(self.get("eventCallbacks")[da])do +_b=bb(self,...)end;return _b end;return self end +function ca:dispatchEvent(da,...) +if self.get("enabled")==false then return false end;if self[da]then return self[da](self,...)end;return +self:handleEvent(da,...)end;function ca:handleEvent(da,...)return false end;function ca:onChange(da,_b) +self:observe(da,_b)return self end +function ca:getBaseFrame()if self.parent then return +self.parent:getBaseFrame()end;return self end;function ca:destroy() +if(self.parent)then self.parent:removeChild(self)end;self._destroyed=true;self:removeAllObservers() +self:setFocused(false)end;function ca:updateRender() +if +(self.parent)then self.parent:updateRender()else self._renderUpdate=true end;return self end;return ca end +project["elements/ContextMenu.lua"] = function(...) local aa=require("elementManager") +local ba=require("elements/VisualElement")local ca=aa.getElement("Container") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"items",{default={},type="table",canTriggerRender=true}) +_b.defineProperty(_b,"isOpen",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"openSubmenu",{default=nil,type="table",allowNil=true}) +_b.defineProperty(_b,"itemHeight",{default=1,type="number",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +function _b.new() +local ab=setmetatable({},_b):__init()ab.class=_b;ab.set("width",10)ab.set("height",10) +ab.set("visible",false)return ab end;function _b:init(ab,bb)ca.init(self,ab,bb) +self.set("type","ContextMenu")end +function _b:setItems(ab) +self.set("items",ab or{})self:calculateSize()return self end +function _b:calculateSize()local ab=self.get("items") +local bb=self.get("itemHeight") +if#ab==0 then self.set("width",10)self.set("height",2)return end;local cb=8 +for _c,ac in ipairs(ab)do if ac.label then local bc=#ac.label;local cc=bc+3 +if ac.submenu then cc=cc+1 end;if cc>cb then cb=cc end end end;local db=#ab*bb;self.set("width",cb) +self.set("height",db)end;function _b:open()self.set("isOpen",true) +self.set("visible",true)self:updateRender()self:dispatchEvent("opened") +return self end +function _b:close() +self.set("isOpen",false)self.set("visible",false) +local ab=self.get("openSubmenu")if ab and ab.menu then ab.menu:close()end +self.set("openSubmenu",nil)self:updateRender()self:dispatchEvent("closed") +return self end;function _b:closeAll()local ab=self;while ab.parentMenu do ab=ab.parentMenu end +ab:close()return self end +function _b:getItemAt(ab) +local bb=self.get("items")local cb=self.get("itemHeight") +local db=math.floor((ab-1)/cb)+1;if db>=1 and db<=#bb then return db,bb[db]end;return nil,nil end +function _b:createSubmenu(ab,bb)local cb=self.parent:addContextMenu() +cb:setItems(ab) +cb.set("background",self.get("background")) +cb.set("foreground",self.get("foreground"))cb.parentMenu=self;local db=self.get("x")local _c=self.get("y") +local ac=self.get("width")local bc=self.get("itemHeight")local cc=bb._index or 1 +cb.set("x",db+ac)cb.set("y",_c+ (cc-1)*bc) +cb.set("z",self.get("z")+1)return cb end +function _b:mouse_click(ab,bb,cb)if not ba.mouse_click(self,ab,bb,cb)then self:close() +return false end +local db,_c=ba.getRelativePosition(self,bb,cb)local ac,bc=self:getItemAt(_c) +if bc then if bc.disabled then return true end +if bc.submenu then +local cc=self.get("openSubmenu") +if cc and cc.index==ac then cc.menu:close() +self.set("openSubmenu",nil)else if cc and cc.menu then cc.menu:close()end;bc._index=ac +local dc=self:createSubmenu(bc.submenu,bc)dc:open() +self.set("openSubmenu",{index=ac,menu=dc})end;return true end;if bc.onClick then bc.onClick(bc)end;self:closeAll() +return true end;return true end +function _b:render()local ab=self.get("items")local bb=self.get("width") +local cb=self.get("height")local db=self.get("itemHeight") +local _c=self.get("background")local ac=self.get("foreground") +for bc,cc in ipairs(ab)do local dc=(bc-1)*db+1;local _d= +cc.background or _c;local ad=cc.foreground or ac;local bd=da[_d] +local cd=da[ad]local dd=string.rep(" ",bb)local __a=string.rep(bd,bb) +local a_a=string.rep(cd,bb)self:blit(1,dc,dd,a_a,__a)local b_a=cc.label or""if#b_a>bb-3 then b_a=b_a:sub(1, +bb-3)end +self:textFg(2,dc,b_a,ad)if cc.submenu then self:textFg(bb-1,dc,">",ad)end end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(bc)end end +for bc,cc in ipairs(self.get("visibleChildren")or{})do if cc==self then +error("CIRCULAR REFERENCE DETECTED!")return end;cc:render()cc:postRender()end end;return _b end +project["elements/List.lua"] = function(...) local _a=require("elements/Collection") +local aa=require("libraries/colorHex")local ba=setmetatable({},_a)ba.__index=ba +ba.defineProperty(ba,"offset",{default=0,type="number",canTriggerRender=true,setter=function(da,_b) +local ab=math.max(0,# +da.get("items")-da.get("height"))return math.min(ab,math.max(0,_b))end}) +ba.defineProperty(ba,"emptyText",{default="No items",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackground",{default="\127",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true})ba.defineEvent(ba,"mouse_click") +ba.defineEvent(ba,"mouse_up")ba.defineEvent(ba,"mouse_drag") +ba.defineEvent(ba,"mouse_scroll")ba.defineEvent(ba,"key") +local ca={text={type="string",default="Entry"},bg={type="number",default=nil},fg={type="number",default= +nil},selectedBg={type="number",default=nil},selectedFg={type="number",default=nil},callback={type="function",default=nil}} +function ba.new()local da=setmetatable({},ba):__init() +da.class=ba;da.set("width",16)da.set("height",8)da.set("z",5) +da.set("background",colors.gray)return da end +function ba:init(da,_b)_a.init(self,da,_b)self._entrySchema=ca +self.set("type","List") +self:observe("items",function() +local ab=math.max(0,#self.get("items")-self.get("height")) +if self.get("offset")>ab then self.set("offset",ab)end end) +self:observe("height",function() +local ab=math.max(0,#self.get("items")-self.get("height")) +if self.get("offset")>ab then self.set("offset",ab)end end)return self end +function ba:mouse_click(da,_b,ab) +if _a.mouse_click(self,da,_b,ab)then +local bb,cb=self:getRelativePosition(_b,ab)local db=self.get("width")local _c=self.get("items") +local ac=self.get("height")local bc=self.get("showScrollBar") +if bc and#_c>ac and bb==db then local cc= +#_c-ac +local dc=math.max(1,math.floor((ac/#_c)*ac)) +local _d=cc>0 and(self.get("offset")/cc*100)or 0 +local ad=math.floor((_d/100)* (ac-dc))+1 +if cb>=ad and cb +ab+_b then self.set("offset",da-_b)end;return self end +function ba:key(da) +if _a.key(self,da)and self.get("selectable")then +local _b=self.get("items")local ab=self:getSelectedIndex() +if da==keys.up then +self:selectPrevious()if ab and ab>1 then self:scrollToItem(ab-1)end +return true elseif da==keys.down then self:selectNext()if ab and ab<#_b then +self:scrollToItem(ab+1)end;return true elseif da==keys.home then +self:clearItemSelection()self:selectItem(1)self:scrollToTop()return true elseif +da==keys["end"]then self:clearItemSelection()self:selectItem(#_b) +self:scrollToBottom()return true elseif da==keys.pageUp then local bb=self.get("height") +local cb=math.max(1,(ab or 1)-bb)self:clearItemSelection()self:selectItem(cb) +self:scrollToItem(cb)return true elseif da==keys.pageDown then local bb=self.get("height") +local cb=math.min(#_b,(ab or 1)+bb)self:clearItemSelection()self:selectItem(cb) +self:scrollToItem(cb)return true end end;return false end +function ba:render(da)da=da or 0;_a.render(self)local _b=self.get("items") +local ab=self.get("height")local bb=self.get("offset")local cb=self.get("width") +local db=self.getResolved("background")local _c=self.getResolved("foreground") +local ac=self.get("showScrollBar")local bc=ac and#_b>ab;local cc=bc and cb-1 or cb +if#_b==0 then +local dc=self.get("emptyText")local _d=math.floor(ab/2)+da;local ad=math.max(1, +math.floor((cb-#dc)/2)+1)for i=1,ab do +self:textBg(1,i,string.rep(" ",cb),db)end;if _d>=1 and _d<=ab then +self:textFg(ad,_d+da,dc,colors.gray)end;return end +for i=1,ab do local dc=i+bb;local _d=_b[dc] +if _d then +if _d.separator then +local ad=( +(_d.text or"-")~=""and _d.text or"-"):sub(1,1)local bd=string.rep(ad,cc)local cd=_d.fg or _c;local dd=_d.bg or db;self:textBg(1, +i+da,string.rep(" ",cc),dd)self:textFg(1,i+ +da,bd,cd)else local ad=_d.text or""local bd=_d.selected +local cd= +bd and( +_d.selectedBg or self.getResolved("selectedBackground"))or(_d.bg or db) +local dd=bd and +(_d.selectedFg or self.getResolved("selectedForeground"))or(_d.fg or _c)local __a=ad +if#__a>cc then __a=__a:sub(1,cc-3).."..."else __a=__a..string.rep(" ",cc- +#__a)end;self:textBg(1,i+da,string.rep(" ",cc),cd)self:textFg(1, +i+da,__a,dd)end else self:textBg(1,i+da,string.rep(" ",cc),db)end end +if bc then +local dc=math.max(1,math.floor((ab/#_b)*ab))local _d=#_b-ab;local ad=_d>0 and(bb/_d*100)or 0;local bd=math.floor((ad/ +100)* (ab-dc))+1 +local cd=self.getResolved("scrollBarSymbol")local dd=self.getResolved("scrollBarBackground") +local __a=self.getResolved("scrollBarColor")local a_a=self.getResolved("scrollBarBackgroundColor") +for i=1,ab do self:blit(cb, +i+da,dd,aa[_c],aa[a_a])end;for i=bd,math.min(ab,bd+dc-1)do +self:blit(cb,i+da,cd,aa[__a],aa[a_a])end end end;return ba end +project["elements/Collection.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/collectionentry")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"items",{default={},type="table",canTriggerRender=true}) +aa.defineProperty(aa,"selectable",{default=true,type="boolean"}) +aa.defineProperty(aa,"multiSelection",{default=false,type="boolean"}) +aa.defineProperty(aa,"selectedBackground",{default=colors.blue,type="color",canTriggerRender=true}) +aa.defineProperty(aa,"selectedForeground",{default=colors.white,type="color",canTriggerRender=true})function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;return ba end +function aa:init(ba,ca) +d.init(self,ba,ca)self._entrySchema={}self.set("type","Collection")return self end +function aa:addItem(ba)if type(ba)=="string"then ba={text=ba}end;if ba.selected==nil then +ba.selected=false end +local ca=_a.new(self,ba,self._entrySchema)table.insert(self.get("items"),ca) +self:updateRender()return ca end +function aa:removeItem(ba)local ca=self.get("items")if type(ba)=="number"then +table.remove(ca,ba)else +for da,_b in pairs(ca)do if _b==ba then table.remove(ca,da)break end end end +self:updateRender()return self end +function aa:clear()self.set("items",{})self:updateRender()return self end +function aa:getSelectedItems()local ba={}for ca,da in ipairs(self.get("items"))do +if type(da)=="table"and +da.selected then local _b=da;_b.index=ca;table.insert(ba,_b)end end;return ba end +function aa:getSelectedItem()local ba=self.get("items") +for ca,da in ipairs(ba)do if type(da)=="table"and +da.selected then return da end end;return nil end +function aa:selectItem(ba)local ca=self.get("items") +if type(ba)=="number"then +if ca[ba]and +type(ca[ba])=="table"then ca[ba].selected=true end else for da,_b in pairs(ca)do +if _b==ba then if type(_b)=="table"then _b.selected=true end;break end end end;self:updateRender()return self end +function aa:unselectItem(ba)local ca=self.get("items") +if type(ba)=="number"then +if ca[ba]and +type(ca[ba])=="table"then ca[ba].selected=false end else +for da,_b in pairs(ca)do if _b==ba then +if type(ca[da])=="table"then ca[da].selected=false end;break end end end;self:updateRender()return self end +function aa:clearItemSelection()local ba=self.get("items") +for ca,da in ipairs(ba)do da.selected=false end;self:updateRender()return self end +function aa:getSelectedIndex()local ba=self.get("items") +for ca,da in ipairs(ba)do if type(da)=="table"and +da.selected then return ca end end;return nil end +function aa:selectNext()local ba=self.get("items") +local ca=self:getSelectedIndex() +if not ca then if#ba>0 then self:selectItem(1)end elseif ca<#ba then +if not +self.get("multiSelection")then self:clearItemSelection()end;self:selectItem(ca+1)end;self:updateRender()return self end +function aa:selectPrevious()local ba=self.get("items") +local ca=self:getSelectedIndex() +if not ca then if#ba>0 then self:selectItem(#ba)end elseif ca>1 then +if not +self.get("multiSelection")then self:clearItemSelection()end;self:selectItem(ca-1)end;self:updateRender()return self end +function aa:onSelect(ba)self:registerCallback("select",ba)return self end;return aa end +project["elements/Accordion.lua"] = function(...) local aa=require("elementManager") +local ba=require("elements/VisualElement")local ca=aa.getElement("Container") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"panels",{default={},type="table"}) +_b.defineProperty(_b,"panelHeaderHeight",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"allowMultiple",{default=false,type="boolean"}) +_b.defineProperty(_b,"headerBackground",{default=colors.gray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"headerTextColor",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"expandedHeaderBackground",{default=colors.lightGray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"expandedHeaderTextColor",{default=colors.black,type="color",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +_b.defineEvent(_b,"mouse_up")function _b.new()local ab=setmetatable({},_b):__init() +ab.class=_b;ab.set("width",20)ab.set("height",10)ab.set("z",10)return +ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","Accordion")end +function _b:newPanel(ab,bb)local cb=self.get("panels")or{}local db=#cb+1 +local _c=self:addContainer()_c.set("x",1)_c.set("y",1) +_c.set("width",self.get("width"))_c.set("height",self.get("height")) +_c.set("visible",bb or false)_c.set("ignoreOffset",true) +table.insert(cb,{id=db,title=tostring(ab or("Panel "..db)),expanded= +bb or false,container=_c})self.set("panels",cb)self:updatePanelLayout()return _c end;_b.addPanel=_b.newPanel +function _b:updatePanelLayout() +local ab=self.get("panels")or{}local bb=self.get("panelHeaderHeight")or 1;local cb=1 +local db=self.get("width")local _c=self.get("height") +for dc,_d in ipairs(ab)do local ad=cb+bb +_d.container.set("x",1)_d.container.set("y",ad) +_d.container.set("width",db)_d.container.set("visible",_d.expanded) +_d.container.set("ignoreOffset",false)cb=cb+bb +if _d.expanded then local bd=0 +for dd,__a in +ipairs(_d.container._values.children or{})do +if not __a._destroyed then local a_a=__a.get("y")local b_a=__a.get("height")local c_a= +a_a+b_a-1;if c_a>bd then bd=c_a end end end;local cd=math.max(1,bd)_d.container.set("height",cd)cb= +cb+cd end end;local ac=cb-1;local bc=math.max(0,ac-_c) +local cc=self.get("offsetY")if cc>bc then self.set("offsetY",bc)end +self:updateRender()end +function _b:togglePanel(ab)local bb=self.get("panels")or{} +local cb=self.get("allowMultiple") +for db,_c in ipairs(bb)do +if _c.id==ab then _c.expanded=not _c.expanded +if not cb and _c.expanded then for ac,bc in +ipairs(bb)do if ac~=db then bc.expanded=false end end end;self:updatePanelLayout() +self:dispatchEvent("panelToggled",ab,_c.expanded)break end end;return self end +function _b:expandPanel(ab)local bb=self.get("panels")or{} +local cb=self.get("allowMultiple") +for db,_c in ipairs(bb)do +if _c.id==ab then +if not _c.expanded then _c.expanded=true +if not cb then for ac,bc in ipairs(bb)do if ac~=db then +bc.expanded=false end end end;self:updatePanelLayout() +self:dispatchEvent("panelToggled",ab,true)end;break end end;return self end +function _b:collapsePanel(ab)local bb=self.get("panels")or{} +for cb,db in ipairs(bb)do +if db.id==ab then if +db.expanded then db.expanded=false;self:updatePanelLayout() +self:dispatchEvent("panelToggled",ab,false)end;break end end;return self end +function _b:getPanel(ab)local bb=self.get("panels")or{}for cb,db in ipairs(bb)do if db.id==ab then return +db.container end end;return nil end +function _b:_getPanelMetrics()local ab=self.get("panels")or{}local bb= +self.get("panelHeaderHeight")or 1;local cb={}local db=1 +for _c,ac in ipairs(ab)do +table.insert(cb,{id=ac.id,title=ac.title,expanded=ac.expanded,headerY=db,headerHeight=bb})db=db+bb;if ac.expanded then +db=db+ac.container.get("height")end end;return{positions=cb,totalHeight=db-1}end +function _b:mouse_click(ab,bb,cb) +if not ba.mouse_click(self,ab,bb,cb)then return false end;local db,_c=ba.getRelativePosition(self,bb,cb) +local ac=self.get("offsetY")local bc=_c+ac;local cc=self:_getPanelMetrics() +for dc,_d in ipairs(cc.positions)do local ad= +_d.headerY+_d.headerHeight-1;if +bc>=_d.headerY and bc<=ad then self:togglePanel(_d.id) +self.set("focusedChild",nil)return true end end;return ca.mouse_click(self,ab,bb,cb)end +function _b:mouse_scroll(ab,bb,cb) +if ba.mouse_scroll(self,ab,bb,cb)then +local db=self:_getPanelMetrics()local _c=self.get("height")local ac=db.totalHeight +local bc=math.max(0,ac-_c) +if bc>0 then local cc=self.get("offsetY")local dc=cc+ab +dc=math.max(0,math.min(bc,dc))self.set("offsetY",dc)return true end;return ca.mouse_scroll(self,ab,bb,cb)end;return false end +function _b:render()ba.render(self)local ab=self.get("width") +local bb=self.get("offsetY")local cb=self:_getPanelMetrics() +for db,_c in ipairs(cb.positions)do +local ac=_c.expanded and +self.get("expandedHeaderBackground")or self.get("headerBackground") +local bc=_c.expanded and self.get("expandedHeaderTextColor")or +self.get("headerTextColor")local cc=_c.headerY-bb +if +cc>=1 and cc<=self.get("height")then +ba.multiBlit(self,1,cc,ab,_c.headerHeight," ",da[bc],da[ac])local dc=_c.expanded and"v"or">" +local _d=dc.." ".._c.title;ba.textFg(self,1,cc,_d,bc)end end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for db in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(db)end end +for db,_c in ipairs(self.get("visibleChildren")or{})do if _c==self then +error("CIRCULAR REFERENCE DETECTED!")return end;_c:render()_c:postRender()end end;return _b end +project["plugins/canvas.lua"] = function(...) local ba=require("libraries/colorHex") +local ca=require("errorManager")local da={}da.__index=da;local _b,ab=string.sub,string.rep +function da.new(cb) +local db=setmetatable({},da)db.commands={pre={},post={}}db.type="pre"db.element=cb;return db end +function da:clear()self.commands={pre={},post={}}return self end;function da:getValue(cb) +if type(cb)=="function"then return cb(self.element)end;return cb end +function da:setType(cb)if +cb=="pre"or cb=="post"then self.type=cb else +ca.error("Invalid type. Use 'pre' or 'post'.")end;return self end +function da:addCommand(cb) +local db=#self.commands[self.type]+1;self.commands[self.type][db]=cb;return db end +function da:setCommand(cb,db)self.commands[cb]=db;return self end;function da:removeCommand(cb) +table.remove(self.commands[self.type],cb)return self end +function da:text(cb,db,_c,ac,bc) +return +self:addCommand(function(cc) +local dc,_d=self:getValue(cb),self:getValue(db)local ad=self:getValue(_c)local bd=self:getValue(ac) +local cd=self:getValue(bc) +local dd=type(bd)=="number"and ba[bd]:rep(#_c)or bd +local __a=type(cd)=="number"and ba[cd]:rep(#_c)or cd;cc:drawText(dc,_d,ad) +if dd then cc:drawFg(dc,_d,dd)end;if __a then cc:drawBg(dc,_d,__a)end end)end;function da:bg(cb,db,_c)return +self:addCommand(function(ac)ac:drawBg(cb,db,_c)end)end +function da:fg(cb,db,_c)return self:addCommand(function(ac) +ac:drawFg(cb,db,_c)end)end +function da:rect(cb,db,_c,ac,bc,cc,dc) +return +self:addCommand(function(_d)local ad,bd=self:getValue(cb),self:getValue(db) +local cd,dd=self:getValue(_c),self:getValue(ac)local __a=self:getValue(bc)local a_a=self:getValue(cc) +local b_a=self:getValue(dc)if(type(a_a)=="number")then a_a=ba[a_a]end;if +(type(b_a)=="number")then b_a=ba[b_a]end +local c_a=b_a and _b(b_a:rep(cd),1,cd)local d_a=a_a and _b(a_a:rep(cd),1,cd)local _aa=__a and +_b(__a:rep(cd),1,cd) +for i=0,dd-1 do +if b_a then _d:drawBg(ad,bd+i,c_a)end;if a_a then _d:drawFg(ad,bd+i,d_a)end;if __a then +_d:drawText(ad,bd+i,_aa)end end end)end +function da:line(cb,db,_c,ac,bc,cc,dc) +local function _d(cd,dd,__a,a_a)local b_a={}local c_a=0;local d_a=math.abs(__a-cd) +local _aa=math.abs(a_a-dd)local aaa=(cd<__a)and 1 or-1 +local baa=(dd-_aa then caa=caa-_aa;cd=cd+aaa end;if daa0 do +aaa=aaa-1;daa=daa-2 *c_a;if baa>0 then baa=baa+c_a-daa else _aa=_aa+1 +caa=caa+2 *d_a;baa=baa+c_a-daa+caa end +_ba(_aa,aaa)end +return a_a end;local ad=_d(cb,db,_c,ac) +return +self:addCommand(function(bd)local cd=self:getValue(bc) +local dd=self:getValue(cc)local __a=self:getValue(dc) +local a_a=type(dd)=="number"and ba[dd]or dd +local b_a=type(__a)=="number"and ba[__a]or __a +for c_a,d_a in pairs(ad)do local _aa=math.floor(d_a.x)local aaa=math.floor(d_a.y)if cd then +bd:drawText(_aa,aaa,cd)end;if a_a then bd:drawFg(_aa,aaa,a_a)end;if b_a then +bd:drawBg(_aa,aaa,b_a)end end end)end;local bb={hooks={}} +function bb.setup(cb) +cb.defineProperty(cb,"canvas",{default=nil,type="table",getter=function(db)if not db._values.canvas then +db._values.canvas=da.new(db)end;return db._values.canvas end})end;function bb.hooks.render(cb)local db=cb.get("canvas") +if +db and#db.commands.pre>0 then for _c,ac in pairs(db.commands.pre)do ac(cb)end end end +function bb.hooks.postRender(cb) +local db=cb.get("canvas")if db and#db.commands.post>0 then for _c,ac in pairs(db.commands.post)do +ac(cb)end end end;return{VisualElement=bb,API=da} end +project["plugins/theme.lua"] = function(...) local ab=require("errorManager") +local bb={default={background=colors.lightGray,foreground=colors.black},BaseFrame={background=colors.white,foreground=colors.black,Frame={background=colors.black,names={basaltDebugLogClose={background=colors.blue,foreground=colors.white}}},Button={background=colors.cyan,foreground=colors.black},names={basaltDebugLog={background=colors.red,foreground=colors.white}}}}local cb={default=bb}local db="default" +local _c={hooks={postInit={pre=function(ad)if ad._postInitialized then return ad end +ad:applyTheme()end}}} +function _c.____getElementPath(ad,bd)if bd then table.insert(bd,1,ad._values.type)else +bd={ad._values.type}end;local cd=ad.parent;if cd then return +cd.____getElementPath(cd,bd)else return bd end end +local function ac(ad,bd)local cd=ad +for i=1,#bd do local dd=false;local __a=bd[i]for a_a,b_a in ipairs(__a)do +if cd[b_a]then cd=cd[b_a]dd=true;break end end;if not dd then return nil end end;return cd end +local function bc(ad,bd)local cd={} +if ad.default then for dd,__a in pairs(ad.default)do +if type(__a)~="table"then cd[dd]=__a end end;if ad.default[bd]then +for dd,__a in +pairs(ad.default[bd])do if type(__a)~="table"then cd[dd]=__a end end end end;return cd end +local function cc(ad,bd,cd,dd,__a) +if +bd.default and bd.default.names and bd.default.names[dd]then for a_a,b_a in pairs(bd.default.names[dd])do +if type(b_a)~="table"then ad[a_a]=b_a end end end +if + +bd.default and bd.default[cd]and bd.default[cd].names and bd.default[cd].names[dd]then +for a_a,b_a in pairs(bd.default[cd].names[dd])do if +type(b_a)~="table"then ad[a_a]=b_a end end end;if __a and __a.names and __a.names[dd]then +for a_a,b_a in pairs(__a.names[dd])do if +type(b_a)~="table"then ad[a_a]=b_a end end end end +local function dc(ad,bd,cd,dd)local __a={}local a_a=ac(ad,bd) +if a_a then for b_a,c_a in pairs(a_a)do +if type(c_a)~="table"then __a[b_a]=c_a end end end;if next(__a)==nil then __a=bc(ad,cd)end +cc(__a,ad,cd,dd,a_a)return __a end +function _c:applyTheme(ad)local bd=self:getTheme() +if(bd~=nil)then +for cd,dd in pairs(bd)do +local __a=self._properties[cd] +if(__a)then +if( (__a.type)=="color")then if(type(dd)=="string")then +if(colors[dd])then dd=colors[dd]end end end;self.set(cd,dd)end end end +if(ad~=false)then if(self:isType("Container"))then local cd=self.get("children") +for dd,__a in +ipairs(cd)do if(__a and __a.applyTheme)then __a:applyTheme()end end end end;return self end +function _c:getTheme()local ad=self:____getElementPath() +local bd=self.get("type")local cd=self.get("name")return dc(cb[db],ad,bd,cd)end;local _d={}function _d.setTheme(ad)cb.default=ad end +function _d.getTheme()return cb.default end +function _d.loadTheme(ad)local bd=fs.open(ad,"r") +if bd then local cd=bd.readAll()bd.close() +cb.default=textutils.unserializeJSON(cd)if not cb.default then +ab.error("Failed to load theme from "..ad)end else +ab.error("Could not open theme file: "..ad)end end;return{BaseElement=_c,API=_d} end +project["plugins/reactive.lua"] = function(...) local cb=require("errorManager") +local db=require("propertySystem")local _c={colors=true,math=true,clamp=true,round=true} +local ac={clamp=function(__a,a_a,b_a)return +math.min(math.max(__a,a_a),b_a)end,round=function(__a) +return math.floor(__a+0.5)end,floor=math.floor,ceil=math.ceil,abs=math.abs} +local function bc(__a)return +{parent=__a:find("parent%."),self=__a:find("self%."),other=__a:find("[^(parent)][^(self)]%.")}end +local function cc(__a,a_a,b_a)local c_a=bc(__a) +if c_a.parent and not a_a.parent then +cb.header="Reactive evaluation error" +cb.error("Expression uses parent but no parent available")return function()return nil end end;__a=__a:gsub("^{(.+)}$","%1") +__a=__a:gsub("([%w_]+)%$([%w_]+)",function(baa,caa) +if baa=="self"then return +string.format('__getState("%s")',caa)elseif baa=="parent"then return +string.format('__getParentState("%s")',caa)else return +string.format('__getElementState("%s", "%s")',baa,caa)end end) +__a=__a:gsub("([%w_]+)%.([%w_]+)",function(baa,caa)if _c[baa]then return baa.."."..caa end;if +tonumber(baa)then return baa.."."..caa end;return +string.format('__getProperty("%s", "%s")',baa,caa)end) +local d_a=setmetatable({colors=colors,math=math,tostring=tostring,tonumber=tonumber,__getState=function(baa)return a_a:getState(baa)end,__getParentState=function(baa)return +a_a.parent:getState(baa)end,__getElementState=function(baa,caa)if tonumber(baa)then return nil end +local daa=a_a:getBaseFrame():getChild(baa)if not daa then cb.header="Reactive evaluation error" +cb.error("Could not find element: "..baa)return nil end;return +daa:getState(caa).value end,__getProperty=function(baa,caa)if +tonumber(baa)then return nil end +if baa=="self"then if a_a._properties[caa]then +return a_a.get(caa)end;if +a_a._registeredStates and a_a._registeredStates[caa]then return a_a:hasState(caa)end +local daa=a_a.get("states")if daa and daa[caa]~=nil then return true end +cb.header="Reactive evaluation error" +cb.error("Property or state '"..caa.. +"' not found in element '"..a_a:getType().."'")return nil elseif baa=="parent"then if a_a.parent._properties[caa]then return +a_a.parent.get(caa)end;if a_a.parent._registeredStates and +a_a.parent._registeredStates[caa]then +return a_a.parent:hasState(caa)end +local daa=a_a.parent.get("states")if daa and daa[caa]~=nil then return true end +cb.header="Reactive evaluation error" +cb.error("Property or state '"..caa.."' not found in parent element")return nil else local daa=a_a.parent:getChild(baa)if not daa then +cb.header="Reactive evaluation error" +cb.error("Could not find element: "..baa)return nil end;if +daa._properties[caa]then return daa.get(caa)end +if daa._registeredStates and +daa._registeredStates[caa]then return daa:hasState(caa)end;local _ba=daa.get("states") +if _ba and _ba[caa]~=nil then return true end;cb.header="Reactive evaluation error" +cb.error("Property or state '"..caa.. +"' not found in element '"..baa.."'")return nil end end},{__index=ac})if(a_a._properties[b_a].type=="string")then +__a="tostring("..__a..")"elseif(a_a._properties[b_a].type=="number")then +__a="tonumber("..__a..")"end;local _aa,aaa=load( +"return "..__a,"reactive","t",d_a) +if not _aa then +cb.header="Reactive evaluation error"cb.error("Invalid expression: "..aaa)return +function()return nil end end;return _aa end +local function dc(__a,a_a) +for b_a in __a:gmatch("([%w_]+)%.")do +if not _c[b_a]then +if b_a=="self"then elseif b_a=="parent"then +if not a_a.parent then +cb.header="Reactive evaluation error"cb.error("No parent element available")return false end else +if(tonumber(b_a)==nil)then local c_a=a_a.parent:getChild(b_a)if not c_a then +cb.header="Reactive evaluation error" +cb.error("Referenced element not found: "..b_a)return false end end end end end;return true end;local _d=setmetatable({},{__mode="k"}) +local ad=setmetatable({},{__mode="k",__index=function(__a,a_a)__a[a_a]={}return +__a[a_a]end}) +local bd=setmetatable({},{__mode="k",__index=function(__a,a_a)__a[a_a]={}return __a[a_a]end}) +local function cd(__a,a_a,b_a)local c_a=bc(a_a) +if ad[__a][b_a]then for _aa,aaa in ipairs(ad[__a][b_a])do +aaa.target:removeObserver(aaa.property,aaa.callback)end end;local d_a={} +for _aa,aaa in a_a:gmatch("([%w_]+)%.([%w_]+)")do +if not _c[_aa]then local baa +if +_aa=="self"and c_a.self then baa=__a elseif _aa=="parent"and c_a.parent then baa=__a.parent elseif c_a.other then +baa=__a:getBaseFrame():getChild(_aa)end +if baa then local caa=false +if baa._properties[aaa]then caa=false elseif baa._registeredStates and +baa._registeredStates[aaa]then caa=true else local _ba=baa.get("states")if _ba and +_ba[aaa]~=nil then caa=true end end +local daa={target=baa,property=caa and"states"or aaa,callback=function()local _ba=bd[__a][b_a]local aba=__a.get(b_a) +if +_ba~=aba then bd[__a][b_a]=aba +if +__a._observers and __a._observers[b_a]then for bba,cba in ipairs(__a._observers[b_a])do cba()end end;__a:updateRender()end end}baa:observe(daa.property,daa.callback) +table.insert(d_a,daa)end end end;ad[__a][b_a]=d_a end +db.addSetterHook(function(__a,a_a,b_a,c_a) +if type(b_a)=="string"and b_a:match("^{.+}$")then +local d_a=b_a:gsub("^{(.+)}$","%1")local _aa=bc(d_a) +if _aa.parent and not __a.parent then return c_a.default end;if not dc(d_a,__a)then return c_a.default end +cd(__a,d_a,a_a)if not _d[__a]then _d[__a]={}end;if not _d[__a][b_a]then +local aaa=cc(b_a,__a,a_a)_d[__a][b_a]=aaa end +return +function(aaa) +if __a._destroyed or(_aa.parent and not +__a.parent)then return c_a.default end;local baa,caa=pcall(_d[__a][b_a]) +if not baa then +if caa and +caa:match("attempt to index.-nil value")then return c_a.default end;cb.header="Reactive evaluation error"if type(caa)=="string"then cb.error( +"Error evaluating expression: "..caa)else +cb.error("Error evaluating expression")end +return c_a.default end;bd[__a][a_a]=caa;return caa end end end)local dd={} +dd.hooks={destroy=function(__a) +if ad[__a]then +for a_a,b_a in pairs(ad[__a])do for c_a,d_a in ipairs(b_a)do +d_a.target:removeObserver(d_a.property,d_a.callback)end end;ad[__a]=nil;bd[__a]=nil;_d[__a]=nil end end}return{BaseElement=dd} end +project["plugins/xml.lua"] = function(...) local bb=require("errorManager")local cb=require("log") +local db={new=function(cd) +return +{tag=cd,value=nil,attributes={},children={},addChild=function(dd,__a) +table.insert(dd.children,__a)end,addAttribute=function(dd,__a,a_a)dd.attributes[__a]=a_a end}end} +local _c=function(cd,dd) +local __a,a_a=string.gsub(dd,"([%w:]+)=([\"'])(.-)%2",function(d_a,_aa,aaa) +cd:addAttribute(d_a,"\""..aaa.."\"")end) +local b_a,c_a=string.gsub(dd,"([%w:]+)={(.-)}",function(d_a,_aa)cd:addAttribute(d_a,_aa)end)end;local ac={} +ac={_customTagHandlers={},registerTagHandler=function(cd,dd)ac._customTagHandlers[cd]=dd +cb.info( +"XMLParser: Registered custom tag handler for '"..cd.."'")end,unregisterTagHandler=function(cd)ac._customTagHandlers[cd]= +nil +cb.info("XMLParser: Unregistered custom tag handler for '"..cd.."'")end,getTagHandler=function(cd)return +ac._customTagHandlers[cd]end,parseText=function(cd)local dd={}local __a=db.new() +table.insert(dd,__a)local a_a,b_a,c_a,d_a,_aa;local aaa,baa=1,1 +while true do +a_a,baa,b_a,c_a,d_a,_aa=string.find(cd,"<(%/?)([%w_:]+)(.-)(%/?)>",aaa)if not a_a then break end;local caa=string.sub(cd,aaa,a_a-1)if not +string.find(caa,"^%s*$")then local daa=(__a.value or"")..caa +dd[#dd].value=daa end +if _aa=="/"then local daa=db.new(c_a) +_c(daa,d_a)__a:addChild(daa)elseif b_a==""then local daa=db.new(c_a)_c(daa,d_a) +table.insert(dd,daa)__a=daa else local daa=table.remove(dd)__a=dd[#dd] +if#dd<1 then bb.error( +"XMLParser: nothing to close with "..c_a)end;if daa.tag~=c_a then +bb.error("XMLParser: trying to close "..daa.tag.." with "..c_a)end;__a:addChild(daa)end;aaa=baa+1 end;if#dd>1 then +error("XMLParser: unclosed "..dd[#dd].tag)end;return __a.children end} +local function bc(cd)local dd={}local __a=1 +while true do local a_a,b_a,c_a=cd:find("%${([^}]+)}",__a) +if not a_a then break end +table.insert(dd,{start=a_a,ending=b_a,expression=c_a,raw=cd:sub(a_a,b_a)})__a=b_a+1 end;return dd end +local function cc(cd,dd)if not cd then return cd end;if +cd:sub(1,1)=="\""and cd:sub(-1)=="\""then cd=cd:sub(2,-2)end;local __a=bc(cd) +for a_a,b_a in ipairs(__a)do +local c_a=b_a.expression;local d_a=b_a.start-1;local _aa=b_a.ending+1;if dd[c_a]then cd=cd:sub(1,d_a).. +tostring(dd[c_a])..cd:sub(_aa)else +bb.error( +"XMLParser: variable '"..c_a.."' not found in scope")end end +if cd:match("^%s*%s*$")then +local a_a=cd:match("")local b_a=_ENV;for baa,caa in pairs(dd)do b_a[baa]=caa end +local c_a,d_a=load("return "..a_a,nil,"bt",b_a)if not c_a then +bb.error("XMLParser: CDATA syntax error: "..tostring(d_a))end;local _aa,aaa=pcall(c_a)if not _aa then +bb.error( +"XMLParser: CDATA execution error: "..tostring(aaa))end;return aaa end +if cd=="true"then return true elseif cd=="false"then return false elseif colors[cd]then return colors[cd]elseif tonumber(cd)then return +tonumber(cd)else return cd end end +local function dc(cd,dd)local __a={} +for a_a,b_a in pairs(cd.children)do +if b_a.tag=="item"or b_a.tag=="entry"then +local c_a={} +for d_a,_aa in pairs(b_a.attributes)do c_a[d_a]=cc(_aa,dd)end;for d_a,_aa in pairs(b_a.children)do +if _aa.value then c_a[_aa.tag]=cc(_aa.value,dd)elseif# +_aa.children>0 then c_a[_aa.tag]=dc(_aa)end end +table.insert(__a,c_a)else if b_a.value then __a[b_a.tag]=cc(b_a.value,dd)elseif#b_a.children>0 then +__a[b_a.tag]=dc(b_a)end end end;return __a end +local function _d(cd,dd,__a,a_a)local b_a,c_a=dd:match("^(.+)State:(.+)$") +if b_a and c_a then +c_a=c_a:gsub("^\"",""):gsub("\"$","") +local d_a=b_a:sub(1,1):upper()..b_a:sub(2)local _aa="set"..d_a.."State" +if cd[_aa]then +cd[_aa](cd,c_a,cc(__a,a_a))return true else +cb.warn("XMLParser: State method '".._aa.. +"' not found for element '"..cd:getType().."'")return true end end;return false end;local ad={}function ad.setup(cd) +cd.defineProperty(cd,"customXML",{default={attributes={},children={}},type="table"})end +function ad:fromXML(cd,dd) +if(cd.attributes)then +for __a,a_a in +pairs(cd.attributes)do +if not _d(self,__a,a_a,dd)then +if(self._properties[__a])then +self.set(__a,cc(a_a,dd))elseif self[__a]then +if(__a:sub(1,2)=="on")then local b_a=a_a:gsub("\"","") +if(dd[b_a])then if( +type(dd[b_a])~="function")then +bb.error("XMLParser: variable '".. +b_a.."' is not a function for element '"..self:getType().. +"' "..__a)end +self[__a](self,dd[b_a])else +bb.error("XMLParser: variable '"..b_a.."' not found in scope")end else +bb.error("XMLParser: property '"..__a.. +"' not found in element '"..self:getType().."'")end else local b_a=self.get("customXML") +b_a.attributes[__a]=cc(a_a,dd)end end end end +if(cd.children)then +for __a,a_a in pairs(cd.children)do +if a_a.tag=="state"then +local b_a=a_a.attributes and a_a.attributes.name;if not b_a then +bb.error("XMLParser: tag requires 'name' attribute")end +b_a=b_a:gsub("^\"",""):gsub("\"$","") +if a_a.children then +for c_a,d_a in ipairs(a_a.children)do local _aa=d_a.tag;local aaa +if +d_a.attributes and d_a.attributes.value then aaa=cc(d_a.attributes.value,dd)elseif d_a.value then +aaa=cc(d_a.value,dd)else +cb.warn("XMLParser: State property '".._aa.."' has no value")aaa=nil end +if aaa~=nil then +local baa=_aa:sub(1,1):upper().._aa:sub(2)local caa="set"..baa.."State"if self[caa]then +self[caa](self,b_a,aaa)else +cb.warn("XMLParser: State method '"..caa.. +"' not found for element '"..self:getType().."'")end end end end elseif(self._properties[a_a.tag])then if +(self._properties[a_a.tag].type=="table")then self.set(a_a.tag,dc(a_a,dd))else +self.set(a_a.tag,cc(a_a.value,dd))end else local b_a={} +if(a_a.children)then +for c_a,d_a in +pairs(a_a.children)do +if(d_a.tag=="param")then +table.insert(b_a,cc(d_a.value,dd))elseif(d_a.tag=="table")then table.insert(b_a,dc(d_a,dd))end end end +if(self[a_a.tag])then if(#b_a>0)then +self[a_a.tag](self,table.unpack(b_a))elseif(a_a.value)then self[a_a.tag](self,cc(a_a.value,dd))else +self[a_a.tag](self)end else +local c_a=self.get("customXML")a_a.value=cc(a_a.value,dd)c_a.children[a_a.tag]=a_a end end end end;return self end;local bd={} +function bd:loadXML(cd,dd)dd=dd or{}local __a=ac.parseText(cd) +self:fromXML(__a,dd) +if(__a)then +for a_a,b_a in ipairs(__a)do +local c_a=b_a.tag:sub(1,1):upper()..b_a.tag:sub(2)if self["add"..c_a]then local d_a=self["add"..c_a](self) +d_a:fromXML(b_a,dd)end end end;return self end +function bd:fromXML(cd,dd)ad.fromXML(self,cd,dd) +if(cd.children)then +for __a,a_a in ipairs(cd.children)do local b_a= +a_a.tag:sub(1,1):upper()..a_a.tag:sub(2) +local c_a=ac.getTagHandler(a_a.tag) +if c_a then local d_a=c_a(a_a,self,dd)elseif self["add"..b_a]then +local d_a=self["add"..b_a](self)d_a:fromXML(a_a,dd)else +cb.warn("XMLParser: Unknown tag '".. +a_a.tag.."' - no handler or element found")end end end;return self end;return{API=ac,Container=bd,BaseElement=ad} end +project["plugins/debug.lua"] = function(...) local _b=require("log")local ab=require("libraries/colorHex") +local bb=10;local cb=false;local db={ERROR=1,WARN=2,INFO=3,DEBUG=4} +local function _c(dc) +local _d={renderCount=0,eventCount={},lastRender=os.epoch("utc"),properties={},children={}} +return +{trackProperty=function(ad,bd)_d.properties[ad]=bd end,trackRender=function() +_d.renderCount=_d.renderCount+1;_d.lastRender=os.epoch("utc")end,trackEvent=function(ad)_d.eventCount[ad]=( +_d.eventCount[ad]or 0)+1 end,dump=function()return +{type=dc.get("type"),id=dc.get("id"),stats=_d}end}end;local ac={} +function ac.debug(dc,_d)dc._debugger=_c(dc)dc._debugLevel=_d or db.INFO;return dc end;function ac.dumpDebug(dc)if not dc._debugger then return end +return dc._debugger.dump()end;local bc={} +function bc.openConsole(dc) +if +not dc._debugFrame then local _d=dc.get("width")local ad=dc.get("height") +dc._debugFrame=dc:addFrame("basaltDebugLog"):setWidth(_d):setHeight(ad):listenEvent("mouse_scroll",true) +dc._debugFrame:addButton("basaltDebugLogClose"):setWidth(9):setHeight(1):setX( +_d-8):setY(ad):setText("Close"):onClick(function() +dc:closeConsole()end)dc._debugFrame._scrollOffset=0 +dc._debugFrame._processedLogs={} +local function bd(b_a,c_a)local d_a={}while#b_a>0 do local _aa=b_a:sub(1,c_a)table.insert(d_a,_aa)b_a=b_a:sub( +c_a+1)end;return d_a end +local function cd()local b_a={}local c_a=dc._debugFrame.get("width") +for d_a,_aa in +ipairs(_b._logs)do local aaa=bd(_aa.message,c_a)for baa,caa in ipairs(aaa)do +table.insert(b_a,{text=caa,level=_aa.level})end end;return b_a end;local dd=#cd()-dc.get("height")dc._scrollOffset=dd +local __a=dc._debugFrame.render +dc._debugFrame.render=function(b_a)__a(b_a)b_a._processedLogs=cd() +local c_a=b_a.get("height")-2;local d_a=#b_a._processedLogs;local _aa=math.max(0,d_a-c_a) +b_a._scrollOffset=math.min(b_a._scrollOffset,_aa) +for i=1,c_a-2 do local aaa=i+b_a._scrollOffset +local baa=b_a._processedLogs[aaa] +if baa then +local caa= + +baa.level==_b.LEVEL.ERROR and colors.red or baa.level== +_b.LEVEL.WARN and colors.yellow or baa.level==_b.LEVEL.DEBUG and colors.lightGray or colors.white;b_a:textFg(2,i,baa.text,caa)end end end;local a_a=dc._debugFrame.dispatchEvent +dc._debugFrame.dispatchEvent=function(b_a,c_a,d_a,...) +if +(c_a=="mouse_scroll")then +b_a._scrollOffset=math.max(0,b_a._scrollOffset+d_a)b_a:updateRender()return true else return a_a(b_a,c_a,d_a,...)end end end +dc._debugFrame.set("width",dc.get("width")) +dc._debugFrame.set("height",dc.get("height"))dc._debugFrame.set("visible",true)return dc end +function bc.closeConsole(dc)if dc._debugFrame then +dc._debugFrame.set("visible",false)end;return dc end;function bc.toggleConsole(dc)if dc._debugFrame and dc._debugFrame:getVisible()then +dc:closeConsole()else dc:openConsole()end +return dc end +local cc={} +function cc.debugChildren(dc,_d)dc:debug(_d)for ad,bd in pairs(dc.get("children"))do if bd.debug then +bd:debug(_d)end end;return dc end;return{BaseElement=ac,Container=cc,BaseFrame=bc} end +project["plugins/animation.lua"] = function(...) local aa={} +local ba={linear=function(ab)return ab end,easeInQuad=function(ab)return ab*ab end,easeOutQuad=function(ab)return +1 - (1 -ab)* (1 -ab)end,easeInOutQuad=function(ab)if ab<0.5 then return 2 *ab*ab end;return 1 - ( +-2 *ab+2)^2 /2 end}local ca={}ca.__index=ca +function ca.new(ab,bb,cb,db,_c)local ac=setmetatable({},ca)ac.element=ab +ac.type=bb;ac.args=cb;ac.duration=db or 1;ac.startTime=0;ac.isPaused=false +ac.handlers=aa[bb]ac.easing=_c;return ac end;function ca:start()self.startTime=os.epoch("local")/1000;if +self.handlers.start then self.handlers.start(self)end +return self end +function ca:update(ab)local bb=math.min(1, +ab/self.duration) +local cb=ba[self.easing](bb)return self.handlers.update(self,cb)end;function ca:complete()if self.handlers.complete then +self.handlers.complete(self)end end +local da={}da.__index=da +function da.registerAnimation(ab,bb)aa[ab]=bb +da[ab]=function(cb,...)local db={...}local _c="linear" +if( +type(db[#db])=="string")then _c=table.remove(db,#db)end;local ac=table.remove(db,#db) +return cb:addAnimation(ab,db,ac,_c)end end;function da.registerEasing(ab,bb)ba[ab]=bb end +function da.new(ab)local bb={}bb.element=ab +bb.sequences={{}}bb.sequenceCallbacks={}bb.currentSequence=1;bb.timer=nil +setmetatable(bb,da)return bb end +function da:sequence()table.insert(self.sequences,{})self.currentSequence=# +self.sequences;self.sequenceCallbacks[self.currentSequence]={start=nil,update=nil,complete= +nil}return self end +function da:onStart(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].start=ab;return self end +function da:onUpdate(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].update=ab;return self end +function da:onComplete(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].complete=ab;return self end +function da:addAnimation(ab,bb,cb,db)local _c=ca.new(self.element,ab,bb,cb,db) +table.insert(self.sequences[self.currentSequence],_c)return self end +function da:start()self.currentSequence=1;self.timer=nil +if +(self.sequenceCallbacks[self.currentSequence])then if(self.sequenceCallbacks[self.currentSequence].start)then +self.sequenceCallbacks[self.currentSequence].start(self.element)end end +if +#self.sequences[self.currentSequence]>0 then self.timer=os.startTimer(0.05)for ab,bb in +ipairs(self.sequences[self.currentSequence])do bb:start()end end;return self end +function da:event(ab,bb) +if ab=="timer"and bb==self.timer then +local cb=os.epoch("local")/1000;local db=true;local _c={} +local ac=self.sequenceCallbacks[self.currentSequence] +for bc,cc in ipairs(self.sequences[self.currentSequence])do +local dc=cb-cc.startTime;local _d=dc/cc.duration;local ad=cc:update(dc)if ac and ac.update then +ac.update(self.element,_d)end;if not ad then table.insert(_c,cc)db=false else +cc:complete()end end +if db then +if ac and ac.complete then ac.complete(self.element)end +if self.currentSequence<#self.sequences then +self.currentSequence=self.currentSequence+1;_c={} +local bc=self.sequenceCallbacks[self.currentSequence]if bc and bc.start then bc.start(self.element)end +for cc,dc in +ipairs(self.sequences[self.currentSequence])do dc:start()table.insert(_c,dc)end end end;if#_c>0 then self.timer=os.startTimer(0.05)end +return true end end +function da:stop()if self.timer then pcall(os.cancelTimer,self.timer) +self.timer=nil end +for ab,bb in ipairs(self.sequences)do for cb,db in ipairs(bb)do +pcall(function()if db and +db.complete then db:complete()end end)end end;if +self.element and type(self.element.set)=="function"then +pcall(function()self.element.set("animation",nil)end)end end +da.registerAnimation("move",{start=function(ab)ab.startX=ab.element.get("x") +ab.startY=ab.element.get("y")end,update=function(ab,bb)local cb=ab.startX+ +(ab.args[1]-ab.startX)*bb;local db=ab.startY+ +(ab.args[2]-ab.startY)*bb +ab.element.set("x",math.floor(cb))ab.element.set("y",math.floor(db))return bb>=1 end,complete=function(ab) +ab.element.set("x",ab.args[1])ab.element.set("y",ab.args[2])end}) +da.registerAnimation("resize",{start=function(ab)ab.startW=ab.element.get("width") +ab.startH=ab.element.get("height")end,update=function(ab,bb)local cb=ab.startW+ +(ab.args[1]-ab.startW)*bb;local db=ab.startH+ +(ab.args[2]-ab.startH)*bb +ab.element.set("width",math.floor(cb))ab.element.set("height",math.floor(db)) +return bb>=1 end,complete=function(ab) +ab.element.set("width",ab.args[1])ab.element.set("height",ab.args[2])end}) +da.registerAnimation("moveOffset",{start=function(ab)ab.startX=ab.element.get("offsetX") +ab.startY=ab.element.get("offsetY")end,update=function(ab,bb)local cb=ab.startX+ (ab.args[1]-ab.startX)* +bb;local db=ab.startY+ (ab.args[2]- +ab.startY)*bb +ab.element.set("offsetX",math.floor(cb))ab.element.set("offsetY",math.floor(db))return +bb>=1 end,complete=function(ab) +ab.element.set("offsetX",ab.args[1])ab.element.set("offsetY",ab.args[2])end}) +da.registerAnimation("number",{start=function(ab) +ab.startValue=ab.element.get(ab.args[1])ab.targetValue=ab.args[2]end,update=function(ab,bb) +local cb= +ab.startValue+ (ab.targetValue-ab.startValue)*bb +ab.element.set(ab.args[1],math.floor(cb))return bb>=1 end,complete=function(ab) +ab.element.set(ab.args[1],ab.targetValue)end}) +da.registerAnimation("entries",{start=function(ab) +ab.startColor=ab.element.get(ab.args[1])ab.colorList=ab.args[2]end,update=function(ab,bb) +local cb=ab.colorList;local db=math.floor(#cb*bb)+1;if db>#cb then db=#cb end +ab.element.set(ab.args[1],cb[db])end,complete=function(ab) +ab.element.set(ab.args[1],ab.colorList[ +#ab.colorList])end}) +da.registerAnimation("morphText",{start=function(ab)local bb=ab.element.get(ab.args[1]) +local cb=ab.args[2]local db=math.max(#bb,#cb) +local _c=string.rep(" ",math.floor(db-#bb)/2)ab.startText=_c..bb.._c +ab.targetText=cb..string.rep(" ",db-#cb)ab.length=db end,update=function(ab,bb) +local cb="" +for i=1,ab.length do local db=ab.startText:sub(i,i) +local _c=ab.targetText:sub(i,i) +if bb<0.5 then +cb=cb.. (math.random()>bb*2 and db or" ")else cb=cb.. +(math.random()> (bb-0.5)*2 and" "or _c)end end;ab.element.set(ab.args[1],cb)return bb>=1 end,complete=function(ab) +ab.element.set(ab.args[1],ab.targetText:gsub("%s+$",""))end}) +da.registerAnimation("typewrite",{start=function(ab)ab.targetText=ab.args[2] +ab.element.set(ab.args[1],"")end,update=function(ab,bb) +local cb=math.floor(#ab.targetText*bb) +ab.element.set(ab.args[1],ab.targetText:sub(1,cb))return bb>=1 end}) +da.registerAnimation("fadeText",{start=function(ab)ab.chars={}for i=1,#ab.args[2]do +ab.chars[i]={char=ab.args[2]:sub(i,i),visible=false}end end,update=function(ab,bb) +local cb=""for db,_c in ipairs(ab.chars)do +if math.random()=1 end}) +da.registerAnimation("scrollText",{start=function(ab)ab.width=ab.element.get("width")ab.startText= +ab.element.get(ab.args[1])or"" +ab.targetText=ab.args[2]or""ab.startText=tostring(ab.startText) +ab.targetText=tostring(ab.targetText)end,update=function(ab,bb) +local cb=ab.width +if bb<0.5 then local db=bb/0.5;local _c=math.floor(cb*db) +local ac=( +ab.startText:sub(_c+1)..string.rep(" ",cb)):sub(1,cb)ab.element.set(ab.args[1],ac)else +local db=(bb-0.5)/0.5;local _c=math.floor(cb* (1 -db)) +local ac=string.rep(" ",_c)..ab.targetText;local bc=ac:sub(1,cb)ab.element.set(ab.args[1],bc)end;return bb>=1 end,complete=function(ab)local bb=( +ab.targetText..string.rep(" ",ab.width)) +ab.element.set(ab.args[1],bb)end}) +da.registerAnimation("marquee",{start=function(ab)ab.width=ab.element.get("width")ab.text=tostring( +ab.args[2]or"") +ab.speed=tonumber(ab.args[3])or 0.15;ab.offset=0;ab.lastShift=-1 +ab.padded=ab.text..string.rep(" ",ab.width)end,update=function(ab,bb)local cb= +os.epoch("local")/1000 -ab.startTime +local db=math.max(0.01,ab.speed)local _c=math.floor(cb/db) +if _c~=ab.lastShift then ab.lastShift=_c +local ac=#ab.padded;local bc=(_c%ac)+1;local cc=ab.padded..ab.padded +local dc=cc:sub(bc,bc+ab.width-1)ab.element.set(ab.args[1],dc)end;return false end,complete=function(ab) +end})local _b={hooks={}} +function _b.hooks.handleEvent(ab,bb,...)if bb=="timer"then local cb=ab.get("animation")if cb then +cb:event(bb,...)end end end +function _b.setup(ab) +ab.defineProperty(ab,"animation",{default=nil,type="table"})ab.defineEvent(ab,"timer")end +function _b.stopAnimation(ab)local bb=ab.get("animation") +if +bb and type(bb.stop)=="function"then bb:stop()else ab.set("animation",nil)end;return ab end +function _b:animate()local ab=da.new(self)self.set("animation",ab)return ab end;return{VisualElement=_b} end +project["plugins/benchmark.lua"] = function(...) local ca=require("log")local da=setmetatable({},{__mode="k"})local function _b()return +{methods={}}end +local function ab(_c,ac)local bc=_c[ac] +if not da[_c]then da[_c]=_b()end +if not da[_c].methods[ac]then +da[_c].methods[ac]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=ac,originalMethod=bc}end +_c[ac]=function(cc,...)cc:startProfile(ac)local dc=bc(cc,...) +cc:endProfile(ac)return dc end end;local bb={} +function bb:startProfile(_c)local ac=da[self]if not ac then ac=_b()da[self]=ac end;if not +ac.methods[_c]then +ac.methods[_c]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=_c}end +local bc=ac.methods[_c]bc.startTime=os.clock()*1000;bc.path={}local cc=self;while cc do +table.insert(bc.path,1, +cc.get("name")or cc.get("id"))cc=cc.parent end;return self end +function bb:endProfile(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]local cc=os.clock()*1000 +local dc=cc-bc.startTime;bc.calls=bc.calls+1;bc.totalTime=bc.totalTime+dc +bc.minTime=math.min(bc.minTime,dc)bc.maxTime=math.max(bc.maxTime,dc)bc.lastTime=dc;return self end +function bb:benchmark(_c)if not self[_c]then +ca.error("Method ".._c.." does not exist")return self end;da[self]=_b() +da[self].methodName=_c;da[self].isRunning=true;ab(self,_c)return self end +function bb:logBenchmark(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c] +if bc then local cc= +bc.calls>0 and(bc.totalTime/bc.calls)or 0 +ca.info(string.format( +"Benchmark results for %s.%s: ".. +"Path: %s ".."Calls: %d ".. +"Average time: %.2fms ".."Min time: %.2fms ".."Max time: %.2fms ".. +"Last time: %.2fms ".."Total time: %.2fms",table.concat(bc.path,"."),bc.methodName,table.concat(bc.path,"/"),bc.calls,cc, +bc.minTime~=math.huge and bc.minTime or 0,bc.maxTime,bc.lastTime,bc.totalTime))end;return self end +function bb:stopBenchmark(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]if bc and bc.originalMethod then +self[_c]=bc.originalMethod end;ac.methods[_c]=nil;if +not next(ac.methods)then da[self]=nil end;return self end +function bb:getBenchmarkStats(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return nil end;local bc=ac.methods[_c]return +{averageTime=bc.totalTime/bc.calls,totalTime=bc.totalTime,calls=bc.calls,minTime=bc.minTime,maxTime=bc.maxTime,lastTime=bc.lastTime}end;local cb={} +function cb:benchmarkContainer(_c)self:benchmark(_c) +for ac,bc in +pairs(self.get("children"))do bc:benchmark(_c)if bc:isType("Container")then +bc:benchmarkContainer(_c)end end;return self end +function cb:logContainerBenchmarks(_c,ac)ac=ac or 0;local bc=string.rep(" ",ac)local cc=0;local dc={} +for ad,bd in +pairs(self.get("children"))do local cd=da[bd] +if cd and cd.methods[_c]then local dd=cd.methods[_c] +cc=cc+dd.totalTime +table.insert(dc,{element=bd,type=bd.get("type"),calls=dd.calls,totalTime=dd.totalTime,avgTime=dd.totalTime/dd.calls})end end;local _d=da[self] +if _d and _d.methods[_c]then local ad=_d.methods[_c] +local bd=ad.totalTime-cc;local cd=bd/ad.calls +ca.info(string.format("%sBenchmark %s (%s): ".."%.2fms/call (Self: %.2fms/call) ".. +"[Total: %dms, Calls: %d]",bc,self.get("type"),_c, +ad.totalTime/ad.calls,cd,ad.totalTime,ad.calls)) +if#dc>0 then +for dd,__a in ipairs(dc)do +if __a.element:isType("Container")then __a.element:logContainerBenchmarks(_c, +ac+1)else +ca.info(string.format("%s> %s: %.2fms/call [Total: %dms, Calls: %d]", +bc.." ",__a.type,__a.avgTime,__a.totalTime,__a.calls))end end end end;return self end +function cb:stopContainerBenchmark(_c) +for ac,bc in pairs(self.get("children"))do if bc:isType("Container")then +bc:stopContainerBenchmark(_c)else bc:stopBenchmark(_c)end end;self:stopBenchmark(_c)return self end;local db={} +function db.start(_c,ac)ac=ac or{}local bc=_b()bc.name=_c +bc.startTime=os.clock()*1000;bc.custom=true;bc.calls=0;bc.totalTime=0;bc.minTime=math.huge;bc.maxTime=0 +bc.lastTime=0;da[_c]=bc end +function db.stop(_c)local ac=da[_c]if not ac or not ac.custom then return end;local bc= +os.clock()*1000;local cc=bc-ac.startTime;ac.calls=ac.calls+1;ac.totalTime= +ac.totalTime+cc;ac.minTime=math.min(ac.minTime,cc) +ac.maxTime=math.max(ac.maxTime,cc)ac.lastTime=cc +ca.info(string.format("Custom Benchmark '%s': ".. +"Calls: %d ".."Average time: %.2fms ".. +"Min time: %.2fms ".. +"Max time: %.2fms ".."Last time: %.2fms ".."Total time: %.2fms",_c,ac.calls, +ac.totalTime/ac.calls,ac.minTime,ac.maxTime,ac.lastTime,ac.totalTime))end +function db.getStats(_c)local ac=da[_c]if not ac then return nil end;return +{averageTime=ac.totalTime/ac.calls,totalTime=ac.totalTime,calls=ac.calls,minTime=ac.minTime,maxTime=ac.maxTime,lastTime=ac.lastTime}end;function db.clear(_c)da[_c]=nil end;function db.clearAll()for _c,ac in pairs(da)do +if ac.custom then da[_c]=nil end end end;return +{BaseElement=bb,Container=cb,API=db} end +project["elementManager.lua"] = function(...) local _c=table.pack(...) +local ac=fs.getDir(_c[2]or"basalt")local bc=_c[1]if(ac==nil)then +error("Unable to find directory ".. +_c[2].." please report this bug to our discord.")end +local cc=require("log")local dc=package.path;local _d="path;/path/?.lua;/path/?/init.lua;" +local ad=_d:gsub("path",ac)local bd={}bd._elements={}bd._plugins={}bd._APIs={} +bd._config={autoLoadMissing=false,allowRemoteLoading=false,allowDiskLoading=true,remoteSources={},diskMounts={},useGlobalCache=false,globalCacheName="_BASALT_ELEMENT_CACHE"}local cd=fs.combine(ac,"elements") +local dd=fs.combine(ac,"plugins")cc.info("Loading elements from "..cd) +if +fs.exists(cd)then +for d_a,_aa in ipairs(fs.list(cd))do local aaa=_aa:match("(.+).lua")if aaa then cc.debug( +"Found element: "..aaa) +bd._elements[aaa]={class=nil,plugins={},loaded=false,source="local",path=nil}end end end;cc.info("Loading plugins from "..dd) +if +fs.exists(dd)then +for d_a,_aa in ipairs(fs.list(dd))do local aaa=_aa:match("(.+).lua") +if aaa then cc.debug("Found plugin: ".. +aaa) +local baa=require(fs.combine("plugins",aaa)) +if type(baa)=="table"then +for caa,daa in pairs(baa)do +if(caa~="API")then if(bd._plugins[caa]==nil)then +bd._plugins[caa]={}end +table.insert(bd._plugins[caa],daa)else bd._APIs[aaa]=daa end end end end end end +if(minified)then if(minified_elementDirectory==nil)then +error("Unable to find minified_elementDirectory please report this bug to our discord.")end;for d_a,_aa in +pairs(minified_elementDirectory)do +bd._elements[d_a:gsub(".lua","")]={class=nil,plugins={},loaded=false,source="local",path=nil}end;if( +minified_pluginDirectory==nil)then +error("Unable to find minified_pluginDirectory please report this bug to our discord.")end +for d_a,_aa in +pairs(minified_pluginDirectory)do local aaa=d_a:gsub(".lua","") +local baa=require(fs.combine("plugins",aaa)) +if type(baa)=="table"then +for caa,daa in pairs(baa)do +if(caa~="API")then if(bd._plugins[caa]==nil)then +bd._plugins[caa]={}end +table.insert(bd._plugins[caa],daa)else bd._APIs[aaa]=daa end end end end end +local function __a(d_a,_aa)if not bd._config.useGlobalCache then return end +if not +_G[bd._config.globalCacheName]then _G[bd._config.globalCacheName]={}end;_G[bd._config.globalCacheName][d_a]=_aa;cc.debug( +"Cached element in _G: "..d_a)end +local function a_a(d_a)if not bd._config.useGlobalCache then return nil end +if + +_G[bd._config.globalCacheName]and _G[bd._config.globalCacheName][d_a]then +cc.debug("Loaded element from _G cache: "..d_a)return _G[bd._config.globalCacheName][d_a]end;return nil end +function bd.configure(d_a)for _aa,aaa in pairs(d_a)do +if bd._config[_aa]~=nil then bd._config[_aa]=aaa end end end +function bd.registerDiskMount(d_a)if not fs.exists(d_a)then +error("Disk mount path does not exist: "..d_a)end +table.insert(bd._config.diskMounts,d_a)cc.info("Registered disk mount: "..d_a) +local _aa=fs.combine(d_a,"elements") +if fs.exists(_aa)then +for aaa,baa in ipairs(fs.list(_aa))do +local caa=baa:match("(.+).lua") +if caa then +if not bd._elements[caa]then +cc.debug("Found element on disk: "..caa) +bd._elements[caa]={class=nil,plugins={},loaded=false,source="disk",path=fs.combine(_aa,baa)}end end end end end +function bd.registerRemoteSource(d_a,_aa)if not bd._config.allowRemoteLoading then +error("Remote loading is disabled. Enable with ElementManager.configure({allowRemoteLoading = true})")end +bd._config.remoteSources[d_a]=_aa +if not bd._elements[d_a]then +bd._elements[d_a]={class=nil,plugins={},loaded=false,source="remote",path=_aa}else bd._elements[d_a].source="remote" +bd._elements[d_a].path=_aa end +cc.info("Registered remote source for "..d_a..": ".._aa)end +local function b_a(d_a)if not http then +error("HTTP API is not available. Enable it in your CC:Tweaked config.")end +cc.info("Loading element from remote: "..d_a)local _aa=http.get(d_a)if not _aa then +error("Failed to download from: "..d_a)end;local aaa=_aa.readAll()_aa.close()if +not aaa or aaa==""then +error("Empty response from: "..d_a)end;local baa,caa=load(aaa,d_a,"t",_ENV)if not baa then +error( +"Failed to load element from "..d_a..": "..tostring(caa))end;local daa=baa()return daa end +local function c_a(d_a)if not fs.exists(d_a)then +error("Element file does not exist: "..d_a)end +cc.info("Loading element from disk: "..d_a)local _aa,aaa=loadfile(d_a)if not _aa then +error("Failed to load element from ".. +d_a..": "..tostring(aaa))end;local baa=_aa()return baa end +function bd.tryAutoLoad(d_a) +if bd._config.allowDiskLoading then +for _aa,aaa in ipairs(bd._config.diskMounts)do +local baa=fs.combine(aaa,"elements")local caa=fs.combine(baa,d_a..".lua") +if fs.exists(caa)then +bd._elements[d_a]={class= +nil,plugins={},loaded=false,source="disk",path=caa}bd.loadElement(d_a)return true end end end +if +bd._config.allowRemoteLoading and bd._config.remoteSources[d_a]then bd.loadElement(d_a)return true end;return false end +function bd.loadElement(d_a) +if not bd._elements[d_a]then +if bd._config.autoLoadMissing then +local _aa=bd.tryAutoLoad(d_a)if not _aa then +error("Element '"..d_a.."' not found and could not be auto-loaded")end else +error("Element '"..d_a.."' not found")end end +if not bd._elements[d_a].loaded then local _aa=bd._elements[d_a].source or +"local"local aaa;local baa=false;aaa=a_a(d_a) +if aaa then +baa=true +cc.info("Loaded element from _G cache: "..d_a)elseif _aa=="local"then package.path=ad.."rom/?" +aaa=require(fs.combine("elements",d_a))package.path=dc elseif _aa=="disk"then if not bd._config.allowDiskLoading then +error( +"Disk loading is disabled for element: "..d_a)end +aaa=c_a(bd._elements[d_a].path)__a(d_a,aaa)elseif _aa=="remote"then if not bd._config.allowRemoteLoading then +error( +"Remote loading is disabled for element: "..d_a)end +aaa=b_a(bd._elements[d_a].path)__a(d_a,aaa)else +error("Unknown source type: ".._aa)end +bd._elements[d_a]={class=aaa,plugins=aaa.plugins,loaded=true,source=baa and"cache"or _aa,path=bd._elements[d_a].path}if not baa then +cc.debug("Loaded element: "..d_a.." from ".._aa)end +if(bd._plugins[d_a]~=nil)then +for caa,daa in +pairs(bd._plugins[d_a])do if(daa.setup)then daa.setup(aaa)end +if(daa.hooks)then +for _ba,aba in pairs(daa.hooks)do +local bba=aaa[_ba]if(type(bba)~="function")then +error("Element ".. +d_a.." does not have a method ".._ba)end +if(type(aba)=="function")then +aaa[_ba]=function(cba,...) +local dba=bba(cba,...)local _ca=aba(cba,...)return _ca==nil and dba or _ca end elseif(type(aba)=="table")then +aaa[_ba]=function(cba,...)if aba.pre then aba.pre(cba,...)end +local dba=bba(cba,...)if aba.post then aba.post(cba,...)end;return dba end end end end;for _ba,aba in pairs(daa)do +if _ba~="setup"and _ba~="hooks"then aaa[_ba]=aba end end end end end end +function bd.getElement(d_a) +if not bd._elements[d_a]then +if bd._config.autoLoadMissing then +local _aa=bd.tryAutoLoad(d_a)if not _aa then +error("Element '"..d_a.."' not found")end else +error("Element '"..d_a.."' not found")end end +if not bd._elements[d_a].loaded then bd.loadElement(d_a)end;return bd._elements[d_a].class end;function bd.getElementList()return bd._elements end;function bd.getAPI(d_a) +return bd._APIs[d_a]end +function bd.hasElement(d_a)return bd._elements[d_a]~=nil end +function bd.isElementLoaded(d_a)return +bd._elements[d_a]and bd._elements[d_a].loaded or false end +function bd.clearGlobalCache()if _G[bd._config.globalCacheName]then _G[bd._config.globalCacheName]= +nil +cc.info("Cleared global element cache")end end +function bd.getCacheStats()if not _G[bd._config.globalCacheName]then +return{size=0,elements={}}end;local d_a={}for _aa,aaa in +pairs(_G[bd._config.globalCacheName])do table.insert(d_a,_aa)end;return +{size=#d_a,elements=d_a}end +function bd.preloadElements(d_a)for _aa,aaa in ipairs(d_a)do +if bd._elements[aaa]and +not bd._elements[aaa].loaded then bd.loadElement(aaa)end end end;return bd end +project["log.lua"] = function(...) local aa={}aa._logs={}aa._enabled=false;aa._logToFile=false +aa._logFile="basalt.log"fs.delete(aa._logFile) +aa.LEVEL={DEBUG=1,INFO=2,WARN=3,ERROR=4} +local ba={[aa.LEVEL.DEBUG]="Debug",[aa.LEVEL.INFO]="Info",[aa.LEVEL.WARN]="Warn",[aa.LEVEL.ERROR]="Error"} +local ca={[aa.LEVEL.DEBUG]=colors.lightGray,[aa.LEVEL.INFO]=colors.white,[aa.LEVEL.WARN]=colors.yellow,[aa.LEVEL.ERROR]=colors.red}function aa.setLogToFile(ab)aa._logToFile=ab end +function aa.setEnabled(ab)aa._enabled=ab end;local function da(ab) +if aa._logToFile then local bb=io.open(aa._logFile,"a")if bb then +bb:write(ab.."\n")bb:close()end end end +local function _b(ab,...)if +not aa._enabled then return end;local bb=os.date("%H:%M:%S") +local cb=debug.getinfo(3,"Sl")local db=cb.source:match("@?(.*)")local _c=cb.currentline +local ac=string.format("[%s:%d]",db:match("([^/\\]+)%.lua$"),_c)local bc="["..ba[ab].."]"local cc="" +for _d,ad in ipairs(table.pack(...))do if _d>1 then cc= +cc.." "end;cc=cc..tostring(ad)end;local dc=string.format("%s %s%s %s",bb,ac,bc,cc)da(dc) +table.insert(aa._logs,{time=bb,level=ab,message=cc})end;function aa.debug(...)_b(aa.LEVEL.DEBUG,...)end;function aa.info(...) +_b(aa.LEVEL.INFO,...)end +function aa.warn(...)_b(aa.LEVEL.WARN,...)end;function aa.error(...)_b(aa.LEVEL.ERROR,...)end;return aa end +project["propertySystem.lua"] = function(...) local ba=require("libraries/utils").deepCopy +local ca=require("libraries/expect")local da=require("errorManager")local _b={}_b.__index=_b +_b._properties={}local ab={}_b._setterHooks={}function _b.addSetterHook(cb) +table.insert(_b._setterHooks,cb)end +local function bb(cb,db,_c,ac)for bc,cc in ipairs(_b._setterHooks)do +local dc=cc(cb,db,_c,ac)if dc~=nil then _c=dc end end;return _c end +function _b.defineProperty(cb,db,_c) +if not rawget(cb,'_properties')then cb._properties={}end +cb._properties[db]={type=_c.type,default=_c.default,canTriggerRender=_c.canTriggerRender,getter=_c.getter,setter=_c.setter,allowNil=_c.allowNil}local ac=db:sub(1,1):upper()..db:sub(2) +cb[ +"get"..ac]=function(bc,...)ca(1,bc,"element")local cc=bc._values[db] +if type(cc)== +"function"and _c.type~="function"then cc=cc(bc)end +return _c.getter and _c.getter(bc,cc,...)or cc end +cb["set"..ac]=function(bc,cc,...)ca(1,bc,"element")cc=bb(bc,db,cc,_c)if +type(cc)~="function"then +if _c.type=="table"then if cc==nil then +if not _c.allowNil then ca(2,cc,_c.type)end end else ca(2,cc,_c.type)end end;if +_c.setter then cc=_c.setter(bc,cc,...)end +bc:_updateProperty(db,cc)return bc end +cb["get"..ac.."State"]=function(bc,cc,...)ca(1,bc,"element")return +bc.getPropertyState(db,cc,...)end +cb["set"..ac.."State"]=function(bc,cc,dc,...)ca(1,bc,"element") +bc.setPropertyState(db,cc,dc,...)return bc end end +function _b.combineProperties(cb,db,...)local _c={...}for bc,cc in pairs(_c)do +if not cb._properties[cc]then da.error("Property not found: ".. +cc)end end;local ac= +db:sub(1,1):upper()..db:sub(2) +cb["get"..ac]=function(bc) +ca(1,bc,"element")local cc={} +for dc,_d in pairs(_c)do table.insert(cc,bc.get(_d))end;return table.unpack(cc)end +cb["set"..ac]=function(bc,...)ca(1,bc,"element")local cc={...}for dc,_d in pairs(_c)do +bc.set(_d,cc[dc])end;return bc end end +function _b.blueprint(cb,db,_c,ac) +if not ab[cb]then +local cc={basalt=_c,__isBlueprint=true,_values=db or{},_events={},render=function()end,dispatchEvent=function()end,init=function()end} +cc.loaded=function(_d,ad)_d.loadedCallback=ad;return cc end +cc.create=function(_d)local ad=cb.new()ad:init({},_d.basalt)for bd,cd in pairs(_d._values)do +ad._values[bd]=cd end;for bd,cd in pairs(_d._events)do +for dd,__a in ipairs(cd)do ad[bd](ad,__a)end end +if(ac~=nil)then ac:addChild(ad)end;ad:updateRender()_d.loadedCallback(ad) +ad:postInit()return ad end;local dc=cb +while dc do +if rawget(dc,'_properties')then for _d,ad in pairs(dc._properties)do +if +type(ad.default)=="table"then cc._values[_d]=ba(ad.default)else cc._values[_d]=ad.default end end end +dc=getmetatable(dc)and rawget(getmetatable(dc),'__index')end;ab[cb]=cc end;local bc={_values={},_events={},loadedCallback=function()end} +bc.get=function(cc) +local dc=bc._values[cc]local _d=cb._properties[cc]if +type(dc)=="function"and _d.type~="function"then dc=dc(bc)end;return dc end +bc.set=function(cc,dc)bc._values[cc]=dc;return bc end +setmetatable(bc,{__index=function(cc,dc) +if dc:match("^on%u")then return +function(_d,ad) +cc._events[dc]=cc._events[dc]or{}table.insert(cc._events[dc],ad)return cc end end +if dc:match("^get%u")then +local _d=dc:sub(4,4):lower()..dc:sub(5)return function()return cc._values[_d]end end;if dc:match("^set%u")then +local _d=dc:sub(4,4):lower()..dc:sub(5) +return function(ad,bd)cc._values[_d]=bd;return cc end end +return ab[cb][dc]end})return bc end +function _b.createFromBlueprint(cb,db,_c)local ac=cb.new({},_c) +for bc,cc in pairs(db._values)do if type(cc)=="table"then +ac._values[bc]=ba(cc)else ac._values[bc]=cc end end;return ac end +function _b:__init()self._values={}self._observers={}self._states={} +self.set=function(bc,cc,...) +local dc=self._values[bc]local _d=self._properties[bc] +if(_d~=nil)then if(_d.setter)then +cc=_d.setter(self,cc,...)end +if _d.canTriggerRender then self:updateRender()end;self._values[bc]=bb(self,bc,cc,_d)if +dc~=cc and self._observers[bc]then +for ad,bd in ipairs(self._observers[bc])do bd(self,cc,dc)end end end end +self.get=function(bc,...)local cc=self._values[bc]local dc=self._properties[bc] +if +(dc==nil)then da.error("Property not found: "..bc)return end;if type(cc)=="function"and dc.type~="function"then +cc=cc(self)end;return +dc.getter and dc.getter(self,cc,...)or cc end +self.setPropertyState=function(bc,cc,dc,...)local _d=self._properties[bc] +if(_d~=nil)then if(_d.setter)then +dc=_d.setter(self,dc,...)end;dc=bb(self,bc,dc,_d)if +not self._states[cc]then self._states[cc]={}end +self._states[cc][bc]=dc;local ad=self._values.currentState +if ad==cc then if _d.canTriggerRender then +self:updateRender()end +if self._observers[bc]then for bd,cd in +ipairs(self._observers[bc])do cd(self,dc,nil)end end end end end +self.getPropertyState=function(bc,cc,...)local dc=self._states and self._states[cc]and +self._states[cc][bc]local _d= +dc~=nil and dc or self._values[bc] +local ad=self._properties[bc]if(ad==nil)then da.error("Property not found: "..bc) +return end;if +type(_d)=="function"and ad.type~="function"then _d=_d(self)end;return +ad.getter and ad.getter(self,_d,...)or _d end +self.getResolved=function(bc,...)local cc=self:getCurrentState()local dc +if +cc and self._states and +self._states[cc]and self._states[cc][bc]~=nil then dc=self._states[cc][bc]else dc=self._values[bc]end;local _d=self._properties[bc]if(_d==nil)then +da.error("Property not found: "..bc)return end;if +type(dc)=="function"and _d.type~="function"then dc=dc(self)end;return +_d.getter and _d.getter(self,dc,...)or dc end;local cb={}local db=getmetatable(self).__index +while db do if +rawget(db,'_properties')then +for bc,cc in pairs(db._properties)do if not cb[bc]then cb[bc]=cc end end end;db=getmetatable(db)and +rawget(getmetatable(db),'__index')end;self._properties=cb;local _c=getmetatable(self)local ac=_c.__index +setmetatable(self,{__index=function(bc,cc) +local dc=self._properties[cc] +if dc then local _d=self._values[cc]if +type(_d)=="function"and dc.type~="function"then _d=_d(self)end;return _d end +if type(ac)=="function"then return ac(bc,cc)else return ac[cc]end end,__newindex=function(bc,cc,dc) +local _d=self._properties[cc] +if _d then if _d.setter then dc=_d.setter(self,dc)end +dc=bb(self,cc,dc,_d)self:_updateProperty(cc,dc)else rawset(bc,cc,dc)end end,__tostring=function(bc)return +string.format("Object: %s (id: %s)",bc._values.type,bc.id)end}) +for bc,cc in pairs(cb)do if self._values[bc]==nil then +if type(cc.default)=="table"then +self._values[bc]=ba(cc.default)else self._values[bc]=cc.default end end end;return self end +function _b:_updateProperty(cb,db)local _c=self._values[cb] +if type(_c)=="function"then _c=_c(self)end;self._values[cb]=db +local ac=type(db)=="function"and db(self)or db +if _c~=ac then +if self._properties[cb].canTriggerRender then self:updateRender()end +if self._observers[cb]then for bc,cc in ipairs(self._observers[cb])do +cc(self,ac,_c)end end end;return self end +function _b:observe(cb,db) +self._observers[cb]=self._observers[cb]or{}table.insert(self._observers[cb],db)return self end +function _b:removeObserver(cb,db) +if self._observers[cb]then +for _c,ac in ipairs(self._observers[cb])do if ac==db then +table.remove(self._observers[cb],_c) +if#self._observers[cb]==0 then self._observers[cb]=nil end;break end end end;return self end;function _b:removeAllObservers(cb) +if cb then self._observers[cb]=nil else self._observers={}end;return self end +function _b:instanceProperty(cb,db) +_b.defineProperty(self,cb,db)self._values[cb]=db.default;return self end +function _b:removeProperty(cb)self._values[cb]=nil;self._properties[cb]=nil;self._observers[cb]= +nil +local db=cb:sub(1,1):upper()..cb:sub(2)self["get"..db]=nil;self["set"..db]=nil;self["get"..db.."State"]= +nil;self["set"..db.."State"]=nil;return self end +function _b:getPropertyConfig(cb)return self._properties[cb]end;return _b end +project["main.lua"] = function(...) local ad=require("elementManager") +local bd=require("errorManager")local cd=require("propertySystem") +local dd=require("libraries/expect")local __a={}__a.traceback=true;__a._events={}__a._schedule={} +__a._eventQueue={}__a._plugins={}__a.isRunning=false;__a.LOGGER=require("log") +if(minified)then +__a.path=fs.getDir(shell.getRunningProgram())else __a.path=fs.getDir(select(2,...))end;local a_a=nil;local b_a=nil;local c_a={}local d_a=type;local _aa={}local aaa=10;local baa=0;local caa=false +local function daa() +if(caa)then return end;baa=os.startTimer(0.2)caa=true end +local function _ba(aca)for _=1,aca do local bca=_aa[1]if(bca)then bca:create()end +table.remove(_aa,1)end end;local function aba(aca,bca) +if(aca=="timer")then if(bca==baa)then _ba(aaa)caa=false;baa=0;if(#_aa>0)then daa()end +return true end end end +function __a.create(aca,bca,cca,dca)if( +d_a(bca)=="string")then bca={name=bca}end +if(bca==nil)then bca={name=aca}end;local _da=ad.getElement(aca) +if(cca)then +local ada=cd.blueprint(_da,bca,__a,dca)table.insert(_aa,ada)daa()return ada else local ada=_da.new() +ada:init(bca,__a)return ada end end +function __a.createFrame()local aca=__a.create("BaseFrame")aca:postInit()if +(a_a==nil)then a_a=tostring(term.current()) +__a.setActiveFrame(aca,true)end;return aca end;function __a.getElementManager()return ad end +function __a.getErrorManager()return bd end +function __a.getMainFrame()local aca=tostring(term.current())if(c_a[aca]==nil)then +a_a=aca;__a.createFrame()end;return c_a[aca]end +function __a.setActiveFrame(aca,bca)local cca=aca:getTerm()if(bca==nil)then bca=true end +if(cca~=nil)then c_a[tostring(cca)]= +bca and aca or nil;aca:updateRender()end end;function __a.getActiveFrame(aca)if(aca==nil)then aca=term.current()end;return +c_a[tostring(aca)]end +function __a.setFocus(aca)if +(b_a==aca)then return end +if(b_a~=nil)then b_a:dispatchEvent("blur")end;b_a=aca +if(b_a~=nil)then b_a:dispatchEvent("focus")end end;function __a.getFocus()return b_a end +function __a.schedule(aca)dd(1,aca,"function") +local bca=coroutine.create(aca)local cca,dca=coroutine.resume(bca) +if(cca)then +table.insert(__a._schedule,{coroutine=bca,filter=dca})else bd.header="Basalt Schedule Error"bd.error(dca)end;return bca end +function __a.removeSchedule(aca) +for bca,cca in ipairs(__a._schedule)do if(cca.coroutine==aca)then +table.remove(__a._schedule,bca)return true end end;return false end +local bba={mouse_click=true,mouse_up=true,mouse_scroll=true,mouse_drag=true}local cba={key=true,key_up=true,char=true} +local function dba(aca,...)if(aca=="terminate")then __a.stop() +return end;if aba(aca,...)then return end;local bca={...} +local function cca() +if(bba[aca])then if +c_a[a_a]then +c_a[a_a]:dispatchEvent(aca,table.unpack(bca))end elseif(cba[aca])then if(b_a~=nil)then +b_a:dispatchEvent(aca,table.unpack(bca))end else for bda,cda in pairs(c_a)do +cda:dispatchEvent(aca,table.unpack(bca))end end end +for bda,cda in pairs(__a._eventQueue)do +if +coroutine.status(cda.coroutine)=="suspended"then +if cda.filter==aca or cda.filter==nil then cda.filter=nil +local dda,__b=coroutine.resume(cda.coroutine,aca,...) +if not dda then bd.header="Basalt Event Error"bd.error(__b)end;cda.filter=__b end end;if coroutine.status(cda.coroutine)=="dead"then +table.remove(__a._eventQueue,bda)end end;local dca={coroutine=coroutine.create(cca),filter=aca} +local _da,ada=coroutine.resume(dca.coroutine,aca,...) +if(not _da)then bd.header="Basalt Event Error"bd.error(ada)end;if(ada~=nil)then dca.filter=ada end +table.insert(__a._eventQueue,dca) +for bda,cda in ipairs(__a._schedule)do +if +coroutine.status(cda.coroutine)=="suspended"then +if aca==cda.filter or cda.filter==nil then cda.filter=nil +local dda,__b=coroutine.resume(cda.coroutine,aca,...) +if(not dda)then bd.header="Basalt Schedule Error"bd.error(__b)end;cda.filter=__b end end;if(coroutine.status(cda.coroutine)=="dead")then +__a.removeSchedule(cda.coroutine)end end;if __a._events[aca]then +for bda,cda in ipairs(__a._events[aca])do cda(...)end end end;local function _ca() +for aca,bca in pairs(c_a)do bca:render()bca:postRender()end end +function __a.update(...)local aca=function(...)__a.isRunning=true +dba(...)_ca()end +local bca,cca=pcall(aca,...) +if not(bca)then bd.header="Basalt Runtime Error"bd.error(cca)end;__a.isRunning=false end;function __a.stop()__a.isRunning=false;term.clear() +term.setCursorPos(1,1)end +function __a.run(aca)if(__a.isRunning)then +bd.error("Basalt is already running")end;if(aca==nil)then __a.isRunning=true else +__a.isRunning=aca end +local function bca()_ca()while __a.isRunning do +dba(os.pullEventRaw())if(__a.isRunning)then _ca()end end end +while __a.isRunning do local cca,dca=pcall(bca)if not(cca)then bd.header="Basalt Runtime Error" +bd.error(dca)end end end;function __a.getElementClass(aca)return ad.getElement(aca)end;function __a.getAPI(aca)return +ad.getAPI(aca)end +function __a.onEvent(aca,bca)dd(1,aca,"string") +dd(2,bca,"function") +if not __a._events[aca]then __a._events[aca]={}end;table.insert(__a._events[aca],bca)end +function __a.removeEvent(aca,bca)dd(1,aca,"string")dd(2,bca,"function")if not +__a._events[aca]then return false end;for cca,dca in ipairs(__a._events[aca])do +if +dca==bca then table.remove(__a._events[aca],cca)return true end end;return false end +function __a.triggerEvent(aca,...)dd(1,aca,"string") +if __a._events[aca]then +for bca,cca in +ipairs(__a._events[aca])do local dca,_da=pcall(cca,...)if not dca then bd.header="Basalt Event Callback Error" +bd.error( +"Error in event callback for '"..aca.."': "..tostring(_da))end end end end +function __a.requireElements(aca,bca)if type(aca)=="string"then aca={aca}end +dd(1,aca,"table")if bca~=nil then dd(2,bca,"boolean")end;local cca={}local dca={}for _da,ada in +ipairs(aca)do +if not ad.hasElement(ada)then table.insert(cca,ada)elseif not +ad.isElementLoaded(ada)then table.insert(dca,ada)end end +if +#dca>0 then +for _da,ada in ipairs(dca)do local bda,cda=pcall(ad.loadElement,ada) +if not bda then +__a.LOGGER.warn( +"Failed to load element "..ada..": "..tostring(cda))table.insert(cca,ada)end end end +if#cca>0 then +if bca then local _da={}for ada,bda in ipairs(cca)do local cda=ad.tryAutoLoad(bda)if not cda then +table.insert(_da,bda)end end +if +#_da>0 then +local ada="Missing required elements: "..table.concat(_da,", ") +ada=ada.."\n\nThese elements could not be auto-loaded." +ada=ada.."\nPlease install them or register remote sources."bd.error(ada)end else +local _da="Missing required elements: "..table.concat(cca,", ")_da=_da.."\n\nSuggestions:" +_da=_da.."\n • Use basalt.requireElements({...}, true) to auto-load" +_da=_da.."\n • Register remote sources with elementManager.registerRemoteSource()" +_da=_da.."\n • Register disk mounts with elementManager.registerDiskMount()"bd.error(_da)end end +__a.LOGGER.info("All required elements are available: "..table.concat(aca,", "))return true end +function __a.loadManifest(aca)dd(1,aca,"string") +if not fs.exists(aca)then bd.error( +"Manifest file not found: "..aca)end;local bca;local cca,dca=pcall(dofile,aca)if not cca then +bd.error("Failed to load manifest: "..tostring(dca))end;bca=dca;if type(bca)~="table"then +bd.error("Manifest must return a table")end +if bca.config then +ad.configure(bca.config)__a.LOGGER.debug("Applied manifest config")end;if bca.diskMounts then +for _da,ada in ipairs(bca.diskMounts)do ad.registerDiskMount(ada)end end;if bca.remoteSources then +for _da,ada in +pairs(bca.remoteSources)do ad.registerRemoteSource(_da,ada)end end;if bca.requiredElements then local _da= +bca.autoLoadMissing~=false +__a.requireElements(bca.requiredElements,_da)end +if bca.optionalElements then for _da,ada in +ipairs(bca.optionalElements)do pcall(ad.loadElement,ada)end end +if bca.preloadElements then ad.preloadElements(bca.preloadElements)end +__a.LOGGER.info("Manifest loaded successfully: ".. (bca.name or aca))return bca end +function __a.install(aca,bca)dd(1,aca,"string") +if bca~=nil then dd(2,bca,"string")end +if ad.hasElement(aca)and ad.isElementLoaded(aca)then return true end +if bca then +if bca:match("^https?://")then ad.registerRemoteSource(aca,bca)else if not +fs.exists(bca)then +bd.error("Source file not found: "..bca)end end end;local cca=ad.tryAutoLoad(aca)if cca then return true else return false end end +function __a.configure(aca)dd(1,aca,"table")ad.configure(aca)end;return __a end +project["layoutManager.lua"] = function(...) local b={}b._cache={} +function b.load(c)if b._cache[c]then return b._cache[c]end +local d,_a=pcall(require,c)if not d then +error("Failed to load layout: "..c.."\n".._a)end;if type(_a)~="table"then +error("Layout must return a table: "..c)end;if type(_a.calculate)~="function"then +error( +"Layout must have a calculate() function: "..c)end;b._cache[c]=_a;return _a end +function b.apply(c,d)local _a=b.load(d)local aa={layout=_a,container=c,options={}} +_a.calculate(aa)b._applyPositions(aa)return aa end +function b._applyPositions(c)if not c._positions then return end +for d,_a in pairs(c._positions)do +if +not d._destroyed then d.set("x",_a.x)d.set("y",_a.y) +d.set("width",_a.width)d.set("height",_a.height) +d._layoutValues={x=_a.x,y=_a.y,width=_a.width,height=_a.height}end end end +function b._wasChangedByUser(c)if not c._layoutValues then return false end +local d=c.get("x")local _a=c.get("y")local aa=c.get("width")local ba=c.get("height") +return d~= +c._layoutValues.x or _a~=c._layoutValues.y or aa~= +c._layoutValues.width or +ba~=c._layoutValues.height end +function b.update(c) +if c and c.layout and c.layout.calculate then +if c._positions then for d,_a in pairs(c._positions)do +if not +d._destroyed then d._userModified=b._wasChangedByUser(d)end end end;c.layout.calculate(c)b._applyPositions(c)end end +function b.destroy(c)if c and c.layout and c.layout.destroy then +c.layout.destroy(c)end;if c then c._positions=nil end end;return b end +project["libraries/colorHex.lua"] = function(...) local b={}for i=0,15 do b[2 ^i]=("%x"):format(i) +b[("%x"):format(i)]=2 ^i end;return b end +project["libraries/utils.lua"] = function(...) local d,_a=math.floor,string.len;local aa={} +function aa.getCenteredPosition(ba,ca,da)local _b=_a(ba)local ab=d( +(ca-_b+1)/2 +0.5)local bb=d(da/2 +0.5)return ab,bb end +function aa.deepCopy(ba)if type(ba)~="table"then return ba end;local ca={}for da,_b in pairs(ba)do +ca[aa.deepCopy(da)]=aa.deepCopy(_b)end;return ca end +function aa.copy(ba)local ca={}for da,_b in pairs(ba)do ca[da]=_b end;return ca end;function aa.reverse(ba)local ca={}for i=#ba,1,-1 do table.insert(ca,ba[i])end +return ca end +function aa.uuid() +return +string.format('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',math.random(0,0xffff),math.random(0,0xffff),math.random(0,0xffff), +math.random(0,0x0fff)+0x4000,math.random(0,0x3fff)+0x8000,math.random(0,0xffff),math.random(0,0xffff),math.random(0,0xffff))end +function aa.split(ba,ca)local da={}for _b in(ba..ca):gmatch("(.-)"..ca)do +table.insert(da,_b)end;return da end;function aa.removeTags(ba)return ba:gsub("{[^}]+}","")end +function aa.wrapText(ba,ca)if +ba==nil then return{}end;ba=aa.removeTags(ba)local da={} +local _b=aa.split(ba,"\n\n") +for ab,bb in ipairs(_b)do +if#bb==0 then table.insert(da,"")if ab<#_b then +table.insert(da,"")end else local cb=aa.split(bb,"\n") +for db,_c in ipairs(cb)do +local ac=aa.split(_c," ")local bc="" +for cc,dc in ipairs(ac)do if#bc==0 then bc=dc elseif#bc+#dc+1 <=ca then bc=bc.." "..dc else +table.insert(da,bc)bc=dc end end;if#bc>0 then table.insert(da,bc)end end;if ab<#_b then table.insert(da,"")end end end;return da end;return aa end +project["libraries/collectionentry.lua"] = function(...) local b={} +b.__index=function(c,d)local _a=rawget(b,d)if _a then return _a end;if c._data[d]~=nil then return +c._data[d]end;local aa=c._parent[d]if aa then return aa end +return nil end +function b.new(c,d)local _a={_parent=c,_data=d}return setmetatable(_a,b)end +function b:_findIndex()for c,d in ipairs(self._parent:getItems())do +if d==self then return c end end;return nil end;function b:setText(c)self._data.text=c +self._parent:updateRender()return self end;function b:getText() +return self._data.text end +function b:moveUp(c)local d=self._parent:getItems() +local _a=self:_findIndex()if not _a then return self end;c=c or 1;local aa=math.max(1,_a-c)if _a~=aa then +table.remove(d,_a)table.insert(d,aa,self) +self._parent:updateRender()end;return self end +function b:moveDown(c)local d=self._parent:getItems() +local _a=self:_findIndex()if not _a then return self end;c=c or 1;local aa=math.min(#d,_a+c)if _a~=aa then +table.remove(d,_a)table.insert(d,aa,self) +self._parent:updateRender()end;return self end +function b:moveToTop()local c=self._parent:getItems() +local d=self:_findIndex()if not d or d==1 then return self end;table.remove(c,d) +table.insert(c,1,self)self._parent:updateRender()return self end +function b:moveToBottom()local c=self._parent:getItems() +local d=self:_findIndex()if not d or d==#c then return self end;table.remove(c,d) +table.insert(c,self)self._parent:updateRender()return self end;function b:getIndex()return self:_findIndex()end +function b:swapWith(c) +local d=self._parent:getItems()local _a=self:getIndex()local aa=c:getIndex() +if _a and aa and _a~=aa then +d[_a],d[aa]=d[aa],d[_a]self._parent:updateRender()end;return self end +function b:remove()if self._parent and self._parent.removeItem then +self._parent:removeItem(self)return true end;return false end +function b:select()if self._parent and self._parent.selectItem then +self._parent:selectItem(self)end;return self end +function b:unselect()if self._parent and self._parent.unselectItem then +self._parent:unselectItem(self)end end +function b:isSelected() +if self._parent and self._parent.getSelectedItem then return +self._parent:getSelectedItem()==self end;return false end;return b end +project["libraries/expect.lua"] = function(...) local c=require("errorManager") +local function d(_a,aa,ba)local ca=type(aa) +if ba=="element"then if ca=="table"and +aa.get("type")~=nil then return true end end +if ba=="color"then if ca=="number"then return true end;if +ca=="string"and colors[aa]then return true end end;if ca~=ba then c.header="Basalt Type Error" +c.error(string.format("Bad argument #%d: expected %s, got %s",_a,ba,ca))end;return true end;return d end +return project["main.lua"]() \ No newline at end of file diff --git a/release/basalt-full.lua b/release/basalt-full.lua new file mode 100644 index 0000000..2eeadbd --- /dev/null +++ b/release/basalt-full.lua @@ -0,0 +1,4535 @@ +local minified = true +local minified_elementDirectory = {} +local minified_pluginDirectory = {} +local project = {} +local loadedProject = {} +local baseRequire = require +require = function(path) if(project[path..".lua"])then if(loadedProject[path]==nil)then loadedProject[path] = project[path..".lua"]() end return loadedProject[path] end return baseRequire(path) end +minified_elementDirectory["BaseFrame"] = {} +minified_elementDirectory["Timer"] = {} +minified_elementDirectory["Program"] = {} +minified_elementDirectory["Image"] = {} +minified_elementDirectory["BarChart"] = {} +minified_elementDirectory["ComboBox"] = {} +minified_elementDirectory["ScrollFrame"] = {} +minified_elementDirectory["TabControl"] = {} +minified_elementDirectory["TextBox"] = {} +minified_elementDirectory["Button"] = {} +minified_elementDirectory["Label"] = {} +minified_elementDirectory["SideNav"] = {} +minified_elementDirectory["Input"] = {} +minified_elementDirectory["Toast"] = {} +minified_elementDirectory["BigFont"] = {} +minified_elementDirectory["Switch"] = {} +minified_elementDirectory["Frame"] = {} +minified_elementDirectory["Container"] = {} +minified_elementDirectory["Dialog"] = {} +minified_elementDirectory["Tree"] = {} +minified_elementDirectory["DropDown"] = {} +minified_elementDirectory["Display"] = {} +minified_elementDirectory["Breadcrumb"] = {} +minified_elementDirectory["LineChart"] = {} +minified_elementDirectory["Graph"] = {} +minified_elementDirectory["Table"] = {} +minified_elementDirectory["Menu"] = {} +minified_elementDirectory["Slider"] = {} +minified_elementDirectory["ScrollBar"] = {} +minified_elementDirectory["VisualElement"] = {} +minified_elementDirectory["ProgressBar"] = {} +minified_elementDirectory["CheckBox"] = {} +minified_elementDirectory["BaseElement"] = {} +minified_elementDirectory["ContextMenu"] = {} +minified_elementDirectory["List"] = {} +minified_elementDirectory["Collection"] = {} +minified_elementDirectory["Accordion"] = {} +minified_pluginDirectory["canvas"] = {} +minified_pluginDirectory["theme"] = {} +minified_pluginDirectory["reactive"] = {} +minified_pluginDirectory["xml"] = {} +minified_pluginDirectory["debug"] = {} +minified_pluginDirectory["animation"] = {} +minified_pluginDirectory["benchmark"] = {} +project["errorManager.lua"] = function(...) local d=require("log") +local _a={tracebackEnabled=true,header="Basalt Error"}local function aa(ba,ca)term.setTextColor(ca)print(ba) +term.setTextColor(colors.white)end +function _a.error(ba) +if _a.errorHandled then error()end;term.setBackgroundColor(colors.black) +term.clear()term.setCursorPos(1,1) +aa(_a.header..":",colors.red)print()local ca=2;local da;while true do local db=debug.getinfo(ca,"Sl") +if not db then break end;da=db;ca=ca+1 end;local _b=da or +debug.getinfo(2,"Sl")local ab=_b.source:sub(2) +local bb=_b.currentline;local cb=ba +if(_a.tracebackEnabled)then local db=debug.traceback() +if db then +for _c in db:gmatch("[^\r\n]+")do +local ac,bc=_c:match("([^:]+):(%d+):") +if ac and bc then term.setTextColor(colors.lightGray) +term.write(ac)term.setTextColor(colors.gray)term.write(":") +term.setTextColor(colors.lightBlue)term.write(bc)term.setTextColor(colors.gray)_c=_c:gsub( +ac..":"..bc,"")end;aa(_c,colors.gray)end;print()end end +if ab and bb then term.setTextColor(colors.red) +term.write("Error in ")term.setTextColor(colors.white)term.write(ab) +term.setTextColor(colors.red)term.write(":") +term.setTextColor(colors.lightBlue)term.write(bb)term.setTextColor(colors.red) +term.write(": ") +if cb then cb=string.gsub(cb,"stack traceback:.*","") +if cb~=""then +aa(cb,colors.red)else aa("Error message not available",colors.gray)end else aa("Error message not available",colors.gray)end;local db=fs.open(ab,"r") +if db then local _c=""local ac=1 +repeat _c=db.readLine()if +ac==tonumber(bb)then aa("\149Line "..bb,colors.cyan) +aa(_c,colors.lightGray)break end;ac=ac+1 until not _c;db.close()end end;term.setBackgroundColor(colors.black) +d.error(ba)_a.errorHandled=true;error()end;return _a end +project["render.lua"] = function(...) local _a=require("libraries/colorHex")local aa=require("log") +local ba={}ba.__index=ba;local ca=string.sub +function ba.new(da)local _b=setmetatable({},ba) +_b.terminal=da;_b.width,_b.height=da.getSize() +_b.buffer={text={},fg={},bg={},dirtyRects={}} +for y=1,_b.height do _b.buffer.text[y]=string.rep(" ",_b.width) +_b.buffer.fg[y]=string.rep("0",_b.width)_b.buffer.bg[y]=string.rep("f",_b.width)end;return _b end;function ba:addDirtyRect(da,_b,ab,bb) +table.insert(self.buffer.dirtyRects,{x=da,y=_b,width=ab,height=bb})return self end +function ba:blit(da,_b,ab,bb,cb)if +_b<1 or _b>self.height then return self end;if(#ab~=#bb or +#ab~=#cb)then +error("Text, fg, and bg must be the same length")end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.fg[_b]=ca( +self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width) +self.buffer.bg[_b]=ca( +self.buffer.bg[_b]:sub(1,da-1)..cb..self.buffer.bg[_b]:sub(da+#cb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:multiBlit(da,_b,ab,bb,cb,db,_c)if _b<1 or _b>self.height then return self end;if( +#cb~=#db or#cb~=#_c)then +error("Text, fg, and bg must be the same length")end;cb=cb:rep(ab) +db=db:rep(ab)_c=_c:rep(ab) +for dy=0,bb-1 do local ac=_b+dy +if ac>=1 and ac<=self.height then +self.buffer.text[ac]=ca(self.buffer.text[ac]:sub(1, +da-1)..cb.. +self.buffer.text[ac]:sub(da+#cb),1,self.width) +self.buffer.fg[ac]=ca( +self.buffer.fg[ac]:sub(1,da-1)..db..self.buffer.fg[ac]:sub(da+#db),1,self.width) +self.buffer.bg[ac]=ca( +self.buffer.bg[ac]:sub(1,da-1).._c..self.buffer.bg[ac]:sub(da+#_c),1,self.width)end end;self:addDirtyRect(da,_b,ab,bb)return self end +function ba:textFg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end +bb=_a[bb]or"0"bb=bb:rep(#ab) +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.fg[_b]=ca( +self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:textBg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end +bb=_a[bb]or"f" +self.buffer.text[_b]=ca( +self.buffer.text[_b]:sub(1,da-1).. +ab..self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.bg[_b]=ca( +self.buffer.bg[_b]:sub(1,da-1).. +bb:rep(#ab)..self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, +da-1)..ab.. +self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, +da-1)..ab.. +self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, +da-1)..ab.. +self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, +da-1)..ab.. +self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:clear(da)local _b=_a[da]or"f" +for y=1,self.height do +self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) +self.buffer.bg[y]=string.rep(_b,self.width)self:addDirtyRect(1,y,self.width,1)end;return self end +function ba:render()local da={} +for _b,ab in ipairs(self.buffer.dirtyRects)do local bb=false;for cb,db in ipairs(da)do +if +self:rectOverlaps(ab,db)then self:mergeRects(db,ab)bb=true;break end end;if not bb then +table.insert(da,ab)end end +for _b,ab in ipairs(da)do +for y=ab.y,ab.y+ab.height-1 do +if y>=1 and y<=self.height then +self.terminal.setCursorPos(ab.x,y) +self.terminal.blit(self.buffer.text[y]:sub(ab.x,ab.x+ab.width-1),self.buffer.fg[y]:sub(ab.x, +ab.x+ab.width-1),self.buffer.bg[y]:sub(ab.x, +ab.x+ab.width-1))end end end;self.buffer.dirtyRects={} +if self.blink then +self.terminal.setTextColor(self.cursorColor or +colors.white) +self.terminal.setCursorPos(self.xCursor,self.yCursor)self.terminal.setCursorBlink(true)else +self.terminal.setCursorBlink(false)end;return self end +function ba:rectOverlaps(da,_b)return +not( +da.x+da.width<=_b.x or _b.x+_b.width<=da.x or da.y+da.height<=_b.y or +_b.y+_b.height<=da.y)end +function ba:mergeRects(da,_b)local ab=math.min(da.x,_b.x) +local bb=math.min(da.y,_b.y) +local cb=math.max(da.x+da.width,_b.x+_b.width) +local db=math.max(da.y+da.height,_b.y+_b.height)da.x=ab;da.y=bb;da.width=cb-ab;da.height=db-bb;return self end +function ba:setCursor(da,_b,ab,bb) +if bb~=nil then self.terminal.setTextColor(bb)end;self.terminal.setCursorPos(da,_b) +self.terminal.setCursorBlink(ab)self.xCursor=da;self.yCursor=_b;self.blink=ab;self.cursorColor=bb +return self end +function ba:clearArea(da,_b,ab,bb,cb)local db=_a[cb]or"f" +for dy=0,bb-1 do local _c=_b+dy;if +_c>=1 and _c<=self.height then local ac=string.rep(" ",ab)local bc=string.rep(db,ab) +self:blit(da,_c,ac,"0",db)end end;return self end;function ba:getSize()return self.width,self.height end +function ba:setSize(da,_b) +self.width=da;self.height=_b +for y=1,self.height do +self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) +self.buffer.bg[y]=string.rep("f",self.width)end;return self end;return ba end +project["init.lua"] = function(...) local da={...}local _b=fs.getDir(da[2])local ab=package.path +local bb="path;/path/?.lua;/path/?/init.lua;"local cb=bb:gsub("path",_b)package.path=cb.."rom/?;"..ab +local function db(bc)package.path= +cb.."rom/?"local cc=require("errorManager") +package.path=ab;cc.header="Basalt Loading Error"cc.error(bc)end;local _c,ac=pcall(require,"main")package.loaded.log=nil +package.path=ab;if not _c then db(ac)else return ac end end +project["elements/BaseFrame.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("Container")local da=require("errorManager")local _b=require("render") +local ab=setmetatable({},ca)ab.__index=ab +local function bb(cb) +local db,_c=pcall(function()return peripheral.getType(cb)end)if db then return true end;return false end +ab.defineProperty(ab,"term",{default=nil,type="table",setter=function(cb,db)cb._peripheralName=nil;if +cb.basalt.getActiveFrame(cb._values.term)==cb then +cb.basalt.setActiveFrame(cb,false)end;if +db==nil or db.setCursorPos==nil then return db end;if(bb(db))then +cb._peripheralName=peripheral.getName(db)end;cb._values.term=db +if +cb.basalt.getActiveFrame(db)==nil then cb.basalt.setActiveFrame(cb)end;cb._render=_b.new(db)cb._renderUpdate=true;local _c,ac=db.getSize() +cb.set("width",_c)cb.set("height",ac)return db end})function ab.new()local cb=setmetatable({},ab):__init() +cb.class=ab;return cb end;function ab:init(cb,db) +ca.init(self,cb,db)self.set("term",term.current()) +self.set("type","BaseFrame")return self end +function ab:multiBlit(cb,db,_c,ac,bc,cc,dc)if +(cb<1)then _c=_c+cb-1;cb=1 end;if(db<1)then ac=ac+db-1;db=1 end +self._render:multiBlit(cb,db,_c,ac,bc,cc,dc)end;function ab:textFg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end +self._render:textFg(cb,db,_c,ac)end;function ab:textBg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 - +cb)cb=1 end +self._render:textBg(cb,db,_c,ac)end;function ab:drawText(cb,db,_c)if cb<1 then _c=string.sub(_c, +1 -cb)cb=1 end +self._render:text(cb,db,_c)end +function ab:drawFg(cb,db,_c)if cb<1 then +_c=string.sub(_c,1 -cb)cb=1 end;self._render:fg(cb,db,_c)end;function ab:drawBg(cb,db,_c)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end +self._render:bg(cb,db,_c)end +function ab:blit(cb,db,_c,ac,bc) +if cb<1 then +_c=string.sub(_c,1 -cb)ac=string.sub(ac,1 -cb)bc=string.sub(bc,1 -cb)cb=1 end;self._render:blit(cb,db,_c,ac,bc)end;function ab:setCursor(cb,db,_c,ac)local bc=self.get("term") +self._render:setCursor(cb,db,_c,ac)end +function ab:monitor_touch(cb,db,_c) +local ac=self.get("term")if ac==nil then return end +if(bb(ac))then if self._peripheralName==cb then +self:mouse_click(1,db,_c) +self.basalt.schedule(function()sleep(0.1)self:mouse_up(1,db,_c)end)end end end;function ab:mouse_click(cb,db,_c)ca.mouse_click(self,cb,db,_c) +self.basalt.setFocus(self)end +function ab:mouse_up(cb,db,_c) +ca.mouse_up(self,cb,db,_c)ca.mouse_release(self,cb,db,_c)end +function ab:term_resize()local cb,db=self.get("term").getSize() +if(cb== +self.get("width")and db==self.get("height"))then return end;self.set("width",cb)self.set("height",db) +self._render:setSize(cb,db)self._renderUpdate=true end +function ab:key(cb)self:fireEvent("key",cb)ca.key(self,cb)end +function ab:key_up(cb)self:fireEvent("key_up",cb)ca.key_up(self,cb)end +function ab:char(cb)self:fireEvent("char",cb)ca.char(self,cb)end +function ab:dispatchEvent(cb,...)local db=self.get("term")if db==nil then return end;if(bb(db))then if +cb=="mouse_click"then return end end +ca.dispatchEvent(self,cb,...)end;function ab:render() +if(self._renderUpdate)then if self._render~=nil then ca.render(self) +self._render:render()self._renderUpdate=false end end end +return ab end +project["elements/Timer.lua"] = function(...) local d=require("elementManager") +local _a=d.getElement("BaseElement")local aa=setmetatable({},_a)aa.__index=aa +aa.defineProperty(aa,"interval",{default=1,type="number"}) +aa.defineProperty(aa,"action",{default=function()end,type="function"}) +aa.defineProperty(aa,"running",{default=false,type="boolean"}) +aa.defineProperty(aa,"amount",{default=-1,type="number"})aa.defineEvent(aa,"timer")function aa.new() +local ba=setmetatable({},aa):__init()ba.class=aa;return ba end;function aa:init(ba,ca) +_a.init(self,ba,ca)self.set("type","Timer")end +function aa:start()if +not self.running then self.running=true;local ba=self.get("interval") +self.timerId=os.startTimer(ba)end;return self end +function aa:stop()if self.running then self.running=false +os.cancelTimer(self.timerId)end;return self end +function aa:dispatchEvent(ba,...)_a.dispatchEvent(self,ba,...) +if ba=="timer"then +local ca=select(1,...) +if ca==self.timerId then self.action()local da=self.get("amount")if da>0 then self.set("amount", +da-1)end;if da~=0 then +self.timerId=os.startTimer(self.get("interval"))end end end end;return aa end +project["elements/Program.lua"] = function(...) local ca=require("elementManager") +local da=ca.getElement("VisualElement")local _b=require("errorManager")local ab=setmetatable({},da) +ab.__index=ab +ab.defineProperty(ab,"program",{default=nil,type="table"}) +ab.defineProperty(ab,"path",{default="",type="string"}) +ab.defineProperty(ab,"running",{default=false,type="boolean"}) +ab.defineProperty(ab,"errorCallback",{default=nil,type="function"}) +ab.defineProperty(ab,"doneCallback",{default=nil,type="function"})ab.defineEvent(ab,"*")local bb={}bb.__index=bb +local cb=dofile("rom/modules/main/cc/require.lua").make +function bb.new(_c,ac,bc)local cc=setmetatable({},bb)cc.env=ac or{}cc.args={}cc.addEnvironment= +bc==nil and true or bc;cc.program=_c;return cc end;function bb:setArgs(...)self.args={...}end +local function db(_c) +local ac={shell=shell,multishell=multishell}ac.require,ac.package=cb(ac,_c)return ac end +function bb:run(_c,ac,bc) +self.window=window.create(self.program:getBaseFrame():getTerm(),1,1,ac,bc,false) +local cc=shell.resolveProgram(_c)or fs.exists(_c)and _c or nil +if(cc~=nil)then +if(fs.exists(cc))then local dc=fs.open(cc,"r")local _d=dc.readAll() +dc.close() +local ad=setmetatable(db(fs.getDir(_c)),{__index=_ENV})ad.term=self.window;ad.term.current=term.current +ad.term.redirect=term.redirect;ad.term.native=function()return self.window end +if +(self.addEnvironment)then for __a,a_a in pairs(self.env)do ad[__a]=a_a end else ad=self.env end +self.coroutine=coroutine.create(function()local __a=load(_d,"@/".._c,nil,ad)if __a then +local a_a=__a(table.unpack(self.args))return a_a end end)local bd=term.current()term.redirect(self.window) +local cd,dd=coroutine.resume(self.coroutine)term.redirect(bd) +if not cd then +local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end +local a_a=self.program.get("errorCallback") +if a_a then local b_a=debug.traceback(self.coroutine,dd) +local c_a=a_a(self.program,dd,b_a:gsub(dd,""))if(c_a==false)then self.filter=nil;return cd,dd end end;_b.header="Basalt Program Error ".._c;_b.error(dd)end +if coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)self.program.set("program",nil) +local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end end else _b.header="Basalt Program Error ".._c +_b.error("File not found")end else _b.header="Basalt Program Error" +_b.error("Program ".._c.." not found")end end;function bb:resize(_c,ac)self.window.reposition(1,1,_c,ac) +self:resume("term_resize",_c,ac)end +function bb:resume(_c,...)local ac={...}if +(_c:find("mouse_"))then +ac[2],ac[3]=self.program:getRelativePosition(ac[2],ac[3])end;if self.coroutine==nil or +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)return end +if +(self.filter~=nil)then if(_c~=self.filter)then return end;self.filter=nil end;local bc=term.current()term.redirect(self.window) +local cc,dc=coroutine.resume(self.coroutine,_c,table.unpack(ac))term.redirect(bc) +if cc then self.filter=dc +if +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)self.program.set("program",nil) +local _d=self.program.get("doneCallback")if _d then _d(self.program,cc,dc)end end else local _d=self.program.get("doneCallback")if _d then +_d(self.program,cc,dc)end +local ad=self.program.get("errorCallback") +if ad then local bd=debug.traceback(self.coroutine,dc) +bd=bd==nil and""or bd;dc=dc or"Unknown error" +local cd=ad(self.program,dc,bd:gsub(dc,""))if(cd==false)then self.filter=nil;return cc,dc end end;_b.header="Basalt Program Error"_b.error(dc)end;return cc,dc end +function bb:stop()if self.coroutine==nil or +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)return end +coroutine.close(self.coroutine)self.coroutine=nil end;function ab.new()local _c=setmetatable({},ab):__init() +_c.class=ab;_c.set("z",5)_c.set("width",30)_c.set("height",12) +return _c end +function ab:init(_c,ac) +da.init(self,_c,ac)self.set("type","Program") +self:observe("width",function(bc,cc) +local dc=bc.get("program") +if dc then dc:resize(cc,bc.get("height"))end end) +self:observe("height",function(bc,cc)local dc=bc.get("program")if dc then +dc:resize(bc.get("width"),cc)end end)return self end +function ab:execute(_c,ac,bc,...)self.set("path",_c)self.set("running",true) +local cc=bb.new(self,ac,bc)self.set("program",cc)cc:setArgs(...) +cc:run(_c,self.get("width"),self.get("height"),...)self:updateRender()return self end;function ab:stop()local _c=self.get("program")if _c then _c:stop() +self.set("running",false)self.set("program",nil)end +return self end;function ab:sendEvent(_c,...) +self:dispatchEvent(_c,...)return self end;function ab:onError(_c) +self.set("errorCallback",_c)return self end;function ab:onDone(_c) +self.set("doneCallback",_c)return self end +function ab:dispatchEvent(_c,...) +local ac=self.get("program")local bc=da.dispatchEvent(self,_c,...) +if ac then ac:resume(_c,...) +if +(self:hasState("focused"))then local cc=ac.window.getCursorBlink() +local dc,_d=ac.window.getCursorPos() +self:setCursor(dc,_d,cc,ac.window.getTextColor())end;self:updateRender()end;return bc end +function ab:focus() +if(da.focus(self))then local _c=self.get("program")if _c then +local ac=_c.window.getCursorBlink()local bc,cc=_c.window.getCursorPos() +self:setCursor(bc,cc,ac,_c.window.getTextColor())end end end +function ab:render()da.render(self)local _c=self.get("program") +if _c then +local ac,bc=_c.window.getSize()for y=1,bc do local cc,dc,_d=_c.window.getLine(y)if cc then +self:blit(1,y,cc,dc,_d)end end end end;return ab end +project["elements/Image.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("VisualElement")local da=require("libraries/colorHex") +local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"bimg",{default={{}},type="table",canTriggerRender=true}) +_b.defineProperty(_b,"currentFrame",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"autoResize",{default=false,type="boolean"}) +_b.defineProperty(_b,"offsetX",{default=0,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"offsetY",{default=0,type="number",canTriggerRender=true}) +_b.combineProperties(_b,"offset","offsetX","offsetY") +function _b.new()local cb=setmetatable({},_b):__init() +cb.class=_b;cb.set("width",12)cb.set("height",6) +cb.set("background",colors.black)cb.set("z",5)return cb end;function _b:init(cb,db)ca.init(self,cb,db)self.set("type","Image") +return self end +function _b:resizeImage(cb,db) +local _c=self.get("bimg") +for ac,bc in ipairs(_c)do local cc={} +for y=1,db do local dc=string.rep(" ",cb) +local _d=string.rep("f",cb)local ad=string.rep("0",cb) +if bc[y]and bc[y][1]then local bd=bc[y][1] +local cd=bc[y][2]local dd=bc[y][3] +dc=(bd..string.rep(" ",cb)):sub(1,cb) +_d=(cd..string.rep("f",cb)):sub(1,cb) +ad=(dd..string.rep("0",cb)):sub(1,cb)end;cc[y]={dc,_d,ad}end;_c[ac]=cc end;self:updateRender()return self end +function _b:getImageSize()local cb=self.get("bimg")if not cb[1]or not cb[1][1]then +return 0,0 end;return#cb[1][1][1],#cb[1]end +function _b:getPixelData(cb,db) +local _c=self.get("bimg")[self.get("currentFrame")]if not _c or not _c[db]then return end;local ac=_c[db][1] +local bc=_c[db][2]local cc=_c[db][3] +if not ac or not bc or not cc then return end;local dc=tonumber(bc:sub(cb,cb),16) +local _d=tonumber(cc:sub(cb,cb),16)local ad=ac:sub(cb,cb)return dc,_d,ad end +local function ab(cb,db) +local _c=cb.get("bimg")[cb.get("currentFrame")]if not _c then _c={} +cb.get("bimg")[cb.get("currentFrame")]=_c end +if not _c[db]then _c[db]={"","",""}end;return _c end +local function bb(cb,db,_c)if not cb.get("autoResize")then return end +local ac=cb.get("bimg")local bc=db;local cc=_c +for dc,_d in ipairs(ac)do for ad,bd in pairs(_d)do bc=math.max(bc,#bd[1]) +cc=math.max(cc,ad)end end +for dc,_d in ipairs(ac)do +for y=1,cc do if not _d[y]then _d[y]={"","",""}end;local ad=_d[y]while#ad[1]< +bc do ad[1]=ad[1].." "end;while#ad[2]dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then +bb(self,cb+#_c-1,db)else local cc=#ac[db][1]if cb>cc then return self end +_c=_c:sub(1,cc-cb+1)end +local bc=ac[db][1] +ac[db][1]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end +function _b:getText(cb,db,_c)if not cb or not db then return""end +local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][1]if not bc then +return""end +if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb,cb)end end +function _b:setFg(cb,db,_c)if +type(_c)~="string"or#_c<1 or cb<1 or db<1 then return self end +if +not self.get("autoResize")then local cc,dc=self:getImageSize()if db>dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then +bb(self,cb+#_c-1,db)else local cc=#ac[db][2]if cb>cc then return self end +_c=_c:sub(1,cc-cb+1)end +local bc=ac[db][2] +ac[db][2]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end +function _b:getFg(cb,db,_c)if not cb or not db then return""end +local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][2]if not bc then +return""end +if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb)end end +function _b:setBg(cb,db,_c)if +type(_c)~="string"or#_c<1 or cb<1 or db<1 then return self end +if +not self.get("autoResize")then local cc,dc=self:getImageSize()if db>dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then +bb(self,cb+#_c-1,db)else local cc=#ac[db][3]if cb>cc then return self end +_c=_c:sub(1,cc-cb+1)end +local bc=ac[db][3] +ac[db][3]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end +function _b:getBg(cb,db,_c)if not cb or not db then return""end +local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][3]if not bc then +return""end +if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb)end end +function _b:setPixel(cb,db,_c,ac,bc)if _c then self:setText(cb,db,_c)end;if ac then +self:setFg(cb,db,ac)end;if bc then self:setBg(cb,db,bc)end;return self end +function _b:nextFrame() +if not self.get("bimg").animation then return self end;local cb=self.get("bimg")local db=self.get("currentFrame") +local _c=db+1;if _c>#cb then _c=1 end;self.set("currentFrame",_c)return self end +function _b:addFrame()local cb=self.get("bimg") +local db=cb.width or#cb[1][1][1]local _c=cb.height or#cb[1]local ac={}local bc=string.rep(" ",db) +local cc=string.rep("f",db)local dc=string.rep("0",db)for y=1,_c do ac[y]={bc,cc,dc}end +table.insert(cb,ac)return self end;function _b:updateFrame(cb,db)local _c=self.get("bimg")_c[cb]=db +self:updateRender()return self end;function _b:getFrame(cb) +local db=self.get("bimg") +return db[cb or self.get("currentFrame")]end +function _b:getMetadata()local cb={} +local db=self.get("bimg") +for _c,ac in pairs(db)do if(type(ac)=="string")then cb[_c]=ac end end;return cb end +function _b:setMetadata(cb,db)if(type(cb)=="table")then +for ac,bc in pairs(cb)do self:setMetadata(ac,bc)end;return self end +local _c=self.get("bimg")if(type(db)=="string")then _c[cb]=db end;return self end +function _b:render()ca.render(self) +local cb=self.get("bimg")[self.get("currentFrame")]if not cb then return end;local db=self.get("offsetX") +local _c=self.get("offsetY")local ac=self.get("width")local bc=self.get("height") +for y=1,bc do local cc=y+_c +local dc=cb[cc] +if dc then local _d=dc[1]local ad=dc[2]local bd=dc[3] +if _d and ad and bd then +local cd=ac-math.max(0,db) +if cd>0 then if db<0 then local dd=math.abs(db)+1;_d=_d:sub(dd)ad=ad:sub(dd) +bd=bd:sub(dd)end;_d=_d:sub(1,cd) +ad=ad:sub(1,cd)bd=bd:sub(1,cd) +self:blit(math.max(1,1 +db),y,_d,ad,bd)end end end end end;return _b end +project["elements/BarChart.lua"] = function(...) local aa=require("elementManager") +local ba=aa.getElement("VisualElement")local ca=aa.getElement("Graph") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b;function _b.new() +local ab=setmetatable({},_b):__init()ab.class=_b;return ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","BarChart")return self end +function _b:render()ba.render(self)local ab=self.get("width") +local bb=self.get("height")local cb=self.get("minValue")local db=self.get("maxValue") +local _c=self.get("series")local ac=0;local bc={} +for ad,bd in pairs(_c)do if(bd.visible)then if#bd.data>0 then ac=ac+1 +table.insert(bc,bd)end end end;local cc=ac;local dc=1 +local _d=math.min(bc[1]and bc[1].pointCount or 0,math.floor((ab+dc)/ ( +cc+dc))) +for groupIndex=1,_d do local ad=( (groupIndex-1)* (cc+dc))+1 +for bd,cd in ipairs(bc)do +local dd=cd.data[groupIndex] +if dd then local __a=ad+ (bd-1)local a_a=(dd-cb)/ (db-cb) +local b_a=math.floor(bb- (a_a* (bb-1)))b_a=math.max(1,math.min(b_a,bb))for barY=b_a,bb do +self:blit(__a,barY,cd.symbol,da[cd.fgColor],da[cd.bgColor])end end end end end;return _b end +project["elements/ComboBox.lua"] = function(...) local aa=require("elements/VisualElement") +local ba=require("elements/List")local ca=require("elements/DropDown") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"editable",{default=true,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"text",{default="",type="string",canTriggerRender=true,setter=function(ab,bb)ab.set("cursorPos",#bb+1) +ab:updateViewport()return bb end}) +_b.defineProperty(_b,"cursorPos",{default=1,type="number"}) +_b.defineProperty(_b,"viewOffset",{default=0,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"autoComplete",{default=false,type="boolean"}) +_b.defineProperty(_b,"manuallyOpened",{default=false,type="boolean"})function _b.new()local ab=setmetatable({},_b):__init() +ab.class=_b;ab.set("width",16)ab.set("height",1)ab.set("z",8) +return ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","ComboBox") +self.set("cursorPos",1)self.set("viewOffset",0)return self end +function _b:getFilteredItems()local ab=self.get("items")or{} +local bb=self.get("text"):lower() +if not self.get("autoComplete")or#bb==0 then return ab end;local cb={} +for db,_c in ipairs(ab)do local ac="" +if type(_c)=="string"then ac=_c:lower()elseif +type(_c)=="table"and _c.text then ac=_c.text:lower()end;if ac:find(bb,1,true)then table.insert(cb,_c)end end;return cb end +function _b:updateFilteredDropdown() +if not self.get("autoComplete")then return end;local ab=self:getFilteredItems()local bb=#ab>0 and +#self.get("text")>0 +if bb then self:setState("opened") +self.set("manuallyOpened",false)local cb=self.get("dropdownHeight")or 5 +local db=math.min(cb,#ab)self.set("height",1 +db)else +self:unsetState("opened")self.set("manuallyOpened",false) +self.set("height",1)end;self:updateRender()end +function _b:updateViewport()local ab=self.get("text") +local bb=self.get("cursorPos")local cb=self.get("width")local db=self.get("dropSymbol") +local _c=cb-#db;if _c<1 then _c=1 end;local ac=self.get("viewOffset")if bb-ac>_c then ac=bb-_c elseif +bb-1 1 then local _c=cb:sub(1,db-2).. +cb:sub(db)self.set("text",_c) +self.set("cursorPos",db-1)self:updateViewport()if self.get("autoComplete")then +self:updateFilteredDropdown()else self:updateRender()end end elseif ab==keys.delete then +if db<=#cb then +local _c=cb:sub(1,db-1)..cb:sub(db+1)self.set("text",_c)self:updateViewport() +if +self.get("autoComplete")then self:updateFilteredDropdown()else self:updateRender()end end elseif ab==keys.home then self.set("cursorPos",1) +self:updateViewport()elseif ab==keys["end"]then self.set("cursorPos",#cb+1) +self:updateViewport()elseif ab==keys.enter then +if self:hasState("opened")then +self:unsetState("opened")else self:setState("opened")end;self:updateRender()end end +function _b:mouse_click(ab,bb,cb) +if not aa.mouse_click(self,ab,bb,cb)then return false end;local db,_c=self:getRelativePosition(bb,cb) +local ac=self.get("width")local bc=self.get("dropSymbol") +local cc=self:hasState("opened") +if _c==1 then +if db>=ac-#bc+1 and db<=ac then +if cc then +self:unsetState("opened")self.set("height",1) +self.set("manuallyOpened",false)else self:setState("opened") +local dc=self.get("items")or{}local _d=self.get("dropdownHeight")or 5 +local ad=math.min(_d,#dc)self.set("height",1 +ad) +self.set("manuallyOpened",true)end;self:updateRender()return true end +if db<=ac-#bc and self.get("editable")then +local dc=self.get("text")local _d=self.get("viewOffset")local ad=#dc+1 +local bd=math.min(ad,_d+db)self.set("cursorPos",bd) +if not cc then +self:setState("opened")local cd=self.get("items")or{} +local dd=self.get("dropdownHeight")or 5;local __a=math.min(dd,#cd)self.set("height",1 +__a) +self.set("manuallyOpened",true)end;self:updateRender()return true end;return true elseif cc and _c>1 then return ca.mouse_click(self,ab,bb,cb)end;return false end +function _b:mouse_up(ab,bb,cb) +if self:hasState("opened")then +local db,_c=self:getRelativePosition(bb,cb) +if +_c>1 and self.get("selectable")and not self._scrollBarDragging then local ac=(_c-1)+self.get("offset")local bc +if +self.get("autoComplete")and not self.get("manuallyOpened")then +bc=self:getFilteredItems()else bc=self.get("items")end +if ac<=#bc then local cc=bc[ac] +if type(cc)=="string"then cc={text=cc}bc[ac]=cc end;if not self.get("multiSelection")then +for dc,_d in +ipairs(self.get("items"))do if type(_d)=="table"then _d.selected=false end end end +cc.selected=true +if cc.text then self.set("text",cc.text) +self.set("cursorPos",#cc.text+1)self:updateViewport()end;if cc.callback then cc.callback(self)end +self:fireEvent("select",ac,cc)self:unsetState("opened") +self:unsetState("clicked")self.set("height",1) +self.set("manuallyOpened",false)self:updateRender()return true end end;return ca.mouse_up(self,ab,bb,cb)end;return +aa.mouse_up and aa.mouse_up(self,ab,bb,cb)or false end +function _b:render()aa.render(self)local ab=self.get("text") +local bb=self.get("width")local cb=self.get("dropSymbol") +local db=self:hasState("focused")local _c=self:hasState("opened") +local ac=self.get("viewOffset")local bc=self.getResolved("selectedText") +local cc=self.getResolved("background")local dc=self.getResolved("foreground")local _d=ab;local ad=bb-#cb +if +#ab==0 and not db and#bc>0 then _d=bc;dc=colors.gray end;if#_d>0 then _d=_d:sub(ac+1,ac+ad)end;_d=_d.. +string.rep(" ",ad-#_d) +local bd=_d.. (_c and"\31"or"\17") +self:blit(1,1,bd,string.rep(da[dc],bb),string.rep(da[cc],bb))if db and self.get("editable")then local cd=self.get("cursorPos") +local dd=cd-ac +if dd>=1 and dd<=ad then self:setCursor(dd,1,true,dc)end end +if _c then +local cd=self.get("height")local dd=self.get("items")if self.get("autoComplete")and not +self.get("manuallyOpened")then +dd=self:getFilteredItems()end;local __a=math.min(self.get("dropdownHeight"), +#dd) +local a_a=self._values.items;self._values.items=dd;self.set("height",__a) +ba.render(self,1)self._values.items=a_a;self.set("height",cd) +self:blit(1,1,bd,string.rep(da[dc],bb),string.rep(da[cc],bb))if db and self.get("editable")then local b_a=self.get("cursorPos")local c_a=b_a- +ac +if c_a>=1 and c_a<=ad then self:setCursor(c_a,1,true,dc)end end end end;return _b end +project["elements/ScrollFrame.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("Container")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarBackgroundSymbol",{default="\127",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"scrollBarBackgroundColor2",{default=colors.black,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"contentWidth",{default=0,type="number",getter=function(da)local _b=0;local ab=da.get("children") +for bb,cb in ipairs(ab)do +local db=cb.get("x")local _c=cb.get("width")local ac=db+_c-1;if ac>_b then _b=ac end end;return _b end}) +ca.defineProperty(ca,"contentHeight",{default=0,type="number",getter=function(da)local _b=0;local ab=da.get("children") +for bb,cb in ipairs(ab)do +local db=cb.get("y")local _c=cb.get("height")local ac=db+_c-1;if ac>_b then _b=ac end end;return _b end})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_drag")ca.defineEvent(ca,"mouse_up") +ca.defineEvent(ca,"mouse_scroll")function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",20)da.set("height",10)da.set("z",5) +return da end +function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","ScrollFrame")return self end +function ca:mouse_click(da,_b,ab) +if aa.mouse_click(self,da,_b,ab)then +local bb,cb=self:getRelativePosition(_b,ab)local db=self.get("width")local _c=self.get("height") +local ac=self.get("showScrollBar")local bc=self.get("contentWidth") +local cc=self.get("contentHeight")local dc=ac and bc>db;local _d=dc and _c-1 or _c +local ad=ac and cc>_d;local bd=ad and db-1 or db +if +ad and bb==db and(not dc or cb<_c)then local cd=_d +local dd=math.max(1,math.floor((_d/cc)*cd))local __a=cc-_d;local a_a= +__a>0 and(self.get("offsetY")/__a*100)or 0;local b_a= +math.floor((a_a/100)* (cd-dd))+1 +if cb>=b_a and cb0 and(self.get("offsetX")/__a*100)or 0;local b_a= +math.floor((a_a/100)* (cd-dd))+1 +if bb>=b_a and bbbc;local dc=cc and db-1 or db;local _d=dc +local ad=math.max(1,math.floor((dc/ac)*_d))local bd=ac-dc;cb=math.max(1,math.min(_d,cb))local cd=cb- ( +self._scrollBarDragOffset or 0)local dd= +( (cd-1)/ (_d-ad))*100 +local __a=math.floor((dd/100)*bd+0.5) +self.set("offsetY",math.max(0,math.min(bd,__a)))return true end +if self._hScrollBarDragging then local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("width")local _c=self.get("contentWidth") +local ac=self.get("contentHeight")local bc=self.get("height") +local cc=self.get("showScrollBar")and _c>db;local dc=cc and bc-1 or bc +local _d=self.get("showScrollBar")and ac>dc;local ad=_d and db-1 or db;local bd=ad +local cd=math.max(1,math.floor((ad/_c)*bd))local dd=_c-ad;bb=math.max(1,math.min(bd,bb))local __a=bb- ( +self._hScrollBarDragOffset or 0)local a_a= +( (__a-1)/ (bd-cd))*100 +local b_a=math.floor((a_a/100)*dd+0.5) +self.set("offsetX",math.max(0,math.min(dd,b_a)))return true end;return +aa.mouse_drag and aa.mouse_drag(self,da,_b,ab)or false end +function ca:mouse_up(da,_b,ab)if self._scrollBarDragging then self._scrollBarDragging=false +self._scrollBarDragOffset=nil;return true end +if self._hScrollBarDragging then +self._hScrollBarDragging=false;self._hScrollBarDragOffset=nil;return true end;return +aa.mouse_up and aa.mouse_up(self,da,_b,ab)or false end +function ca:mouse_scroll(da,_b,ab) +if self:isInBounds(_b,ab)then +local bb,cb=self.get("offsetX"),self.get("offsetY")local db,_c=self:getRelativePosition(_b+bb,ab+cb) +local ac,bc=self:callChildrenEvent(true,"mouse_scroll",da,db,_c)if ac then return true end;local cc=self.get("height") +local dc=self.get("width")local _d=self.get("offsetY")local ad=self.get("offsetX") +local bd=self.get("contentWidth")local cd=self.get("contentHeight") +local dd=self.get("showScrollBar")and bd>dc;local __a=dd and cc-1 or cc +local a_a=self.get("showScrollBar")and cd>__a;local b_a=a_a and dc-1 or dc +if a_a then local c_a=math.max(0,cd-__a)local d_a=math.min(c_a,math.max(0, +_d+da)) +self.set("offsetY",d_a)elseif dd then local c_a=math.max(0,bd-b_a) +local d_a=math.min(c_a,math.max(0,ad+da))self.set("offsetX",d_a)end;return true end;return false end +function ca:render()aa.render(self)local da=self.get("height") +local _b=self.get("width")local ab=self.get("offsetY")local bb=self.get("offsetX") +local cb=self.get("showScrollBar")local db=self.get("contentWidth") +local _c=self.get("contentHeight")local ac=cb and db>_b;local bc=ac and da-1 or da +local cc=cb and _c>bc;local dc=cc and _b-1 or _b +if cc then local _d=bc +local ad=math.max(1,math.floor((bc/_c)*_d))local bd=_c-bc;local cd=self.get("scrollBarBackgroundSymbol") +local dd=self.get("scrollBarColor")local __a=self.get("scrollBarBackgroundColor") +local a_a=self.get("scrollBarBackgroundColor2")local b_a=bd>0 and(ab/bd*100)or 0;local c_a= +math.floor((b_a/100)* (_d-ad))+1;for i=1,_d do +if i>=c_a and i0 and(bb/bd*100)or 0;local c_a= +math.floor((b_a/100)* (_d-ad))+1;for i=1,_d do +if i>=c_a and i0 then cb._tabId=1;self:updateTabVisibility()end end;return self end;function bb:updateTabVisibility()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)end +function bb:setActiveTab(cb) +local db=self.get("activeTab")if db==cb then return self end;self.set("activeTab",cb) +self:updateTabVisibility()self:dispatchEvent("tabChanged",cb,db)return self end +function bb:isChildVisible(cb) +if not da.isChildVisible(self,cb)then return false end +if cb._tabId then return cb._tabId==self.get("activeTab")end;return true end +function bb:getContentYOffset()local cb=self:_getHeaderMetrics()return cb.headerHeight end +function bb:_getHeaderMetrics()local cb=self.get("tabs")or{} +local db=self.get("width")or 1;local _c=self.get("tabHeight")or 1 +local ac=self.get("scrollableTab")local bc={} +if ac then local cc=self.get("tabScrollOffset")or 0 +local dc=1;local _d=0 +for ad,bd in ipairs(cb)do local cd=#bd.title+2;if cd>db then cd=db end;local dd=dc-cc +local __a=0;local a_a=0;if dd<1 then __a=1 -dd end +if dd+cd-1 >db then a_a=(dd+cd-1)-db end +if dd+cd>1 and dd<=db then local b_a=math.max(1,dd)local c_a=cd-__a-a_a +table.insert(bc,{id=bd.id,title=bd.title,line=1,x1=b_a,x2= +b_a+c_a-1,width=cd,displayWidth=c_a,actualX=dc,startClip=__a,endClip=a_a})end;dc=dc+cd end;_d=dc-1;return +{headerHeight=1,lines=1,positions=bc,totalWidth=_d,scrollOffset=cc,maxScroll=math.max(0,_d-db)}else local cc=1;local dc=1 +for bd,cd in ipairs(cb)do local dd=# +cd.title+2;if dd>db then dd=db end +if dc+dd-1 >db then cc=cc+1;dc=1 end +table.insert(bc,{id=cd.id,title=cd.title,line=cc,x1=dc,x2=dc+dd-1,width=dd})dc=dc+dd end;local _d=cc;local ad=math.max(_c,_d) +return{headerHeight=ad,lines=_d,positions=bc}end end +function bb:mouse_click(cb,db,_c) +if not ca.mouse_click(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) +local cc=self:_getHeaderMetrics() +if bc<=cc.headerHeight then if#cc.positions==0 then return true end +for dc,_d in +ipairs(cc.positions)do +if _d.line==bc and ac>=_d.x1 and ac<=_d.x2 then +self:setActiveTab(_d.id)self.set("focusedChild",nil)return true end end;return true end;return da.mouse_click(self,cb,db,_c)end +function bb:getRelativePosition(cb,db) +local _c=self:_getHeaderMetrics().headerHeight +if cb==nil or db==nil then return ca.getRelativePosition(self)else +local ac,bc=ca.getRelativePosition(self,cb,db)return ac,bc-_c end end +function bb:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d=self:_getHeaderMetrics().headerHeight;return da.multiBlit(self,cb,( +db or 1)+_d,_c,ac,bc,cc,dc)end +function bb:textFg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textFg(self,cb,( +db or 1)+bc,_c,ac)end +function bb:textBg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textBg(self,cb,( +db or 1)+bc,_c,ac)end +function bb:drawText(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawText(self,cb,( +db or 1)+ac,_c)end +function bb:drawFg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawFg(self,cb,( +db or 1)+ac,_c)end +function bb:drawBg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawBg(self,cb,( +db or 1)+ac,_c)end +function bb:blit(cb,db,_c,ac,bc)local cc=self:_getHeaderMetrics().headerHeight;return da.blit(self,cb,( +db or 1)+cc,_c,ac,bc)end +function bb:mouse_up(cb,db,_c) +if not ca.mouse_up(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) +local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then return true end;return da.mouse_up(self,cb,db,_c)end +function bb:mouse_release(cb,db,_c)ca.mouse_release(self,cb,db,_c) +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight +if bc<=cc then return end;return da.mouse_release(self,cb,db,_c)end +function bb:mouse_move(cb,db,_c) +if ca.mouse_move(self,cb,db,_c)then +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then +return true end +local dc={self:getRelativePosition(db,_c)} +local _d,ad=self:callChildrenEvent(true,"mouse_move",table.unpack(dc))if _d then return true end end;return false end +function bb:mouse_drag(cb,db,_c) +if ca.mouse_drag(self,cb,db,_c)then +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then +return true end;return da.mouse_drag(self,cb,db,_c)end;return false end +function bb:scrollTabs(cb) +if not self.get("scrollableTab")then return self end;local db=self:_getHeaderMetrics() +local _c=self.get("tabScrollOffset")or 0;local ac=db.maxScroll or 0;local bc=_c+ (cb*5) +bc=math.max(0,math.min(ac,bc))self.set("tabScrollOffset",bc)return self end +function bb:mouse_scroll(cb,db,_c) +if ca.mouse_scroll(self,cb,db,_c)then +local ac=self:_getHeaderMetrics().headerHeight;if self.get("scrollableTab")and _c==self.get("y")then +self:scrollTabs(cb)return true end;return +da.mouse_scroll(self,cb,db,_c)end;return false end +function bb:setCursor(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight +if +self.parent then local cc,dc=self:calculatePosition()local _d=cb+cc-1 +local ad=db+dc-1 +bc +if + +(_d<1)or(_d>self.parent.get("width"))or(ad<1)or(ad>self.parent.get("height"))then return self.parent:setCursor(_d,ad,false)end;return self.parent:setCursor(_d,ad,_c,ac)end;return self end +function bb:render()ca.render(self)local cb=self.get("width") +local db=self:_getHeaderMetrics()local _c=db.headerHeight or 1 +ca.multiBlit(self,1,1,cb,_c," ",_b[self.get("foreground")],_b[self.get("headerBackground")])local ac=self.get("activeTab") +for bc,cc in ipairs(db.positions)do +local dc=(cc.id==ac)and +self.get("activeTabBackground")or self.get("headerBackground")local _d=(cc.id==ac)and self.get("activeTabTextColor")or +self.get("foreground") +ca.multiBlit(self,cc.x1,cc.line, +cc.displayWidth or(cc.x2 -cc.x1 +1),1," ",_b[self.get("foreground")],_b[dc])local ad=cc.title;local bd=1 + (cc.startClip or 0) +local cd=#cc.title- (cc.startClip or +0)- (cc.endClip or 0)if cd>0 then ad=cc.title:sub(bd,bd+cd-1)local dd=cc.x1;if +(cc.startClip or 0)==0 then dd=dd+1 end +ca.textFg(self,dd,cc.line,ad,_d)end end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(bc)end end +for bc,cc in ipairs(self.get("visibleChildren")or{})do if cc==self then +error("CIRCULAR REFERENCE DETECTED!")return end;cc:render()cc:postRender()end end +function bb:sortChildrenEvents(cb) +local db=self._values.childrenEvents and self._values.childrenEvents[cb] +if db then local _c={}for ac,bc in ipairs(db)do +if self:isChildVisible(bc)then table.insert(_c,bc)end end +for i=2,#_c do local ac=_c[i] +local bc=ac.get("z")local cc=i-1 +while cc>0 do local dc=_c[cc].get("z")if dc>bc then _c[cc+1]=_c[cc] +cc=cc-1 else break end end;_c[cc+1]=ac end +self._values.visibleChildrenEvents=self._values.visibleChildrenEvents or{}self._values.visibleChildrenEvents[cb]=_c end;self.set("childrenEventsSorted",true)return self end;return bb end +project["elements/TextBox.lua"] = function(...) local b_a=require("elements/VisualElement") +local c_a=require("libraries/colorHex")local d_a=setmetatable({},b_a)d_a.__index=d_a +d_a.defineProperty(d_a,"lines",{default={""},type="table",canTriggerRender=true}) +d_a.defineProperty(d_a,"cursorX",{default=1,type="number"}) +d_a.defineProperty(d_a,"cursorY",{default=1,type="number"}) +d_a.defineProperty(d_a,"scrollX",{default=0,type="number",canTriggerRender=true}) +d_a.defineProperty(d_a,"scrollY",{default=0,type="number",canTriggerRender=true}) +d_a.defineProperty(d_a,"editable",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"syntaxPatterns",{default={},type="table"}) +d_a.defineProperty(d_a,"cursorColor",{default=nil,type="color"}) +d_a.defineProperty(d_a,"autoPairEnabled",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoPairCharacters",{default={["("]=")",["["]="]",["{"]="}",['"']='"',['\'']='\'',['`']='`'},type="table"}) +d_a.defineProperty(d_a,"autoPairSkipClosing",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoPairOverType",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoPairNewlineIndent",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoCompleteEnabled",{default=false,type="boolean"}) +d_a.defineProperty(d_a,"autoCompleteItems",{default={},type="table"}) +d_a.defineProperty(d_a,"autoCompleteProvider",{default=nil,type="function",allowNil=true}) +d_a.defineProperty(d_a,"autoCompleteMinChars",{default=1,type="number"}) +d_a.defineProperty(d_a,"autoCompleteMaxItems",{default=6,type="number"}) +d_a.defineProperty(d_a,"autoCompleteCaseInsensitive",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoCompleteTokenPattern",{default="[%w_]+",type="string"}) +d_a.defineProperty(d_a,"autoCompleteOffsetX",{default=0,type="number"}) +d_a.defineProperty(d_a,"autoCompleteOffsetY",{default=1,type="number"}) +d_a.defineProperty(d_a,"autoCompleteZOffset",{default=1,type="number"}) +d_a.defineProperty(d_a,"autoCompleteMaxWidth",{default=0,type="number"}) +d_a.defineProperty(d_a,"autoCompleteShowBorder",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoCompleteBorderColor",{default=colors.black,type="color"}) +d_a.defineProperty(d_a,"autoCompleteBackground",{default=colors.lightGray,type="color"}) +d_a.defineProperty(d_a,"autoCompleteForeground",{default=colors.black,type="color"}) +d_a.defineProperty(d_a,"autoCompleteSelectedBackground",{default=colors.gray,type="color"}) +d_a.defineProperty(d_a,"autoCompleteSelectedForeground",{default=colors.white,type="color"}) +d_a.defineProperty(d_a,"autoCompleteAcceptOnEnter",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoCompleteAcceptOnClick",{default=true,type="boolean"}) +d_a.defineProperty(d_a,"autoCompleteCloseOnEscape",{default=true,type="boolean"})d_a.defineEvent(d_a,"mouse_click") +d_a.defineEvent(d_a,"key")d_a.defineEvent(d_a,"char") +d_a.defineEvent(d_a,"mouse_scroll")d_a.defineEvent(d_a,"paste") +d_a.defineEvent(d_a,"auto_complete_open")d_a.defineEvent(d_a,"auto_complete_close") +d_a.defineEvent(d_a,"auto_complete_accept")local _aa;local aaa;local function baa(c_b)local d_b=c_b._autoCompleteFrame +return +d_b and not d_b._destroyed and d_b.get and d_b.get("visible")end +local function caa(c_b)return +c_b.get("autoCompleteShowBorder")and 1 or 0 end +local function daa(c_b)local d_b=c_b._autoCompleteFrame;local _ab=c_b._autoCompleteList;if +not d_b or d_b._destroyed then return end +d_b:setBackground(c_b.get("autoCompleteBackground")) +d_b:setForeground(c_b.get("autoCompleteForeground")) +if _ab and not _ab._destroyed then +_ab:setBackground(c_b.get("autoCompleteBackground")) +_ab:setForeground(c_b.get("autoCompleteForeground")) +_ab:setSelectedBackground(c_b.get("autoCompleteSelectedBackground")) +_ab:setSelectedForeground(c_b.get("autoCompleteSelectedForeground"))_ab:updateRender()end;aaa(c_b)_aa(c_b)d_b:updateRender()end +local function _ba(c_b,d_b,_ab)local aab=c_b._autoCompleteList +if not aab or aab._destroyed then return end;local bab=aab.get("items")local cab=#bab;if cab==0 then return end +if d_b<1 then d_b=1 end;if d_b>cab then d_b=cab end;c_b._autoCompleteIndex=d_b +for abb,bbb in ipairs(bab)do if +type(bbb)=="table"then bbb.selected=(abb==d_b)end end;local dab=aab.get("height")or 0 +local _bb=aab.get("offset")or 0;if not _ab and dab>0 then +if d_b>_bb+dab then +aab:setOffset(math.max(0,d_b-dab))elseif d_b<=_bb then aab:setOffset(math.max(0,d_b-1))end end +aab:updateRender()end +local function aba(c_b,d_b)if baa(c_b)then +c_b._autoCompleteFrame:setVisible(false) +if not d_b then c_b:fireEvent("auto_complete_close")end end +c_b._autoCompleteIndex=nil;c_b._autoCompleteSuggestions=nil;c_b._autoCompleteToken=nil +c_b._autoCompleteTokenStart=nil;c_b._autoCompletePopupWidth=nil end +local function bba(c_b,d_b)local _ab=c_b._autoCompleteSuggestions or{} +local aab=c_b._autoCompleteIndex or 1;local bab=d_b or _ab[aab]if not bab then return end +local cab=bab.insert or bab.text or""if cab==""then return end;local dab=c_b.get("lines") +local _bb=c_b.get("cursorY")local abb=c_b.get("cursorX")local bbb=dab[_bb]or"" +local cbb=c_b._autoCompleteTokenStart or abb;if cbb<1 then cbb=1 end;local dbb=bbb:sub(1,cbb-1)local _cb=bbb:sub(abb)dab[_bb]= +dbb..cab.._cb;c_b.set("cursorX",cbb+#cab) +c_b:updateViewport()c_b:updateRender()aba(c_b,true) +c_b:fireEvent("auto_complete_accept",cab,bab.source or bab)end +local function cba(c_b) +if not c_b.get("autoCompleteEnabled")then return nil end;local d_b=c_b._autoCompleteFrame;if d_b and not d_b._destroyed then +return c_b._autoCompleteList end;local _ab=c_b:getBaseFrame()if not _ab or not +_ab.addFrame then return nil end +d_b=_ab:addFrame({width=c_b.get("width"),height=1,x=1,y=1,visible=false,background=c_b.get("autoCompleteBackground"),foreground=c_b.get("autoCompleteForeground"),ignoreOffset=true,z= +c_b.get("z")+c_b.get("autoCompleteZOffset")})d_b:setIgnoreOffset(true)d_b:setVisible(false) +local aab=caa(c_b) +local bab=d_b:addList({x=aab+1,y=aab+1,width=math.max(1,d_b.get("width")-aab*2),height=math.max(1, +d_b.get("height")-aab*2),selectable=true,multiSelection=false,background=c_b.get("autoCompleteBackground"),foreground=c_b.get("autoCompleteForeground")}) +bab:setSelectedBackground(c_b.get("autoCompleteSelectedBackground")) +bab:setSelectedForeground(c_b.get("autoCompleteSelectedForeground"))bab:setOffset(0) +bab:onSelect(function(cab,dab,_bb)if not baa(c_b)then return end +_ba(c_b,dab) +if c_b.get("autoCompleteAcceptOnClick")then bba(c_b,_bb)end end)c_b._autoCompleteFrame=d_b;c_b._autoCompleteList=bab;daa(c_b)return bab end +aaa=function(c_b,d_b,_ab)local aab=c_b._autoCompleteFrame;local bab=c_b._autoCompleteList +if +not aab or aab._destroyed or not bab or bab._destroyed then return end;local cab=caa(c_b) +local dab= +tonumber(d_b)or rawget(c_b,"_autoCompletePopupWidth")or bab.get("width")or aab.get("width") +local _bb=tonumber(_ab)or(bab.get and bab.get("height"))or(# ( +rawget(c_b,"_autoCompleteSuggestions")or{}))dab=math.max(1,dab or 1)_bb=math.max(1,_bb or 1)local abb= +aab.get and aab.get("width")or dab;local bbb= +aab.get and aab.get("height")or _bb;local cbb=math.max(1, +abb-cab*2) +local dbb=math.max(1,bbb-cab*2)if dab>cbb then dab=cbb end;if _bb>dbb then _bb=dbb end +bab:setPosition(cab+1,cab+1)bab:setWidth(math.max(1,dab)) +bab:setHeight(math.max(1,_bb))end +_aa=function(c_b)local d_b=c_b._autoCompleteFrame +if not d_b or d_b._destroyed then return end;local _ab=d_b.get and d_b.get("canvas") +if not _ab then return end;_ab:setType("post") +if d_b._autoCompleteBorderCommand then +_ab:removeCommand(d_b._autoCompleteBorderCommand)d_b._autoCompleteBorderCommand=nil end;if not c_b.get("autoCompleteShowBorder")then +d_b:updateRender()return end;local aab=c_b.get("autoCompleteBorderColor")or +colors.black +local bab=_ab:addCommand(function(cab)local dab= +cab.get("width")or 0;local _bb=cab.get("height")or 0;if dab<1 or +_bb<1 then return end +local abb=cab.get("background")or colors.black;local bbb=c_a[abb]or c_a[colors.black]local cbb=c_a[aab]or +c_a[colors.black] +cab:textFg(1,1,("\131"):rep(dab),aab)cab:multiBlit(1,_bb,dab,1,"\143",bbb,cbb) +cab:multiBlit(1,1,1,_bb,"\149",cbb,bbb)cab:multiBlit(dab,1,1,_bb,"\149",bbb,cbb) +cab:blit(1,1,"\151",cbb,bbb)cab:blit(dab,1,"\148",bbb,cbb) +cab:blit(1,_bb,"\138",bbb,cbb)cab:blit(dab,_bb,"\133",bbb,cbb)end)d_b._autoCompleteBorderCommand=bab;d_b:updateRender()end +local function dba(c_b)local d_b=c_b.get("lines")local _ab=c_b.get("cursorY") +local aab=c_b.get("cursorX")local bab=d_b[_ab]or"" +local cab=bab:sub(1,math.max(aab-1,0)) +local dab=c_b.get("autoCompleteTokenPattern")or"[%w_]+"local _bb=""if dab~=""then +_bb=cab:match("("..dab..")$")or""end;local abb=aab-#_bb;if abb<1 then abb=1 end;return _bb,abb end +local function _ca(c_b) +if type(c_b)=="string"then return{text=c_b,insert=c_b,source=c_b}elseif +type(c_b)=="table"then local d_b= +c_b.text or c_b.label or c_b.value or c_b.insert or c_b[1]if not d_b then return +nil end +local _ab={text=d_b,insert=c_b.insert or c_b.value or d_b,source=c_b}if c_b.foreground then _ab.foreground=c_b.foreground end;if +c_b.background then _ab.background=c_b.background end;if c_b.selectedForeground then +_ab.selectedForeground=c_b.selectedForeground end;if c_b.selectedBackground then +_ab.selectedBackground=c_b.selectedBackground end +if c_b.icon then _ab.icon=c_b.icon end;if c_b.info then _ab.info=c_b.info end;return _ab end end +local function aca(c_b,d_b)if type(c_b)~="table"then return end;local _ab=#c_b +if _ab>0 then for index=1,_ab do +d_b(c_b[index])end else for aab,bab in pairs(c_b)do d_b(bab)end end end +local function bca(c_b,d_b)local _ab=c_b.get("autoCompleteProvider")local aab={} +if _ab then +local abb,bbb=pcall(_ab,c_b,d_b)if abb and type(bbb)=="table"then aab=bbb end else aab= +c_b.get("autoCompleteItems")or{}end;local bab={}local cab=c_b.get("autoCompleteCaseInsensitive")local dab=cab and +d_b:lower()or d_b +aca(aab,function(abb)local bbb=_ca(abb) +if bbb and bbb.text then +local cbb= +cab and bbb.text:lower()or bbb.text;if dab==""or cbb:find(dab,1,true)==1 then +table.insert(bab,bbb)end end end)local _bb=c_b.get("autoCompleteMaxItems")if#bab>_bb then while#bab>_bb do +table.remove(bab)end end;return bab end +local function cca(c_b,d_b)local _ab=0 +for _bb,abb in ipairs(d_b)do local bbb=abb;if type(abb)=="table"then +bbb= +abb.text or abb.label or abb.value or abb.insert or abb[1]end;if bbb~=nil then +local cbb=#tostring(bbb)if cbb>_ab then _ab=cbb end end end;local aab=c_b.get("autoCompleteMaxWidth") +local bab=c_b.get("width")if aab and aab>0 then bab=math.min(bab,aab)end +local cab=caa(c_b)local dab=c_b:getBaseFrame() +if dab and dab.get then +local _bb=dab.get("width")if _bb and _bb>0 then local abb=_bb-cab*2;if abb<1 then abb=1 end +bab=math.min(bab,abb)end end;_ab=math.min(_ab,bab)return math.max(1,_ab)end +local function dca(c_b,d_b,_ab)local aab=c_b._autoCompleteFrame;local bab=c_b._autoCompleteList;if +not aab or aab._destroyed then return end;local cab=caa(c_b) +local dab=math.max(1,_ab or c_b.get("width"))local _bb=math.max(1,d_b or 1)local abb=c_b:getBaseFrame()if not abb then +return end;local bbb=abb.get and abb.get("width")local cbb=abb.get and +abb.get("height") +if bbb and bbb>0 then local bac=bbb-cab*2;if bac<1 then +bac=1 end;if dab>bac then dab=bac end end;if cbb and cbb>0 then local bac=cbb-cab*2;if bac<1 then bac=1 end +if _bb>bac then _bb=bac end end;local dbb=dab+cab*2 +local _cb=_bb+cab*2;local acb,bcb=c_b:calculatePosition() +local ccb=c_b.get("scrollX")or 0;local dcb=c_b.get("scrollY")or 0;local _db=(c_b._autoCompleteTokenStart or +c_b.get("cursorX"))local adb=_db-ccb +adb=math.max(1,math.min(c_b.get("width"),adb))local bdb=c_b.get("cursorY")-dcb +bdb=math.max(1,math.min(c_b.get("height"),bdb))local cdb=c_b.get("autoCompleteOffsetX") +local ddb=c_b.get("autoCompleteOffsetY")local __c=acb+adb-1 +cdb;local a_c=__c-cab +if cab>0 then a_c=a_c+1 end;local b_c=bcb+bdb+ddb;local c_c=bcb+bdb-ddb-1;local d_c=b_c-cab;local _ac= +c_c-_bb+1 -cab;local aac=d_c +if bbb and bbb>0 then if dbb>bbb then dbb=bbb +dab=math.max(1,dbb-cab*2)end;if a_c+dbb-1 >bbb then +a_c=math.max(1,bbb-dbb+1)end;if a_c<1 then a_c=1 end else if a_c<1 then a_c=1 end end +if cbb and cbb>0 then +if aac+_cb-1 >cbb then aac=_ac;if cab>0 then aac=aac-cab end;if +aac<1 then aac=math.max(1,cbb-_cb+1)end end;if aac<1 then aac=1 end else if aac<1 then aac=1 end;if aac==_ac and cab>0 then +aac=math.max(1,aac-cab)end end;aab:setPosition(a_c,aac)aab:setWidth(dbb) +aab:setHeight(_cb) +aab:setZ(c_b.get("z")+c_b.get("autoCompleteZOffset"))aaa(c_b,dab,_bb)if bab and not bab._destroyed then +bab:updateRender()end;aab:updateRender()end +local function _da(c_b) +if not c_b.get("autoCompleteEnabled")then aba(c_b,true)return end +if not c_b:hasState("focused")then aba(c_b,true)return end;local d_b,_ab=dba(c_b)c_b._autoCompleteToken=d_b +c_b._autoCompleteTokenStart=_ab +if#d_b=1 and bbb<=dab then +_ba(c_b,bbb)else _ab:updateRender()end;return true end +function d_a.new()local c_b=setmetatable({},d_a):__init() +c_b.class=d_a;c_b.set("width",20)c_b.set("height",10)return c_b end +function d_a:init(c_b,d_b)b_a.init(self,c_b,d_b) +self.set("type","TextBox") +local function _ab()if +self.get("autoCompleteEnabled")and self:hasState("focused")then _da(self)end end;local function aab()daa(self)end +local function bab() +if baa(self)then +local cab=rawget(self,"_autoCompleteSuggestions")or{} +dca(self,math.max(#cab,1),rawget(self,"_autoCompletePopupWidth")or +self.get("width"))end end +self:observe("autoCompleteEnabled",function(cab,dab)if not dab then aba(self,true)elseif self:hasState("focused")then +_da(self)end end)self:observe("foreground",aab) +self:observe("background",aab)self:observe("autoCompleteBackground",aab) +self:observe("autoCompleteForeground",aab) +self:observe("autoCompleteSelectedBackground",aab) +self:observe("autoCompleteSelectedForeground",aab)self:observe("autoCompleteBorderColor",aab) +self:observe("autoCompleteZOffset",function() +if + +self._autoCompleteFrame and not self._autoCompleteFrame._destroyed then +self._autoCompleteFrame:setZ(self.get("z")+self.get("autoCompleteZOffset"))end end) +self:observe("z",function() +if +self._autoCompleteFrame and not self._autoCompleteFrame._destroyed then +self._autoCompleteFrame:setZ(self.get("z")+self.get("autoCompleteZOffset"))end end) +self:observe("autoCompleteShowBorder",function()aab()bab()end) +for cab,dab in +ipairs({"autoCompleteItems","autoCompleteProvider","autoCompleteMinChars","autoCompleteMaxItems","autoCompleteCaseInsensitive","autoCompleteTokenPattern","autoCompleteOffsetX","autoCompleteOffsetY"})do self:observe(dab,_ab)end;self:observe("x",bab)self:observe("y",bab)self:observe("width",function() +bab()_ab()end) +self:observe("height",bab)self:observe("cursorX",bab) +self:observe("cursorY",bab)self:observe("scrollX",bab) +self:observe("scrollY",bab)self:observe("autoCompleteOffsetX",bab) +self:observe("autoCompleteOffsetY",bab) +self:observe("autoCompleteMaxWidth",function() +if baa(self)then +local cab=rawget(self,"_autoCompleteSuggestions")or{}if#cab>0 then local dab=cca(self,cab)self._autoCompletePopupWidth=dab +dca(self,math.max(#cab,1),dab)end end end)return self end;function d_a:addSyntaxPattern(c_b,d_b) +table.insert(self.get("syntaxPatterns"),{pattern=c_b,color=d_b})return self end +function d_a:removeSyntaxPattern(c_b)local d_b= +self.get("syntaxPatterns")or{} +if type(c_b)~="number"then return self end +if c_b>=1 and c_b<=#d_b then table.remove(d_b,c_b) +self.set("syntaxPatterns",d_b)self:updateRender()end;return self end;function d_a:clearSyntaxPatterns()self.set("syntaxPatterns",{}) +self:updateRender()return self end +local function cda(c_b,d_b) +local _ab=c_b.get("lines")local aab=c_b.get("cursorX")local bab=c_b.get("cursorY") +local cab=_ab[bab] +_ab[bab]=cab:sub(1,aab-1)..d_b..cab:sub(aab)c_b.set("cursorX",aab+1)c_b:updateViewport() +c_b:updateRender()end +local function dda(c_b,d_b)for i=1,#d_b do cda(c_b,d_b:sub(i,i))end end +local function __b(c_b)local d_b=c_b.get("lines")local _ab=c_b.get("cursorX") +local aab=c_b.get("cursorY")local bab=d_b[aab]local cab=bab:sub(_ab) +d_b[aab]=bab:sub(1,_ab-1)table.insert(d_b,aab+1,cab)c_b.set("cursorX",1)c_b.set("cursorY", +aab+1)c_b:updateViewport() +c_b:updateRender()end +local function a_b(c_b)local d_b=c_b.get("lines")local _ab=c_b.get("cursorX") +local aab=c_b.get("cursorY")local bab=d_b[aab] +if _ab>1 then +d_b[aab]=bab:sub(1,_ab-2)..bab:sub(_ab)c_b.set("cursorX",_ab-1)elseif aab>1 then local cab=d_b[aab-1]c_b.set("cursorX", +#cab+1)c_b.set("cursorY",aab-1)d_b[aab-1]= +cab..bab;table.remove(d_b,aab)end;c_b:updateViewport()c_b:updateRender()end +function d_a:updateViewport()local c_b=self.get("cursorX") +local d_b=self.get("cursorY")local _ab=self.get("scrollX")local aab=self.get("scrollY") +local bab=self.get("width")local cab=self.get("height") +if c_b-_ab>bab then +self.set("scrollX",c_b-bab)elseif c_b-_ab<1 then self.set("scrollX",c_b-1)end +if d_b-aab>cab then self.set("scrollY",d_b-cab)elseif d_b-aab<1 then self.set("scrollY", +d_b-1)end;return self end +function d_a:char(c_b) +if not self.get("editable")or +not self:hasState("focused")then return false end;local d_b=self.get("autoPairEnabled") +if d_b and#c_b==1 then local _ab= +self.get("autoPairCharacters")or{}local aab=self.get("lines") +local bab=self.get("cursorX")local cab=self.get("cursorY")local dab=aab[cab]or"" +local _bb=dab:sub(bab,bab)local abb=_ab[c_b] +if abb then cda(self,c_b) +if self.get("autoPairSkipClosing")then if _bb~=abb then +cda(self,abb) +self.set("cursorX",self.get("cursorX")-1)end else cda(self,abb)self.set("cursorX", +self.get("cursorX")-1)end;_da(self)return true end +if self.get("autoPairOverType")then +for bbb,cbb in pairs(_ab)do if c_b==cbb and _bb==cbb then +self.set("cursorX",bab+1)_da(self)return true end end end end;cda(self,c_b)_da(self)return true end +function d_a:key(c_b) +if not self.get("editable")or +not self:hasState("focused")then return false end;if ada(self,c_b)then return true end;local d_b=self.get("lines") +local _ab=self.get("cursorX")local aab=self.get("cursorY") +if c_b==keys.enter then +if +self.get("autoPairEnabled")and self.get("autoPairNewlineIndent")then +local bab=self.get("lines")local cab=self.get("cursorX")local dab=self.get("cursorY")local _bb= +bab[dab]or""local abb=_bb:sub(1,cab-1)local bbb=_bb:sub(cab)local cbb= +self.get("autoPairCharacters")or{}local dbb={} +for bcb,ccb in pairs(cbb)do dbb[ccb]=bcb end;local _cb=abb:sub(-1)local acb=bbb:sub(1,1) +if _cb~=""and acb~=""and +cbb[_cb]==acb then bab[dab]=abb;table.insert(bab,dab+1,"")table.insert(bab, +dab+2,bbb)self.set("cursorY",dab+1) +self.set("cursorX",1)self:updateViewport()self:updateRender()_da(self)return +true end end;__b(self)elseif c_b==keys.backspace then a_b(self)elseif c_b==keys.left then +if _ab>1 then self.set("cursorX", +_ab-1)elseif aab>1 then self.set("cursorY",aab-1)self.set("cursorX", +#d_b[aab-1]+1)end elseif c_b==keys.right then if _ab<=#d_b[aab]then +self.set("cursorX",_ab+1)elseif aab<#d_b then self.set("cursorY",aab+1) +self.set("cursorX",1)end elseif c_b==keys.up and +aab>1 then self.set("cursorY",aab-1) +self.set("cursorX",math.min(_ab,# +d_b[aab-1]+1))elseif c_b==keys.down and aab<#d_b then +self.set("cursorY",aab+1) +self.set("cursorX",math.min(_ab,#d_b[aab+1]+1))end;self:updateRender()self:updateViewport()_da(self)return +true end +function d_a:mouse_scroll(c_b,d_b,_ab)if bda(self,c_b)then return true end +if self:isInBounds(d_b,_ab)then +local aab=self.get("scrollY")local bab=self.get("height")local cab=self.get("lines")local dab=math.max(0,#cab- +bab+2) +local _bb=math.max(0,math.min(dab,aab+c_b))self.set("scrollY",_bb)self:updateRender()return true end;return false end +function d_a:mouse_click(c_b,d_b,_ab) +if b_a.mouse_click(self,c_b,d_b,_ab)then +local aab,bab=self:getRelativePosition(d_b,_ab)local cab=self.get("scrollX")local dab=self.get("scrollY")local _bb= +(bab or 0)+ (dab or 0) +local abb=self.get("lines")or{}if _bb<1 then _bb=1 end +if _bb<=#abb and abb[_bb]~=nil then +self.set("cursorY",_bb)local bbb=#tostring(abb[_bb]) +self.set("cursorX",math.min((aab or 1)+ (cab or 0), +bbb+1))end;self:updateRender()_da(self)return true end +if baa(self)then local aab=self._autoCompleteFrame;if +not +(aab and aab:isInBounds(d_b,_ab))and not self:isInBounds(d_b,_ab)then aba(self)end end;return false end +function d_a:paste(c_b) +if not self.get("editable")or +not self:hasState("focused")then return false end;for d_b in c_b:gmatch(".")do +if d_b=="\n"then __b(self)else cda(self,d_b)end end;_da(self)return true end +function d_a:setText(c_b)local d_b={} +if c_b==""then d_b={""}else for _ab in(c_b.."\n"):gmatch("([^\n]*)\n")do +table.insert(d_b,_ab)end end;self.set("lines",d_b)aba(self,true)return self end +function d_a:getText()return table.concat(self.get("lines"),"\n")end +local function b_b(c_b,d_b)local _ab=d_b +local aab=string.rep(c_a[c_b.get("foreground")],#_ab)local bab=c_b.get("syntaxPatterns") +for cab,dab in ipairs(bab)do local _bb=1 +while true do +local abb,bbb=_ab:find(dab.pattern,_bb)if not abb then break end;local cbb=bbb-abb+1 +if cbb<=0 then +aab=aab:sub(1,abb-1).. +string.rep(c_a[dab.color],1)..aab:sub(abb+1)_bb=abb+1 else +aab=aab:sub(1,abb-1)..string.rep(c_a[dab.color],cbb)..aab:sub( +bbb+1)_bb=bbb+1 end end end;return _ab,aab end +function d_a:render()b_a.render(self)local c_b=self.get("lines") +local d_b=self.get("scrollX")local _ab=self.get("scrollY")local aab=self.get("width") +local bab=self.get("height")local cab=c_a[self.get("foreground")] +local dab=c_a[self.get("background")] +for y=1,bab do local _bb=y+_ab;local abb=c_b[_bb]or""local bbb,cbb=b_b(self,abb)local dbb=bbb:sub(d_b+1,d_b+ +aab)local _cb=cbb:sub(d_b+1,d_b+aab)local acb= +aab-#dbb +if acb>0 then dbb=dbb..string.rep(" ",acb)_cb=_cb.. +string.rep(c_a[self.get("foreground")],acb)end +self:blit(1,y,dbb,_cb,string.rep(dab,#dbb))end +if self:hasState("focused")then local _bb=self.get("cursorX")-d_b;local abb= +self.get("cursorY")-_ab;if _bb>=1 and _bb<=aab and abb>=1 and +abb<=bab then +self:setCursor(_bb,abb,true,self.get("cursorColor")or +self.get("foreground"))end end end +function d_a:destroy() +if +self._autoCompleteFrame and not self._autoCompleteFrame._destroyed then self._autoCompleteFrame:destroy()end;self._autoCompleteFrame=nil;self._autoCompleteList=nil +self._autoCompletePopupWidth=nil;b_a.destroy(self)end;return d_a end +project["elements/Button.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement") +local ba=require("libraries/utils").getCenteredPosition;local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"text",{default="Button",type="string",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up")function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",10)da.set("height",3)da.set("z",5) +return da end;function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","Button")end +function ca:render() +aa.render(self)local da=self.getResolved("text") +da=da:sub(1,self.get("width")) +local _b,ab=ba(da,self.get("width"),self.get("height")) +self:textFg(_b,ab,da,self.getResolved("foreground"))end;return ca end +project["elements/Label.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/utils").wrapText +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"text",{default="Label",type="string",canTriggerRender=true,setter=function(da,_b) +if(type(_b)=="function")then _b=_b()end +if(da.get("autoSize"))then da.set("width",#_b)else da.set("height",# +ba(_b,da.get("width")))end;return _b end}) +ca.defineProperty(ca,"autoSize",{default=true,type="boolean",canTriggerRender=true,setter=function(da,_b)if(_b)then +da.set("width",#da.get("text"))else +da.set("height",#ba(da.get("text"),da.get("width")))end;return _b end}) +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("z",3)da.set("foreground",colors.black) +da.set("backgroundEnabled",false)return da end +function ca:init(da,_b)aa.init(self,da,_b)if(self.parent)then +self.set("background",self.parent.get("background")) +self.set("foreground",self.parent.get("foreground"))end +self.set("type","Label")return self end;function ca:getWrappedText()local da=self.get("text") +local _b=ba(da,self.get("width"))return _b end +function ca:render() +aa.render(self)local da=self.get("text") +if(self.get("autoSize"))then +self:textFg(1,1,da,self.get("foreground"))else local _b=ba(da,self.get("width"))for ab,bb in ipairs(_b)do +self:textFg(1,ab,bb,self.get("foreground"))end end end;return ca end +project["elements/SideNav.lua"] = function(...) local aa=require("elementManager") +local ba=require("elements/VisualElement")local ca=aa.getElement("Container") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"activeTab",{default=nil,type="number",allowNil=true,canTriggerRender=true,setter=function(ab,bb) +return bb end}) +_b.defineProperty(_b,"sidebarWidth",{default=12,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"tabs",{default={},type="table"}) +_b.defineProperty(_b,"sidebarBackground",{default=colors.gray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"activeTabBackground",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"activeTabTextColor",{default=colors.black,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"sidebarScrollOffset",{default=0,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"sidebarPosition",{default="left",type="string",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +_b.defineEvent(_b,"mouse_up")_b.defineEvent(_b,"mouse_scroll")function _b.new() +local ab=setmetatable({},_b):__init()ab.class=_b;ab.set("width",30)ab.set("height",15) +ab.set("z",10)return ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","SideNav")end +function _b:newTab(ab)local bb=self.get("tabs")or{}local cb=#bb+1 +table.insert(bb,{id=cb,title=tostring( +ab or("Item "..cb))})self.set("tabs",bb)if not self.get("activeTab")then +self.set("activeTab",cb)end;self:updateTabVisibility() +local db=self;local _c={} +setmetatable(_c,{__index=function(ac,bc) +if +type(bc)=="string"and bc:sub(1,3)=="add"and type(db[bc])=="function"then +return +function(dc,...) +local _d=db[bc](db,...) +if _d then _d._tabId=cb;db.set("childrenSorted",false) +db.set("childrenEventsSorted",false)db:updateRender()end;return _d end end;local cc=db[bc]if type(cc)=="function"then +return function(dc,...)return cc(db,...)end end;return cc end})return _c end;_b.addTab=_b.newTab;function _b:setTab(ab,bb)ab._tabId=bb +self:updateTabVisibility()return self end +function _b:addElement(ab,bb) +local cb=ca.addElement(self,ab)local db=bb or self.get("activeTab")if db then cb._tabId=db +self:updateTabVisibility()end;return cb end +function _b:addChild(ab)ca.addChild(self,ab)if not ab._tabId then +local bb=self.get("tabs")or{} +if#bb>0 then ab._tabId=1;self:updateTabVisibility()end end;return self end;function _b:updateTabVisibility()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)end +function _b:setActiveTab(ab) +local bb=self.get("activeTab")if bb==ab then return self end;self.set("activeTab",ab) +self:updateTabVisibility()self:dispatchEvent("tabChanged",ab,bb)return self end +function _b:isChildVisible(ab) +if not ca.isChildVisible(self,ab)then return false end +if ab._tabId then return ab._tabId==self.get("activeTab")end;return true end +function _b:getContentXOffset()local ab=self:_getSidebarMetrics()return ab.sidebarWidth end +function _b:_getSidebarMetrics()local ab=self.get("tabs")or{} +local bb=self.get("height")or 1;local cb=self.get("sidebarWidth")or 12;local db= +self.get("sidebarScrollOffset")or 0 +local _c=self.get("sidebarPosition")or"left"local ac={}local bc=1;local cc=#ab +for dc,_d in ipairs(ab)do local ad=1;local bd=bc-db;local cd=0;local dd=0 +if bd<1 then cd=1 -bd end;if bd+ad-1 >bb then dd=(bd+ad-1)-bb end +if +bd+ad>1 and bd<=bb then local __a=math.max(1,bd)local a_a=ad-cd-dd +table.insert(ac,{id=_d.id,title=_d.title,y1=__a,y2=__a+a_a-1,height=ad,displayHeight=a_a,actualY=bc,startClip=cd,endClip=dd})end;bc=bc+ad end;return +{sidebarWidth=cb,sidebarPosition=_c,positions=ac,totalHeight=cc,scrollOffset=db,maxScroll=math.max(0,cc-bb)}end +function _b:mouse_click(ab,bb,cb) +if not ba.mouse_click(self,ab,bb,cb)then return false end;local db,_c=ba.getRelativePosition(self,bb,cb) +local ac=self:_getSidebarMetrics()local bc=self.get("width")or 1;local cc=false;if +ac.sidebarPosition=="right"then cc=db> (bc-ac.sidebarWidth)else +cc=db<=ac.sidebarWidth end +if cc then if#ac.positions==0 then +return true end;for dc,_d in ipairs(ac.positions)do +if _c>=_d.y1 and _c<=_d.y2 then +self:setActiveTab(_d.id)self.set("focusedChild",nil)return true end end +return true end;return ca.mouse_click(self,ab,bb,cb)end +function _b:getRelativePosition(ab,bb)local cb=self:_getSidebarMetrics() +local db=self.get("width")or 1 +if ab==nil or bb==nil then return ba.getRelativePosition(self)else +local _c,ac=ba.getRelativePosition(self,ab,bb) +if cb.sidebarPosition=="right"then return _c,ac else return _c-cb.sidebarWidth,ac end end end +function _b:multiBlit(ab,bb,cb,db,_c,ac,bc)local cc=self:_getSidebarMetrics() +if +cc.sidebarPosition=="right"then return ca.multiBlit(self,ab,bb,cb,db,_c,ac,bc)else +return ca.multiBlit(self,(ab or 1)+ +cc.sidebarWidth,bb,cb,db,_c,ac,bc)end end +function _b:textFg(ab,bb,cb,db)local _c=self:_getSidebarMetrics() +if +_c.sidebarPosition=="right"then return ca.textFg(self,ab,bb,cb,db)else return +ca.textFg(self,(ab or 1)+_c.sidebarWidth,bb,cb,db)end end +function _b:textBg(ab,bb,cb,db)local _c=self:_getSidebarMetrics() +if +_c.sidebarPosition=="right"then return ca.textBg(self,ab,bb,cb,db)else return +ca.textBg(self,(ab or 1)+_c.sidebarWidth,bb,cb,db)end end +function _b:drawText(ab,bb,cb)local db=self:_getSidebarMetrics() +if +db.sidebarPosition=="right"then return ca.drawText(self,ab,bb,cb)else return +ca.drawText(self,(ab or 1)+db.sidebarWidth,bb,cb)end end +function _b:drawFg(ab,bb,cb)local db=self:_getSidebarMetrics() +if +db.sidebarPosition=="right"then return ca.drawFg(self,ab,bb,cb)else return +ca.drawFg(self,(ab or 1)+db.sidebarWidth,bb,cb)end end +function _b:drawBg(ab,bb,cb)local db=self:_getSidebarMetrics() +if +db.sidebarPosition=="right"then return ca.drawBg(self,ab,bb,cb)else return +ca.drawBg(self,(ab or 1)+db.sidebarWidth,bb,cb)end end +function _b:blit(ab,bb,cb,db,_c)local ac=self:_getSidebarMetrics() +if ac.sidebarPosition=="right"then return +ca.blit(self,ab,bb,cb,db,_c)else return +ca.blit(self,(ab or 1)+ac.sidebarWidth,bb,cb,db,_c)end end +function _b:mouse_up(ab,bb,cb) +if not ba.mouse_up(self,ab,bb,cb)then return false end;local db,_c=ba.getRelativePosition(self,bb,cb) +local ac=self:_getSidebarMetrics()local bc=self.get("width")or 1;local cc=false;if +ac.sidebarPosition=="right"then cc=db> (bc-ac.sidebarWidth)else +cc=db<=ac.sidebarWidth end;if cc then return true end;return +ca.mouse_up(self,ab,bb,cb)end +function _b:mouse_release(ab,bb,cb)ba.mouse_release(self,ab,bb,cb) +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then return end;return ca.mouse_release(self,ab,bb,cb)end +function _b:mouse_move(ab,bb,cb) +if ba.mouse_move(self,ab,bb,cb)then +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then return true end +local dc={self:getRelativePosition(bb,cb)} +local _d,ad=self:callChildrenEvent(true,"mouse_move",table.unpack(dc))if _d then return true end end;return false end +function _b:mouse_drag(ab,bb,cb) +if ba.mouse_drag(self,ab,bb,cb)then +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then return true end;return ca.mouse_drag(self,ab,bb,cb)end;return false end +function _b:scrollSidebar(ab)local bb=self:_getSidebarMetrics()local cb= +self.get("sidebarScrollOffset")or 0;local db=bb.maxScroll or 0;local _c=cb+ +(ab*2)_c=math.max(0,math.min(db,_c)) +self.set("sidebarScrollOffset",_c)return self end +function _b:mouse_scroll(ab,bb,cb) +if ba.mouse_scroll(self,ab,bb,cb)then +local db,_c=ba.getRelativePosition(self,bb,cb)local ac=self:_getSidebarMetrics() +local bc=self.get("width")or 1;local cc=false +if ac.sidebarPosition=="right"then +cc=db> (bc-ac.sidebarWidth)else cc=db<=ac.sidebarWidth end;if cc then self:scrollSidebar(ab)return true end;return +ca.mouse_scroll(self,ab,bb,cb)end;return false end +function _b:setCursor(ab,bb,cb,db)local _c=self:_getSidebarMetrics() +if self.parent then +local ac,bc=self:calculatePosition()local cc,dc +if _c.sidebarPosition=="right"then cc=ab+ac-1;dc=bb+bc-1 else cc=ab+ac-1 + +_c.sidebarWidth;dc=bb+bc-1 end +if + +(cc<1)or(cc>self.parent.get("width"))or(dc<1)or(dc>self.parent.get("height"))then return self.parent:setCursor(cc,dc,false)end;return self.parent:setCursor(cc,dc,cb,db)end;return self end +function _b:render()ba.render(self)local ab=self.get("height") +local bb=self:_getSidebarMetrics()local cb=bb.sidebarWidth or 12;for y=1,ab do +ba.multiBlit(self,1,y,cb,1," ",da[self.get("foreground")],da[self.get("sidebarBackground")])end +local db=self.get("activeTab") +for _c,ac in ipairs(bb.positions)do +local bc= +(ac.id==db)and self.get("activeTabBackground")or self.get("sidebarBackground")local cc=(ac.id==db)and self.get("activeTabTextColor")or +self.get("foreground")local dc= +ac.displayHeight or(ac.y2 -ac.y1 +1)for dy=0,dc-1 do +ba.multiBlit(self,1, +ac.y1 +dy,cb,1," ",da[self.get("foreground")],da[bc])end;local _d=ac.title;if#_d>cb-2 then _d=_d:sub(1, +cb-2)end +ba.textFg(self,2,ac.y1,_d,cc)end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for _c in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(_c)end end +for _c,ac in ipairs(self.get("visibleChildren")or{})do if ac==self then +error("CIRCULAR REFERENCE DETECTED!")return end;ac:render()ac:postRender()end end +function _b:sortChildrenEvents(ab) +local bb=self._values.childrenEvents and self._values.childrenEvents[ab] +if bb then local cb={}for db,_c in ipairs(bb)do +if self:isChildVisible(_c)then table.insert(cb,_c)end end +for i=2,#cb do local db=cb[i] +local _c=db.get("z")local ac=i-1 +while ac>0 do local bc=cb[ac].get("z")if bc>_c then cb[ac+1]=cb[ac] +ac=ac-1 else break end end;cb[ac+1]=db end +self._values.visibleChildrenEvents=self._values.visibleChildrenEvents or{}self._values.visibleChildrenEvents[ab]=cb end;self.set("childrenEventsSorted",true)return self end;return _b end +project["elements/Input.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"text",{default="",type="string",canTriggerRender=true}) +aa.defineProperty(aa,"cursorPos",{default=1,type="number"}) +aa.defineProperty(aa,"viewOffset",{default=0,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"maxLength",{default=nil,type="number"}) +aa.defineProperty(aa,"placeholder",{default="...",type="string"}) +aa.defineProperty(aa,"placeholderColor",{default=colors.gray,type="color"}) +aa.defineProperty(aa,"pattern",{default=nil,type="string"}) +aa.defineProperty(aa,"cursorColor",{default=nil,type="number"}) +aa.defineProperty(aa,"replaceChar",{default=nil,type="string",canTriggerRender=true})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"mouse_up")aa.defineEvent(aa,"key")aa.defineEvent(aa,"char") +aa.defineEvent(aa,"paste") +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",8)ba.set("z",3)return ba end +function aa:init(ba,ca)d.init(self,ba,ca)self.set("type","Input")return self end +function aa:setCursor(ba,ca,da,_b) +ba=math.min(self.get("width"),math.max(1,ba))return d.setCursor(self,ba,ca,da,_b)end +function aa:char(ba) +if not self:hasState("focused")then return false end;local ca=self.get("text")local da=self.get("cursorPos") +local _b=self.get("maxLength")local ab=self.get("pattern") +if _b and#ca>=_b then return false end;if ab and not ba:match(ab)then return false end +self.set("text",ca:sub(1, +da-1)..ba..ca:sub(da))self.set("cursorPos",da+1)self:updateViewport()local bb= +self.get("cursorPos")-self.get("viewOffset") +self:setCursor(bb,1,true, +self.get("cursorColor")or self.get("foreground"))d.char(self,ba)return true end +function aa:key(ba,ca) +if not self:hasState("focused")then return false end;local da=self.get("cursorPos")local _b=self.get("text") +local ab=self.get("viewOffset")local bb=self.get("width") +if ba==keys.left then +if da>1 then +self.set("cursorPos",da-1)if da-1 <=ab then +self.set("viewOffset",math.max(0,da-2))end end elseif ba==keys.right then +if da<=#_b then self.set("cursorPos",da+1)if da-ab>=bb then self.set("viewOffset", +da-bb+1)end end elseif ba==keys.backspace then if da>1 then +self.set("text",_b:sub(1,da-2).._b:sub(da))self.set("cursorPos",da-1)self:updateRender() +self:updateViewport()end end +local cb=self.get("cursorPos")-self.get("viewOffset") +self:setCursor(cb,1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))d.key(self,ba,ca)return true end +function aa:mouse_click(ba,ca,da) +if d.mouse_click(self,ba,ca,da)then +local _b,ab=self:getRelativePosition(ca,da)local bb=self.get("text")local cb=self.get("viewOffset") +local db=#bb+1;local _c=math.min(db,cb+_b)self.set("cursorPos",_c) +local ac=_c-cb +self:setCursor(ac,1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))return true end;return false end +function aa:updateViewport()local ba=self.get("width") +local ca=self.get("cursorPos")local da=self.get("viewOffset") +local _b=#self.get("text") +if ca-da>=ba then self.set("viewOffset",ca-ba+1)elseif ca<=da then self.set("viewOffset", +ca-1)end +self.set("viewOffset",math.max(0,math.min(self.get("viewOffset"),_b-ba+1)))return self end +function aa:focus()d.focus(self) +self:setCursor(self.get("cursorPos")- +self.get("viewOffset"),1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))self:updateRender()end +function aa:blur()d.blur(self) +self:setCursor(1,1,false,self.getResolved("cursorColor")or +self.getResolved("foreground"))self:updateRender()end +function aa:paste(ba) +if not self:hasState("focused")then return false end;local ca=self.get("text")local da=self.get("cursorPos") +local _b=self.get("maxLength")local ab=self.get("pattern") +local bb=ca:sub(1,da-1)..ba..ca:sub(da)if _b and#bb>_b then bb=bb:sub(1,_b)end;if +ab and not bb:match(ab)then return false end;self.set("text",bb)self.set("cursorPos",da+ +#ba)self:updateViewport()end +function aa:render()local ba=self.getResolved("text") +local ca=self.get("viewOffset")local da=self.getResolved("placeholder") +local _b=self:hasState("focused")local ab,bb=self.get("width"),self.get("height") +local cb=self.getResolved("replaceChar") +self:multiBlit(1,1,ab,bb," ",_a[self.getResolved("foreground")],_a[self.getResolved("background")])if#ba==0 and#da~=0 and not _b then +self:textFg(1,1,da:sub(1,ab),self.getResolved("placeholderColor"))return end;if(_b)then +self:setCursor( +self.get("cursorPos")-ca,1,true,self.getResolved("cursorColor")or +self.getResolved("foreground"))end +local db=ba:sub(ca+1,ca+ab)if cb and#cb>0 then db=cb:rep(#db)end +self:textFg(1,1,db,self.getResolved("foreground"))end;return aa end +project["elements/Toast.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"title",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"message",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"duration",{default=3,type="number"}) +ca.defineProperty(ca,"toastType",{default="default",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"autoHide",{default=true,type="boolean"}) +ca.defineProperty(ca,"active",{default=false,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"colorMap",{default={success=colors.green,error=colors.red,warning=colors.orange,info=colors.lightBlue,default=colors.gray},type="table"})ca.defineEvent(ca,"timer")function ca.new() +local da=setmetatable({},ca):__init()da.class=ca;da.set("width",30)da.set("height",3) +da.set("z",100)return da end;function ca:init(da,_b) +aa.init(self,da,_b)return self end +function ca:show(da,_b,ab)local bb,cb,db +if type(_b)=="string"then bb=da +cb=_b;db=ab or self.get("duration")elseif type(_b)=="number"then bb="" +cb=da;db=_b else bb=""cb=da;db=self.get("duration")end;self.set("title",bb)self.set("message",cb) +self.set("active",true)if self._hideTimerId then os.cancelTimer(self._hideTimerId) +self._hideTimerId=nil end +if +self.get("autoHide")and db>0 then self._hideTimerId=os.startTimer(db)end;return self end +function ca:hide()self.set("active",false)self.set("title","") +self.set("message","")if self._hideTimerId then os.cancelTimer(self._hideTimerId) +self._hideTimerId=nil end;return self end;function ca:success(da,_b,ab)self.set("toastType","success") +return self:show(da,_b,ab)end;function ca:error(da,_b,ab) +self.set("toastType","error")return self:show(da,_b,ab)end +function ca:warning(da,_b,ab) +self.set("toastType","warning")return self:show(da,_b,ab)end;function ca:info(da,_b,ab)self.set("toastType","info") +return self:show(da,_b,ab)end +function ca:dispatchEvent(da,...) +aa.dispatchEvent(self,da,...)if da=="timer"then local _b=select(1,...) +if _b==self._hideTimerId then self:hide()end end end +function ca:render()aa.render(self) +if not self.get("active")then return end;local da=self.get("width")local _b=self.get("height") +local ab=self.getResolved("title")local bb=self.getResolved("message") +local cb=self.getResolved("toastType")local db=self.getResolved("colorMap") +local _c=db[cb]or db.default;local ac=self.getResolved("foreground")local bc=1;local cc=1 +if ab~=""then local dc=ab:sub(1, +da-bc+1)self:textFg(bc,cc,dc,_c)cc=cc+1 end +if bb~=""and cc<=_b then local dc=da-bc+1;local _d={}for bd in bb:gmatch("%S+")do +table.insert(_d,bd)end;local ad="" +for bd,cd in ipairs(_d)do if#ad+#cd+1 >dc then if cc<=_b then +self:textFg(bc,cc,ad,ac)cc=cc+1;ad=cd else break end else +ad=ad==""and cd or ad.." "..cd end end +if ad~=""and cc<=_b then self:textFg(bc,cc,ad,ac)end end end;return ca end +project["elements/BigFont.lua"] = function(...) local _b=require("libraries/colorHex") +local ab={{"\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 bb={}local cb={} +do local dc=0;local _d=#ab[1]local ad=#ab[1][1] +for i=1,_d,3 do +for j=1,ad,3 do +local bd=string.char(dc)local cd={}cd[1]=ab[1][i]:sub(j,j+2) +cd[2]=ab[1][i+1]:sub(j,j+2)cd[3]=ab[1][i+2]:sub(j,j+2)local dd={}dd[1]=ab[2][i]:sub(j, +j+2)dd[2]=ab[2][i+1]:sub(j,j+2)dd[3]=ab[2][ +i+2]:sub(j,j+2)cb[bd]={cd,dd}dc=dc+1 end end;bb[1]=cb end +local function db(dc,_d)local ad={["0"]="1",["1"]="0"}if dc<=#bb then return true end +for f=#bb+1,dc do local bd={}local cd=bb[ +f-1] +for char=0,255 do local dd=string.char(char)local __a={}local a_a={} +local b_a=cd[dd][1]local c_a=cd[dd][2] +for i=1,#b_a do local d_a,_aa,aaa,baa,caa,daa={},{},{},{},{},{} +for j=1,#b_a[1]do +local _ba=cb[b_a[i]:sub(j,j)][1]table.insert(d_a,_ba[1]) +table.insert(_aa,_ba[2])table.insert(aaa,_ba[3]) +local aba=cb[b_a[i]:sub(j,j)][2] +if c_a[i]:sub(j,j)=="1"then +table.insert(baa,(aba[1]:gsub("[01]",ad))) +table.insert(caa,(aba[2]:gsub("[01]",ad))) +table.insert(daa,(aba[3]:gsub("[01]",ad)))else table.insert(baa,aba[1]) +table.insert(caa,aba[2])table.insert(daa,aba[3])end end;table.insert(__a,table.concat(d_a)) +table.insert(__a,table.concat(_aa))table.insert(__a,table.concat(aaa)) +table.insert(a_a,table.concat(baa))table.insert(a_a,table.concat(caa)) +table.insert(a_a,table.concat(daa))end;bd[dd]={__a,a_a}if _d then _d="Font"..f.."Yeld"..char +os.queueEvent(_d)os.pullEvent(_d)end end;bb[f]=bd end;return true end +local function _c(dc,_d,ad,bd,cd) +if not type(_d)=="string"then error("Not a String",3)end +local dd=type(ad)=="string"and ad:sub(1,1)or _b[ad]or +error("Wrong Front Color",3) +local __a=type(bd)=="string"and bd:sub(1,1)or _b[bd]or +error("Wrong Back Color",3)if(bb[dc]==nil)then db(3,false)end;local a_a=bb[dc]or +error("Wrong font size selected",3)if _d==""then +return{{""},{""},{""}}end;local b_a={} +for daa in _d:gmatch('.')do table.insert(b_a,daa)end;local c_a={}local d_a=#a_a[b_a[1]][1] +for nLine=1,d_a do local daa={}for i=1,#b_a do +daa[i]= +a_a[b_a[i]]and a_a[b_a[i]][1][nLine]or""end;c_a[nLine]=table.concat(daa)end;local _aa={}local aaa={}local baa={["0"]=dd,["1"]=__a}local caa={["0"]=__a,["1"]=dd} +for nLine=1,d_a +do local daa={}local _ba={} +for i=1,#b_a do local aba= +a_a[b_a[i]]and a_a[b_a[i]][2][nLine]or"" +daa[i]=aba:gsub("[01]",cd and +{["0"]=ad:sub(i,i),["1"]=bd:sub(i,i)}or baa) +_ba[i]=aba:gsub("[01]", +cd and{["0"]=bd:sub(i,i),["1"]=ad:sub(i,i)}or caa)end;_aa[nLine]=table.concat(daa) +aaa[nLine]=table.concat(_ba)end;return{c_a,_aa,aaa}end;local ac=require("elementManager") +local bc=ac.getElement("VisualElement")local cc=setmetatable({},bc)cc.__index=cc +cc.defineProperty(cc,"text",{default="BigFont",type="string",canTriggerRender=true,setter=function(dc,_d) +dc.bigfontText=_c(dc.get("fontSize"),_d,dc.get("foreground"),dc.get("background"))return _d end}) +cc.defineProperty(cc,"fontSize",{default=1,type="number",canTriggerRender=true,setter=function(dc,_d) +dc.bigfontText=_c(_d,dc.get("text"),dc.get("foreground"),dc.get("background"))return _d end})function cc.new()local dc=setmetatable({},cc):__init() +dc.class=cc;dc.set("width",16)dc.set("height",3)dc.set("z",5) +return dc end +function cc:init(dc,_d) +bc.init(self,dc,_d)self.set("type","BigFont") +self:observe("background",function(ad,bd) +ad.bigfontText=_c(ad.get("fontSize"),ad.get("text"),ad.get("foreground"),bd)end) +self:observe("foreground",function(ad,bd) +ad.bigfontText=_c(ad.get("fontSize"),ad.get("text"),bd,ad.get("background"))end)end +function cc:render()bc.render(self) +if(self.bigfontText)then +local dc,_d=self.get("x"),self.get("y") +for i=1,#self.bigfontText[1]do +local ad=self.bigfontText[1][i]:sub(1,self.get("width")) +local bd=self.bigfontText[2][i]:sub(1,self.get("width")) +local cd=self.bigfontText[3][i]:sub(1,self.get("width"))self:blit(dc,_d+i-1,ad,bd,cd)end end end;return cc end +project["elements/Switch.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"checked",{default=false,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"text",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"autoSize",{default=false,type="boolean"}) +ca.defineProperty(ca,"onBackground",{default=colors.green,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"offBackground",{default=colors.red,type="number",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up") +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",2)da.set("height",1)da.set("z",5) +da.set("backgroundEnabled",true)return da end +function ca:init(da,_b)aa.init(self,da,_b)self.set("type","Switch")end +function ca:mouse_click(da,_b,ab)if aa.mouse_click(self,da,_b,ab)then +self.set("checked",not self.get("checked"))return true end;return false end +function ca:render()local da=self.get("checked")local _b=self.get("text") +local ab=self.get("width")local bb=self.get("height")local cb=da and self.get("onBackground")or +self.get("offBackground") +self:multiBlit(1,1,ab,bb," ",ba[self.get("foreground")],ba[cb])local db=math.floor(ab/2)local _c=da and(ab-db+1)or 1 +self:multiBlit(_c,1,db,bb," ",ba[self.get("foreground")],ba[self.get("background")])if _b~=""then +self:textFg(ab+2,1,_b,self.get("foreground"))end end;return ca end +project["elements/Frame.lua"] = function(...) local aa=require("elementManager") +local ba=aa.getElement("VisualElement")local ca=aa.getElement("Container")local da=setmetatable({},ca) +da.__index=da +da.defineProperty(da,"draggable",{default=false,type="boolean"}) +da.defineProperty(da,"draggingMap",{default={{x=1,y=1,width="width",height=1}},type="table"}) +da.defineProperty(da,"scrollable",{default=false,type="boolean"})da.defineEvent(da,"mouse_click") +da.defineEvent(da,"mouse_drag")da.defineEvent(da,"mouse_up") +da.defineEvent(da,"mouse_scroll") +function da.new()local ab=setmetatable({},da):__init() +ab.class=da;ab.set("width",12)ab.set("height",6) +ab.set("background",colors.gray)ab.set("z",10)return ab end;function da:init(ab,bb)ca.init(self,ab,bb)self.set("type","Frame") +return self end +function da:mouse_click(ab,bb,cb) +if self:isInBounds(bb,cb)then +if +self.get("draggable")then local db,_c=self:getRelativePosition(bb,cb) +local ac=self.get("draggingMap") +for bc,cc in ipairs(ac)do local dc=cc.width or 1;local _d=cc.height or 1;if +type(dc)=="string"and dc=="width"then dc=self.get("width")elseif +type(dc)=="function"then dc=dc(self)end +if type(_d)== +"string"and _d=="height"then _d=self.get("height")elseif +type(_d)=="function"then _d=_d(self)end;local ad=cc.y or 1 +if +db>=cc.x and db<=cc.x+dc-1 and _c>=ad and _c<=ad+_d-1 then +self.dragStartX=bb-self.get("x")self.dragStartY=cb-self.get("y")self.dragging=true +return true end end end;return ca.mouse_click(self,ab,bb,cb)end;return false end +function da:mouse_up(ab,bb,cb)if self.dragging then self.dragging=false;self.dragStartX=nil +self.dragStartY=nil;return true end;return +ca.mouse_up(self,ab,bb,cb)end +function da:mouse_drag(ab,bb,cb) +if self.dragging then local db=bb-self.dragStartX +local _c=cb-self.dragStartY;self.set("x",db)self.set("y",_c)return true end;return ca.mouse_drag(self,ab,bb,cb)end +function da:getChildrenHeight()local ab=0;local bb=self.get("children") +for cb,db in ipairs(bb)do if +db.get("visible")then local _c=db.get("y")local ac=db.get("height")local bc=_c+ac-1 +if bc>ab then ab=bc end end end;return ab end +local function _b(ab,bb,...)local cb={...} +if bb and bb:find("mouse_")then local db,_c,ac=... +local bc,cc=ab.get("offsetX"),ab.get("offsetY")local dc,_d=ab:getRelativePosition(_c+bc,ac+cc) +cb={db,dc,_d}end;return cb end +function da:mouse_scroll(ab,bb,cb) +if(ba.mouse_scroll(self,ab,bb,cb))then +local db=_b(self,"mouse_scroll",ab,bb,cb) +local _c,ac=self:callChildrenEvent(true,"mouse_scroll",table.unpack(db))if _c then return true end +if self.get("scrollable")then +local bc=self.get("height")local cc=self:getChildrenHeight() +local dc=self.get("offsetY")local _d=math.max(0,cc-bc)local ad=dc+ab +ad=math.max(0,math.min(_d,ad))self.set("offsetY",ad)return true end end;return false end;return da end +project["elements/Container.lua"] = function(...) local _b=require("elementManager") +local ab=require("errorManager")local bb=_b.getElement("VisualElement") +local cb=require("layoutManager")local db=require("libraries/expect") +local _c=require("libraries/utils").split;local ac=setmetatable({},bb)ac.__index=ac +ac.defineProperty(ac,"children",{default={},type="table"}) +ac.defineProperty(ac,"childrenSorted",{default=true,type="boolean"}) +ac.defineProperty(ac,"childrenEventsSorted",{default=true,type="boolean"}) +ac.defineProperty(ac,"childrenEvents",{default={},type="table"}) +ac.defineProperty(ac,"eventListenerCount",{default={},type="table"}) +ac.defineProperty(ac,"focusedChild",{default=nil,type="table",allowNil=true,setter=function(dc,_d,ad)local bd=dc._values.focusedChild +if _d==bd then return _d end +if bd then +if bd:isType("Container")then bd.set("focusedChild",nil,true)end;bd:setFocused(false,true)end;if _d and not ad then _d:setFocused(true,true)if dc.parent then +dc.parent:setFocusedChild(dc)end end;return +_d end}) +ac.defineProperty(ac,"visibleChildren",{default={},type="table"}) +ac.defineProperty(ac,"visibleChildrenEvents",{default={},type="table"}) +ac.defineProperty(ac,"offsetX",{default=0,type="number",canTriggerRender=true,setter=function(dc,_d)dc.set("childrenSorted",false) +dc.set("childrenEventsSorted",false)return _d end}) +ac.defineProperty(ac,"offsetY",{default=0,type="number",canTriggerRender=true,setter=function(dc,_d)dc.set("childrenSorted",false) +dc.set("childrenEventsSorted",false)return _d end}) +ac.combineProperties(ac,"offset","offsetX","offsetY") +for dc,_d in pairs(_b:getElementList())do +local ad=dc:sub(1,1):upper()..dc:sub(2) +if ad~="BaseFrame"then +ac["add"..ad]=function(bd,...)db(1,bd,"table") +local cd=bd.basalt.create(dc,...)bd:addChild(cd)return cd end +ac["addDelayed"..ad]=function(bd,cd)db(1,bd,"table") +local dd=bd.basalt.create(dc,cd,true,bd)return dd end end end;function ac.new()local dc=setmetatable({},ac):__init() +dc.class=ac;return dc end +function ac:init(dc,_d) +bb.init(self,dc,_d)self.set("type","Container") +self:observe("width",function() +self.set("childrenSorted",false)self.set("childrenEventsSorted",false) +self:updateRender()end) +self:observe("height",function()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)self:updateRender()end)end +function ac:isChildVisible(dc) +if not dc:isType("VisualElement")then return false end;if(dc.get("visible")==false)then return false end;if(dc._destroyed)then return +false end +local _d,ad=self.get("width"),self.get("height")local bd,cd=self.get("offsetX"),self.get("offsetY") +local dd,__a=dc.get("x"),dc.get("y")local a_a,b_a=dc.get("width"),dc.get("height")local c_a;local d_a;if +(dc.get("ignoreOffset"))then c_a=dd;d_a=__a else c_a=dd-bd;d_a=__a-cd end;return +(c_a+ +a_a>0)and(c_a<=_d)and(d_a+b_a>0)and(d_a<=ad)end +function ac:addChild(dc) +if dc==self then error("Cannot add container to itself")end;if(dc~=nil)then table.insert(self._values.children,dc) +dc.parent=self;dc:postInit()self.set("childrenSorted",false) +self:registerChildrenEvents(dc)end;return +self end +local function bc(dc,_d)local ad={}for bd,cd in ipairs(_d)do +if dc:isChildVisible(cd)and cd.get("visible")and not +cd._destroyed then table.insert(ad,cd)end end +for i=2,#ad do +local bd=ad[i]local cd=bd.get("z")local dd=i-1 +while dd>0 do local __a=ad[dd].get("z")if __a>cd then +ad[dd+1]=ad[dd]dd=dd-1 else break end end;ad[dd+1]=bd end;return ad end +function ac:clear()self.set("children",{}) +self.set("childrenEvents",{})self.set("visibleChildren",{}) +self.set("visibleChildrenEvents",{})self.set("childrenSorted",true) +self.set("childrenEventsSorted",true)return self end +function ac:sortChildren()self.set("childrenSorted",true)if self._layoutInstance then +self:updateLayout()end +self.set("visibleChildren",bc(self,self._values.children))return self end +function ac:sortChildrenEvents(dc)if self._values.childrenEvents[dc]then +self._values.visibleChildrenEvents[dc]=bc(self,self._values.childrenEvents[dc])end +self.set("childrenEventsSorted",true)return self end +function ac:registerChildrenEvents(dc)if(dc._registeredEvents==nil)then return end +for _d in +pairs(dc._registeredEvents)do self:registerChildEvent(dc,_d)end;return self end +function ac:registerChildEvent(dc,_d) +if not self._values.childrenEvents[_d]then +self._values.childrenEvents[_d]={}self._values.eventListenerCount[_d]=0;if self.parent then +self.parent:registerChildEvent(self,_d)end end +for ad,bd in ipairs(self._values.childrenEvents[_d])do if bd.get("id")== +dc.get("id")then return self end end;self.set("childrenEventsSorted",false) +table.insert(self._values.childrenEvents[_d],dc)self._values.eventListenerCount[_d]= +self._values.eventListenerCount[_d]+1;return self end +function ac:removeChildrenEvents(dc) +if dc~=nil then +if(dc._registeredEvents==nil)then return self end;for _d in pairs(dc._registeredEvents)do +self:unregisterChildEvent(dc,_d)end end;return self end +function ac:unregisterChildEvent(dc,_d) +if self._values.childrenEvents[_d]then +for ad,bd in +ipairs(self._values.childrenEvents[_d])do +if bd.get("id")==dc.get("id")then +table.remove(self._values.childrenEvents[_d],ad)self._values.eventListenerCount[_d]= +self._values.eventListenerCount[_d]-1 +if +self._values.eventListenerCount[_d]<=0 then +self._values.childrenEvents[_d]=nil;self._values.eventListenerCount[_d]=nil;if self.parent then +self.parent:unregisterChildEvent(self,_d)end end;self.set("childrenEventsSorted",false)break end end end;return self end +function ac:removeChild(dc)if dc==nil then return self end +for _d,ad in ipairs(self._values.children)do if +ad.get("id")==dc.get("id")then +table.remove(self._values.children,_d)dc.parent=nil;break end end;self:removeChildrenEvents(dc)self:updateRender() +self.set("childrenSorted",false)return self end +function ac:getChild(dc) +if type(dc)=="string"then local _d=_c(dc,"/") +for ad,bd in +pairs(self._values.children)do if bd.get("name")==_d[1]then +if#_d==1 then return bd else if(bd:isType("Container"))then return +bd:find(table.concat(_d,"/",2))end end end end end;return nil end +local function cc(dc,_d,...)local ad={...} +if _d and _d:find("mouse_")then local bd,cd,dd=... +local __a,a_a=dc.get("offsetX"),dc.get("offsetY")local b_a,c_a=dc:getRelativePosition(cd+__a,dd+a_a) +ad={bd,b_a,c_a}end;return ad end +function ac:callChildrenEvent(dc,_d,...) +if +dc and not self.get("childrenEventsSorted")then for bd in pairs(self._values.childrenEvents)do +self:sortChildrenEvents(bd)end end;local ad=dc and self.get("visibleChildrenEvents")or +self.get("childrenEvents") +if +ad[_d]then local bd=ad[_d]for i=#bd,1,-1 do local cd=bd[i] +if(cd:dispatchEvent(_d,...))then return true,cd end end end +if(ad["*"])then local bd=ad["*"]for i=#bd,1,-1 do local cd=bd[i] +if(cd:dispatchEvent(_d,...))then return true,cd end end end;return false end +function ac:handleEvent(dc,...)bb.handleEvent(self,dc,...)local _d=cc(self,dc,...)return +self:callChildrenEvent(false,dc,table.unpack(_d))end +function ac:mouse_click(dc,_d,ad) +if bb.mouse_click(self,dc,_d,ad)then +local bd=cc(self,"mouse_click",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_click",table.unpack(bd)) +if(cd)then self.set("focusedChild",dd)return true end;self.set("focusedChild",nil)return true end;return false end +function ac:mouse_up(dc,_d,ad)self:mouse_release(dc,_d,ad) +if bb.mouse_up(self,dc,_d,ad)then +local bd=cc(self,"mouse_up",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_up",table.unpack(bd))if(cd)then return true end end;return false end +function ac:mouse_release(dc,_d,ad)bb.mouse_release(self,dc,_d,ad) +local bd=cc(self,"mouse_release",dc,_d,ad) +self:callChildrenEvent(false,"mouse_release",table.unpack(bd))end +function ac:mouse_move(dc,_d,ad) +if bb.mouse_move(self,dc,_d,ad)then +local bd=cc(self,"mouse_move",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_move",table.unpack(bd))if(cd)then return true end end;return false end +function ac:mouse_drag(dc,_d,ad) +if bb.mouse_drag(self,dc,_d,ad)then +local bd=cc(self,"mouse_drag",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_drag",table.unpack(bd))if(cd)then return true end end;return false end +function ac:mouse_scroll(dc,_d,ad) +if(bb.mouse_scroll(self,dc,_d,ad))then +local bd=cc(self,"mouse_scroll",dc,_d,ad) +local cd,dd=self:callChildrenEvent(true,"mouse_scroll",table.unpack(bd))return true end;return false end;function ac:key(dc)if self.get("focusedChild")then return +self.get("focusedChild"):dispatchEvent("key",dc)end +return true end +function ac:char(dc)if +self.get("focusedChild")then +return self.get("focusedChild"):dispatchEvent("char",dc)end;return true end;function ac:key_up(dc) +if self.get("focusedChild")then return +self.get("focusedChild"):dispatchEvent("key_up",dc)end;return true end +function ac:multiBlit(dc,_d,ad,bd,cd,dd,__a) +local a_a,b_a=self.get("width"),self.get("height")ad=dc<1 and math.min(ad+dc-1,a_a)or +math.min(ad,math.max(0,a_a-dc+1))bd=_d<1 and math.min( +bd+_d-1,b_a)or +math.min(bd,math.max(0,b_a-_d+1))if ad<=0 or +bd<=0 then return self end +bb.multiBlit(self,math.max(1,dc),math.max(1,_d),ad,bd,cd,dd,__a)return self end +function ac:textFg(dc,_d,ad,bd)local cd,dd=self.get("width"),self.get("height")if +_d<1 or _d>dd then return self end;local __a=dc<1 and(2 -dc)or 1 +local a_a=math.min(#ad- +__a+1,cd-math.max(1,dc)+1)if a_a<=0 then return self end +bb.textFg(self,math.max(1,dc),math.max(1,_d),ad:sub(__a, +__a+a_a-1),bd)return self end +function ac:textBg(dc,_d,ad,bd)local cd,dd=self.get("width"),self.get("height")if +_d<1 or _d>dd then return self end;local __a=dc<1 and(2 -dc)or 1 +local a_a=math.min(#ad- +__a+1,cd-math.max(1,dc)+1)if a_a<=0 then return self end +bb.textBg(self,math.max(1,dc),math.max(1,_d),ad:sub(__a, +__a+a_a-1),bd)return self end +function ac:drawText(dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if _d<1 or +_d>cd then return self end;local dd=dc<1 and(2 -dc)or 1 +local __a=math.min( +#ad-dd+1,bd-math.max(1,dc)+1)if __a<=0 then return self end +bb.drawText(self,math.max(1,dc),math.max(1,_d),ad:sub(dd, +dd+__a-1))return self end +function ac:drawFg(dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if +_d<1 or _d>cd then return self end;local dd=dc<1 and(2 -dc)or 1 +local __a=math.min(#ad- +dd+1,bd-math.max(1,dc)+1)if __a<=0 then return self end +bb.drawFg(self,math.max(1,dc),math.max(1,_d),ad:sub(dd,dd+__a-1))return self end +function ac:drawBg(dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if +_d<1 or _d>cd then return self end;local dd=dc<1 and(2 -dc)or 1 +local __a=math.min(#ad- +dd+1,bd-math.max(1,dc)+1)if __a<=0 then return self end +bb.drawBg(self,math.max(1,dc),math.max(1,_d),ad:sub(dd,dd+__a-1))return self end +function ac:blit(dc,_d,ad,bd,cd)local dd,__a=self.get("width"),self.get("height")if +_d<1 or _d>__a then return self end;local a_a=dc<1 and(2 -dc)or 1 +local b_a=math.min( +#ad-a_a+1,dd-math.max(1,dc)+1) +local c_a=math.min(#bd-a_a+1,dd-math.max(1,dc)+1) +local d_a=math.min(#cd-a_a+1,dd-math.max(1,dc)+1)if b_a<=0 then return self end;local _aa=ad:sub(a_a,a_a+b_a-1)local aaa=bd:sub(a_a, +a_a+c_a-1) +local baa=cd:sub(a_a,a_a+d_a-1) +bb.blit(self,math.max(1,dc),math.max(1,_d),_aa,aaa,baa)return self end +function ac:render()bb.render(self)if not self.get("childrenSorted")then +self:sortChildren()end +if +not self.get("childrenEventsSorted")then for dc in pairs(self._values.childrenEvents)do +self:sortChildrenEvents(dc)end end;for dc,_d in ipairs(self.get("visibleChildren"))do if _d==self then +ab.error("CIRCULAR REFERENCE DETECTED!")return end;_d:render() +_d:postRender()end end +function ac:applyLayout(dc,_d) +if self._layoutInstance then cb.destroy(self._layoutInstance)end;self._layoutInstance=cb.apply(self,dc)if _d then +self._layoutInstance.options=_d end;return self end;function ac:updateLayout() +if self._layoutInstance then cb.update(self._layoutInstance)end;return self end +function ac:clearLayout() +if +self._layoutInstance then local dc=require("layoutManager") +dc.destroy(self._layoutInstance)self._layoutInstance=nil end;return self end +function ac:destroy() +if not self:isType("BaseFrame")then +for dc,_d in +ipairs(self._values.children)do if _d.destroy then _d:destroy()end end;self:removeAllObservers()bb.destroy(self)return self else +ab.header="Basalt Error"ab.error("Cannot destroy a BaseFrame.")end end;return ac end +project["elements/Dialog.lua"] = function(...) local d=require("elementManager") +local _a=d.getElement("Frame")local aa=setmetatable({},_a)aa.__index=aa +aa.defineProperty(aa,"title",{default="",type="string",canTriggerRender=true}) +aa.defineProperty(aa,"primaryColor",{default=colors.lime,type="color"}) +aa.defineProperty(aa,"secondaryColor",{default=colors.lightGray,type="color"}) +aa.defineProperty(aa,"buttonForeground",{default=colors.black,type="color"}) +aa.defineProperty(aa,"modal",{default=true,type="boolean"})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"close") +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("z",100)ba.set("width",30) +ba.set("height",10)ba.set("background",colors.gray) +ba.set("foreground",colors.white)ba.set("borderColor",colors.cyan)return ba end +function aa:init(ba,ca)_a.init(self,ba,ca) +self:addBorder({left=true,right=true,top=true,bottom=true})self.set("type","Dialog")return self end +function aa:show()self:center()self.set("visible",true)if +self.get("modal")then self:setFocused(true)end;return self end;function aa:close()self.set("visible",false) +self:fireEvent("close")return self end +function aa:alert(ba,ca,da)self:clear() +self.set("title",ba)self.set("height",8) +self:addLabel({text=ca,x=2,y=3,width=self.get("width")-3,height=3,foreground=colors.white})local _b=10 +local ab=math.floor((self.get("width")-_b)/2)+1 +self:addButton({text="OK",x=ab,y=self.get("height")-2,width=_b,height=1,background=self.get("primaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +da then da()end;self:close()end)return self:show()end +function aa:confirm(ba,ca,da)self:clear()self.set("title",ba) +self.set("height",8) +self:addLabel({text=ca,x=2,y=3,width=self.get("width")-3,height=3,foreground=colors.white})local _b=10;local ab=2;local bb=_b*2 +ab;local cb= +math.floor((self.get("width")-bb)/2)+1 +self:addButton({text="Cancel",x=cb,y= +self.get("height")-2,width=_b,height=1,background=self.get("secondaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +da then da(false)end;self:close()end) +self:addButton({text="OK",x=cb+_b+ab,y=self.get("height")-2,width=_b,height=1,background=self.get("primaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +da then da(true)end;self:close()end)return self:show()end +function aa:prompt(ba,ca,da,_b)self:clear()self.set("title",ba) +self.set("height",11) +self:addLabel({text=ca,x=2,y=3,foreground=colors.white}) +local ab=self:addInput({x=2,y=5,width=self.get("width")-3,height=1,defaultText=da or"",background=colors.white,foreground=colors.black})local bb=10;local cb=2;local db=bb*2 +cb;local _c= +math.floor((self.get("width")-db)/2)+1 +self:addButton({text="Cancel",x=_c,y= +self.get("height")-2,width=bb,height=1,background=self.get("secondaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +_b then _b(nil)end;self:close()end) +self:addButton({text="OK",x=_c+bb+cb,y=self.get("height")-2,width=bb,height=1,background=self.get("primaryColor"),foreground=self.get("buttonForeground")}):onClick(function()if +_b then _b(ab.get("text")or"")end +self:close()end)return self:show()end +function aa:render()_a.render(self)local ba=self.get("title")if ba~=""then +local ca=self.get("width")local da=ba:sub(1,ca-4) +self:textFg(2,2,da,colors.white)end end +function aa:mouse_click(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then return +_a.mouse_click(self,ba,ca,da)end;return true end;return _a.mouse_click(self,ba,ca,da)end +function aa:mouse_drag(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then +return _a.mouse_drag and +_a.mouse_drag(self,ba,ca,da)or false end;return true end;return +_a.mouse_drag and _a.mouse_drag(self,ba,ca,da)or false end +function aa:mouse_up(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then +return _a.mouse_up and +_a.mouse_up(self,ba,ca,da)or false end;return true end;return +_a.mouse_up and _a.mouse_up(self,ba,ca,da)or false end +function aa:mouse_scroll(ba,ca,da) +if self.get("modal")then if self:isInBounds(ca,da)then +return _a.mouse_scroll and +_a.mouse_scroll(self,ba,ca,da)or false end;return true end;return +_a.mouse_scroll and _a.mouse_scroll(self,ba,ca,da)or false end;return aa end +project["elements/Tree.lua"] = function(...) local aa=require("elements/VisualElement")local ba=string.sub +local ca=require("libraries/colorHex") +local function da(ab,bb,cb,db)db=db or{}cb=cb or 0;for _c,ac in ipairs(ab)do +table.insert(db,{node=ac,level=cb}) +if bb[ac]and ac.children then da(ac.children,bb,cb+1,db)end end;return db end;local _b=setmetatable({},aa)_b.__index=_b +_b.defineProperty(_b,"nodes",{default={},type="table",canTriggerRender=true,setter=function(ab,bb)if#bb>0 then +ab.get("expandedNodes")[bb[1]]=true end;return bb end}) +_b.defineProperty(_b,"selectedNode",{default=nil,type="table",canTriggerRender=true}) +_b.defineProperty(_b,"expandedNodes",{default={},type="table",canTriggerRender=true}) +_b.defineProperty(_b,"offset",{default=0,type="number",canTriggerRender=true,setter=function(ab,bb)return math.max(0,bb)end}) +_b.defineProperty(_b,"horizontalOffset",{default=0,type="number",canTriggerRender=true,setter=function(ab,bb)return math.max(0,bb)end}) +_b.defineProperty(_b,"selectedForegroundColor",{default=colors.white,type="color"}) +_b.defineProperty(_b,"selectedBackgroundColor",{default=colors.lightBlue,type="color"}) +_b.defineProperty(_b,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarBackground",{default="\127",type="string",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +_b.defineEvent(_b,"mouse_drag")_b.defineEvent(_b,"mouse_up") +_b.defineEvent(_b,"mouse_scroll")function _b.new()local ab=setmetatable({},_b):__init() +ab.class=_b;ab.set("width",30)ab.set("height",10)ab.set("z",5) +return ab end +function _b:init(ab,bb) +aa.init(self,ab,bb)self.set("type","Tree")return self end;function _b:expandNode(ab)self.get("expandedNodes")[ab]=true +self:updateRender()return self end +function _b:collapseNode(ab)self.get("expandedNodes")[ab]= +nil;self:updateRender()return self end;function _b:toggleNode(ab)if self.get("expandedNodes")[ab]then +self:collapseNode(ab)else self:expandNode(ab)end +return self end +function _b:mouse_click(ab,bb,cb) +if +aa.mouse_click(self,ab,bb,cb)then local db,_c=self:getRelativePosition(bb,cb) +local ac=self.get("width")local bc=self.get("height") +local cc=da(self.get("nodes"),self.get("expandedNodes"))local dc=self.get("showScrollBar") +local _d,ad=self:getNodeSize()local bd=dc and _d>ac;local cd=bd and bc-1 or bc +local dd=dc and#cc>cd +if dd and db==ac and(not bd or _c0 and(self.get("offset")/c_a*100)or 0;local _aa= +math.floor((d_a/100)* (a_a-b_a))+1 +if _c>=_aa and _c<_aa+b_a then +self._scrollBarDragging=true;self._scrollBarDragOffset=_c-_aa else +local aaa=( (_c-1)/ (a_a-b_a))*100;local baa=math.floor((aaa/100)*c_a+0.5) +self.set("offset",math.max(0,math.min(c_a,baa)))end;return true end +if bd and _c==bc and(not dd or db0 and +(self.get("horizontalOffset")/c_a*100)or 0 +local _aa=math.floor((d_a/100)* (a_a-b_a))+1 +if db>=_aa and db<_aa+b_a then self._hScrollBarDragging=true;self._hScrollBarDragOffset= +db-_aa else local aaa=( (db-1)/ (a_a-b_a))*100;local baa=math.floor(( +aaa/100)*c_a+0.5) +self.set("horizontalOffset",math.max(0,math.min(c_a,baa)))end;return true end;local __a=_c+self.get("offset") +if cc[__a]then local a_a=cc[__a] +local b_a=a_a.node +if db<=a_a.level*2 +2 then self:toggleNode(b_a)end;self.set("selectedNode",b_a) +self:fireEvent("node_select",b_a)end;return true end;return false end +function _b:onSelect(ab)self:registerCallback("node_select",ab)return self end +function _b:mouse_drag(ab,bb,cb) +if self._scrollBarDragging then local db,_c=self:getRelativePosition(bb,cb) +local ac=da(self.get("nodes"),self.get("expandedNodes"))local bc=self.get("height")local cc,dc=self:getNodeSize() +local _d= +self.get("showScrollBar")and cc>self.get("width")local ad=_d and bc-1 or bc;local bd=ad +local cd=math.max(1,math.floor((ad/#ac)*bd))local dd=#ac-ad;_c=math.max(1,math.min(bd,_c))local __a=_c- ( +self._scrollBarDragOffset or 0)local a_a= +( (__a-1)/ (bd-cd))*100 +local b_a=math.floor((a_a/100)*dd+0.5) +self.set("offset",math.max(0,math.min(dd,b_a)))return true end +if self._hScrollBarDragging then local db,_c=self:getRelativePosition(bb,cb) +local ac=self.get("width")local bc,cc=self:getNodeSize() +local dc=da(self.get("nodes"),self.get("expandedNodes"))local _d=self.get("height") +local ad=self.get("showScrollBar")and bc>ac;local bd=ad and _d-1 or _d +local cd=self.get("showScrollBar")and#dc>bd;local dd=cd and ac-1 or ac +local __a=math.max(1,math.floor((dd/bc)*dd))local a_a=bc-dd;db=math.max(1,math.min(dd,db))local b_a=db- ( +self._hScrollBarDragOffset or 0)local c_a= +( (b_a-1)/ (dd-__a))*100 +local d_a=math.floor((c_a/100)*a_a+0.5) +self.set("horizontalOffset",math.max(0,math.min(a_a,d_a)))return true end;return +aa.mouse_drag and aa.mouse_drag(self,ab,bb,cb)or false end +function _b:mouse_up(ab,bb,cb)if self._scrollBarDragging then self._scrollBarDragging=false +self._scrollBarDragOffset=nil;return true end +if self._hScrollBarDragging then +self._hScrollBarDragging=false;self._hScrollBarDragOffset=nil;return true end;return +aa.mouse_up and aa.mouse_up(self,ab,bb,cb)or false end +function _b:mouse_scroll(ab,bb,cb) +if aa.mouse_scroll(self,ab,bb,cb)then +local db=da(self.get("nodes"),self.get("expandedNodes"))local _c=self.get("height")local ac=self.get("width") +local bc=self.get("showScrollBar")local cc,dc=self:getNodeSize()local _d=bc and cc>ac +local ad=_d and _c-1 or _c;local bd=math.max(0,#db-ad) +local cd=math.min(bd,math.max(0,self.get("offset")+ab))self.set("offset",cd)return true end;return false end +function _b:getNodeSize()local ab,bb=0,0 +local cb=da(self.get("nodes"),self.get("expandedNodes"))local db=self.get("expandedNodes") +for _c,ac in ipairs(cb)do local bc=ac.node +local cc=ac.level;local dc=string.rep(" ",cc)local _d=" "if +bc.children and#bc.children>0 then _d=db[bc]and"\31"or"\16"end +local ad=dc.._d.. +" ".. (bc.text or"Node")ab=math.max(ab,#ad)end;bb=#cb;return ab,bb end +function _b:render()aa.render(self) +local ab=da(self.get("nodes"),self.get("expandedNodes"))local bb=self.get("height")local cb=self.get("width") +local db=self.get("selectedNode")local _c=self.get("expandedNodes") +local ac=self.get("offset")local bc=self.get("horizontalOffset") +local cc=self.get("showScrollBar")local dc,_d=self:getNodeSize()local ad=cc and dc>cb +local bd=ad and bb-1 or bb;local cd=cc and#ab>bd;local dd=cd and cb-1 or cb +for y=1,bd do +local _aa=ab[y+ac] +if _aa then local aaa=_aa.node;local baa=_aa.level;local caa=string.rep(" ",baa) +local daa=" "if aaa.children and#aaa.children>0 then +daa=_c[aaa]and"\31"or"\16"end;local _ba=aaa==db +local aba=_ba and +self.get("selectedBackgroundColor")or +(aaa.background or aaa.bg or self.get("background")) +local bba=_ba and self.get("selectedForegroundColor")or( +aaa.foreground or aaa.fg or self.get("foreground")) +local cba=caa..daa.." ".. (aaa.text or"Node")local dba=ba(cba,bc+1,bc+dd) +local _ca=dba..string.rep(" ",dd-#dba) +local aca=ca[aba]:rep(#_ca)or ca[colors.black]:rep(#_ca) +local bca=ca[bba]:rep(#_ca)or ca[colors.white]:rep(#_ca)self:blit(1,y,_ca,bca,aca)else +self:blit(1,y,string.rep(" ",dd),ca[self.get("foreground")]:rep(dd),ca[self.get("background")]:rep(dd))end end;local __a=self.getResolved("scrollBarSymbol") +local a_a=self.getResolved("scrollBarBackground")local b_a=self.getResolved("scrollBarColor") +local c_a=self.getResolved("scrollBarBackgroundColor")local d_a=self.getResolved("foreground") +if cd then +local _aa=ad and bb-1 or bb +local aaa=math.max(1,math.floor((bd/#ab)*_aa))local baa=#ab-bd;local caa=baa>0 and(ac/baa*100)or 0 +local daa=math.floor(( +caa/100)* (_aa-aaa))+1 +for i=1,_aa do self:blit(cb,i,a_a,ca[d_a],ca[c_a])end;for i=daa,math.min(_aa,daa+aaa-1)do +self:blit(cb,i,__a,ca[b_a],ca[c_a])end end +if ad then local _aa=cd and cb-1 or cb +local aaa=math.max(1,math.floor((_aa/dc)*_aa))local baa=dc-dd;local caa=baa>0 and(bc/baa*100)or 0 +local daa=math.floor(( +caa/100)* (_aa-aaa))+1 +for i=1,_aa do self:blit(i,bb,a_a,ca[d_a],ca[c_a])end;for i=daa,math.min(_aa,daa+aaa-1)do +self:blit(i,bb,__a,ca[b_a],ca[c_a])end end;if cd and ad then +self:blit(cb,bb," ",ca[d_a],ca[self.get("background")])end end;return _b end +project["elements/DropDown.lua"] = function(...) local _a=require("elements/VisualElement") +local aa=require("elements/List")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"dropdownHeight",{default=5,type="number"}) +ca.defineProperty(ca,"selectedText",{default="",type="string"}) +ca.defineProperty(ca,"dropSymbol",{default="\31",type="string"})function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",16)da.set("height",1)da.set("z",8) +return da end;function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","DropDown") +self:registerState("opened",nil,200)return self end +function ca:mouse_click(da,_b,ab) +if +not _a.mouse_click(self,da,_b,ab)then return false end;local bb,cb=self:getRelativePosition(_b,ab) +local db=self:hasState("opened") +if cb==1 then +if db then self.set("height",1)self:unsetState("opened")else +self.set("height", +1 + +math.min(self.get("dropdownHeight"),#self.get("items")))self:setState("opened")end;return true elseif db and cb>1 then return aa.mouse_click(self,da,_b,ab-1)end;return false end +function ca:mouse_drag(da,_b,ab)if self:hasState("opened")then +return aa.mouse_drag(self,da,_b,ab-1)end;return +_a.mouse_drag and _a.mouse_drag(self,da,_b,ab)or false end +function ca:mouse_up(da,_b,ab) +if self:hasState("opened")then +local bb,cb=self:getRelativePosition(_b,ab) +if +cb>1 and self.get("selectable")and not self._scrollBarDragging then local db=(cb-1)+self.get("offset") +local _c=self.get("items") +if db<=#_c then local ac=_c[db] +if type(ac)=="string"then ac={text=ac}_c[db]=ac end +if not self.get("multiSelection")then for bc,cc in ipairs(_c)do if type(cc)=="table"then +cc.selected=false end end end;ac.selected=not ac.selected +if ac.callback then ac.callback(self)end;self:fireEvent("select",db,ac) +self:unsetState("opened")self:unsetState("clicked")self.set("height",1) +self:updateRender()return true end end;aa.mouse_up(self,da,_b,ab-1) +self:unsetState("clicked")return true end;return +_a.mouse_up and _a.mouse_up(self,da,_b,ab)or false end +function ca:render()_a.render(self)local da=self.get("selectedText") +local _b=self:hasState("opened")local ab=self:getSelectedItems() +if#ab>0 then local bb=ab[1] +da=bb.text or""da=da:sub(1,self.get("width")-2)end +if _b then local bb=self.get("height")local cb=math.min(self.get("dropdownHeight"),# +self.get("items")) +self.set("height",cb)aa.render(self,1)self.set("height",bb)end +self:blit(1,1,da.. +string.rep(" ",self.get("width")-#da-1).. (_b and"\31"or"\17"),string.rep(ba[self.getResolved("foreground")],self.get("width")),string.rep(ba[self.getResolved("background")],self.get("width")))end;function ca:focus()_a.focus(self)self:prioritize() +self:setState("opened")end +function ca:blur()_a.blur(self) +self:unsetState("opened")self.set("height",1)self:updateRender()end;return ca end +project["elements/Display.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("VisualElement") +local da=require("libraries/utils").getCenteredPosition;local _b=require("libraries/utils").deepcopy +local ab=require("libraries/colorHex")local bb=setmetatable({},ca)bb.__index=bb;function bb.new() +local cb=setmetatable({},bb):__init()cb.class=bb;cb.set("width",25)cb.set("height",8) +cb.set("z",5)return cb end +function bb:init(cb,db) +ca.init(self,cb,db)self.set("type","Display") +self._window=window.create(db.getActiveFrame():getTerm(),1,1,self.get("width"),self.get("height"),false)local _c=self._window.reposition;local ac=self._window.blit +local bc=self._window.write +self._window.reposition=function(cc,dc,_d,ad)self.set("x",cc)self.set("y",dc) +self.set("width",_d)self.set("height",ad)_c(1,1,_d,ad)end +self._window.getPosition=function(cc)return cc.get("x"),cc.get("y")end +self._window.setVisible=function(cc)self.set("visible",cc)end +self._window.isVisible=function(cc)return cc.get("visible")end +self._window.blit=function(cc,dc,_d,ad,bd)ac(cc,dc,_d,ad,bd)self:updateRender()end +self._window.write=function(cc,dc,_d)bc(cc,dc,_d)self:updateRender()end +self:observe("width",function(cc,dc)local _d=cc._window;if _d then +_d.reposition(1,1,dc,cc.get("height"))end end) +self:observe("height",function(cc,dc)local _d=cc._window;if _d then +_d.reposition(1,1,cc.get("width"),dc)end end)end;function bb:getWindow()return self._window end +function bb:write(cb,db,_c,ac,bc)local cc=self._window +if cc then if ac then +cc.setTextColor(ac)end;if bc then cc.setBackgroundColor(bc)end +cc.setCursorPos(cb,db)cc.write(_c)end;self:updateRender()return self end +function bb:render()ca.render(self)local cb=self._window;local db,_c=cb.getSize() +if cb then for y=1,_c do +local ac,bc,cc=cb.getLine(y)self:blit(1,y,ac,bc,cc)end end end;return bb end +project["elements/Breadcrumb.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"path",{default={},type="table",canTriggerRender=true}) +ca.defineProperty(ca,"separator",{default=" > ",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"clickable",{default=true,type="boolean"}) +ca.defineProperty(ca,"autoSize",{default=true,type="boolean"})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up") +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("z",5)da.set("height",1) +da.set("backgroundEnabled",false)return da end;function ca:init(da,_b)aa.init(self,da,_b) +self.set("type","Breadcrumb")end +function ca:mouse_click(da,_b,ab)if +not self.get("clickable")then return false end +if aa.mouse_click(self,da,_b,ab)then +local bb=self.get("path")local cb=self.get("separator")local db=1 +for _c,ac in ipairs(bb)do local bc=#ac;if +_b>=db and _bcb then local bc="... > "local cc=cb- +#bc +if cc>0 then db=bc..db:sub(-cc)else db=bc:sub(1,cb)end end end;local _c=1;local ac +for bc in db:gmatch("[^".._b.."]+")do ac=ab +self:textFg(_c,1,bc,ac)_c=_c+#bc;local cc=db:find(_b,_c,true)if cc then +self:textFg(_c,1,_b,bb and colors.gray or +colors.lightGray)_c=_c+#_b end end end;return ca end +project["elements/LineChart.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("VisualElement")local da=ba.getElement("Graph") +local _b=require("libraries/colorHex")local ab=setmetatable({},da)ab.__index=ab;function ab.new() +local cb=setmetatable({},ab):__init()cb.class=ab;return cb end +function ab:init(cb,db) +da.init(self,cb,db)self.set("type","LineChart")return self end +local function bb(cb,db,_c,ac,bc,cc,dc,_d)local ad=ac-db;local bd=bc-_c +local cd=math.max(math.abs(ad),math.abs(bd)) +for i=0,cd do local dd=cd==0 and 0 or i/cd +local __a=math.floor(db+ad*dd)local a_a=math.floor(_c+bd*dd) +if + +__a>=1 and __a<=cb.get("width")and a_a>=1 and a_a<=cb.get("height")then cb:blit(__a,a_a,cc,_b[dc],_b[_d])end end end +function ab:render()ca.render(self)local cb=self.get("width") +local db=self.get("height")local _c=self.get("minValue")local ac=self.get("maxValue") +local bc=self.get("series") +for cc,dc in pairs(bc)do +if(dc.visible)then local _d,ad;local bd=#dc.data +local cd=(cb-1)/math.max((bd-1),1) +for dd,__a in ipairs(dc.data)do local a_a=math.floor(( (dd-1)*cd)+1)local b_a= +(__a-_c)/ (ac-_c) +local c_a=math.floor(db- (b_a* (db-1)))c_a=math.max(1,math.min(c_a,db))if _d then +bb(self,_d,ad,a_a,c_a,dc.symbol,dc.bgColor,dc.fgColor)end;_d,ad=a_a,c_a end end end end;return ab end +project["elements/Graph.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"minValue",{default=0,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"maxValue",{default=100,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"series",{default={},type="table",canTriggerRender=true})function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;return da end;function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","Graph")self.set("width",20) +self.set("height",10)return self end +function ca:addSeries(da,_b,ab,bb,cb) +local db=self.get("series") +table.insert(db,{name=da,symbol=_b or" ",bgColor=ab or colors.white,fgColor=bb or colors.black,pointCount=cb or self.get("width"),data={},visible=true})self:updateRender()return self end +function ca:removeSeries(da)local _b=self.get("series")for ab,bb in ipairs(_b)do if bb.name==da then +table.remove(_b,ab)break end end +self:updateRender()return self end +function ca:getSeries(da)local _b=self.get("series")for ab,bb in ipairs(_b)do +if bb.name==da then return bb end end;return nil end +function ca:changeSeriesVisibility(da,_b)local ab=self.get("series")for bb,cb in ipairs(ab)do if cb.name==da then +cb.visible=_b;break end end +self:updateRender()return self end +function ca:addPoint(da,_b)local ab=self.get("series") +for bb,cb in ipairs(ab)do if cb.name==da then +table.insert(cb.data,_b) +while#cb.data>cb.pointCount do table.remove(cb.data,1)end;break end end;self:updateRender()return self end +function ca:focusSeries(da)local _b=self.get("series") +for ab,bb in ipairs(_b)do if bb.name==da then +table.remove(_b,ab)table.insert(_b,bb)break end end;self:updateRender()return self end +function ca:setSeriesPointCount(da,_b)local ab=self.get("series") +for bb,cb in ipairs(ab)do if cb.name==da then +cb.pointCount=_b;while#cb.data>_b do table.remove(cb.data,1)end +break end end;self:updateRender()return self end +function ca:clear(da)local _b=self.get("series") +if da then for ab,bb in ipairs(_b)do +if bb.name==da then bb.data={}break end end else for ab,bb in ipairs(_b)do bb.data={}end end;return self end +function ca:render()aa.render(self)local da=self.get("width") +local _b=self.get("height")local ab=self.get("minValue")local bb=self.get("maxValue") +local cb=self.get("series") +for db,_c in pairs(cb)do +if(_c.visible)then local ac=#_c.data +local bc=(da-1)/math.max((ac-1),1) +for cc,dc in ipairs(_c.data)do local _d=math.floor(( (cc-1)*bc)+1)local ad= +(dc-ab)/ (bb-ab) +local bd=math.floor(_b- (ad* (_b-1)))bd=math.max(1,math.min(bd,_b)) +self:blit(_d,bd,_c.symbol,ba[_c.bgColor],ba[_c.fgColor])end end end end;return ca end +project["elements/Table.lua"] = function(...) local _a=require("elements/Collection") +local aa=require("libraries/colorHex")local ba=setmetatable({},_a)ba.__index=ba +ba.defineProperty(ba,"columns",{default={},type="table",canTriggerRender=true,setter=function(da,_b)local ab={} +for bb,cb in +ipairs(_b)do +if type(cb)=="string"then ab[bb]={name=cb,width=#cb+1}elseif type(cb)=="table"then +ab[bb]={name= +cb.name or"",width=cb.width,minWidth=cb.minWidth or 3,maxWidth=cb.maxWidth or nil}end end;return ab end}) +ba.defineProperty(ba,"headerColor",{default=colors.blue,type="color"}) +ba.defineProperty(ba,"gridColor",{default=colors.gray,type="color"}) +ba.defineProperty(ba,"sortColumn",{default=nil,type="number",canTriggerRender=true}) +ba.defineProperty(ba,"sortDirection",{default="asc",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"customSortFunction",{default={},type="table"}) +ba.defineProperty(ba,"offset",{default=0,type="number",canTriggerRender=true,setter=function(da,_b)local ab=math.max(0,#da.get("items")- +(da.get("height")-1))return +math.min(ab,math.max(0,_b))end}) +ba.defineProperty(ba,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackground",{default="\127",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true})ba.defineEvent(ba,"mouse_click") +ba.defineEvent(ba,"mouse_drag")ba.defineEvent(ba,"mouse_up") +ba.defineEvent(ba,"mouse_scroll") +local ca={cells={type="table",default={}},_sortValues={type="table",default={}},selected={type="boolean",default=false},text={type="string",default=""}}function ba.new()local da=setmetatable({},ba):__init() +da.class=ba;da.set("width",30)da.set("height",10)da.set("z",5) +return da end +function ba:init(da,_b) +_a.init(self,da,_b)self._entrySchema=ca;self.set("type","Table") +self:observe("sortColumn",function() +if +self.get("sortColumn")then self:sortByColumn(self.get("sortColumn"))end end)return self end;function ba:addRow(...)local da={...} +_a.addItem(self,{cells=da,_sortValues=da,text=table.concat(da," ")})return self end;function ba:removeRow(da) +local _b=self.get("items") +if _b[da]then table.remove(_b,da)self.set("items",_b)end;return self end;function ba:getRow(da) +local _b=self.get("items")return _b[da]end +function ba:updateCell(da,_b,ab) +local bb=self.get("items")if bb[da]and bb[da].cells then bb[da].cells[_b]=ab +self.set("items",bb)end;return self end +function ba:getSelectedRow()local da=self.get("items")for _b,ab in ipairs(da)do local bb= +ab._data and ab._data.selected or ab.selected +if bb then return ab end end;return nil end;function ba:clearData()self.set("items",{})return self end;function ba:addColumn(da,_b) +local ab=self.get("columns")table.insert(ab,{name=da,width=_b}) +self.set("columns",ab)return self end +function ba:setColumnSortFunction(da,_b) +local ab=self.get("customSortFunction")ab[da]=_b;self.set("customSortFunction",ab)return self end +function ba:setData(da,_b)self:clearData() +for ab,bb in ipairs(da)do local cb={}local db={} +for _c,ac in ipairs(bb)do db[_c]=ac;if _b and +_b[_c]then cb[_c]=_b[_c](ac)else cb[_c]=ac end end +_a.addItem(self,{cells=cb,_sortValues=db,text=table.concat(cb," ")})end;return self end +function ba:getData()local da=self.get("items")local _b={}for ab,bb in ipairs(da)do local cb= +bb._data and bb._data.cells or bb.cells;if cb then +table.insert(_b,cb)end end +return _b end +function ba:calculateColumnWidths(da,_b)local ab={}local bb=_b;local cb={}local db=0 +for ac,bc in ipairs(da)do +ab[ac]={name=bc.name,width=bc.width,minWidth=bc.minWidth or 3,maxWidth=bc.maxWidth} +if type(bc.width)=="number"then +ab[ac].visibleWidth=math.max(bc.width,ab[ac].minWidth)if ab[ac].maxWidth then +ab[ac].visibleWidth=math.min(ab[ac].visibleWidth,ab[ac].maxWidth)end +bb=bb-ab[ac].visibleWidth;db=db+ab[ac].visibleWidth elseif type(bc.width)=="string"and +bc.width:match("%%$")then +local cc=tonumber(bc.width:match("(%d+)%%")) +if cc then ab[ac].visibleWidth=math.floor(_b*cc/100) +ab[ac].visibleWidth=math.max(ab[ac].visibleWidth,ab[ac].minWidth)if ab[ac].maxWidth then +ab[ac].visibleWidth=math.min(ab[ac].visibleWidth,ab[ac].maxWidth)end +bb=bb-ab[ac].visibleWidth;db=db+ab[ac].visibleWidth else table.insert(cb,ac)end else table.insert(cb,ac)end end +if#cb>0 and bb>0 then local ac=math.floor(bb/#cb) +for bc,cc in ipairs(cb)do +ab[cc].visibleWidth=math.max(ac,ab[cc].minWidth)if ab[cc].maxWidth then +ab[cc].visibleWidth=math.min(ab[cc].visibleWidth,ab[cc].maxWidth)end end end;local _c=0 +for ac,bc in ipairs(ab)do _c=_c+ (bc.visibleWidth or 0)end;if _c>_b then local ac=_b/_c +for bc,cc in ipairs(ab)do if cc.visibleWidth then +cc.visibleWidth=math.max(1,math.floor(cc.visibleWidth*ac))end end end +return ab end +function ba:sortByColumn(da,_b)local ab=self.get("items") +local bb=self.get("sortDirection")local cb=self.get("customSortFunction")local db=_b or cb[da] +if db then +table.sort(ab,function(_c,ac)return +db(_c,ac,bb)end)else +table.sort(ab,function(_c,ac) +local bc=_c._data and _c._data.cells or _c.cells +local cc=ac._data and ac._data.cells or ac.cells +local dc=_c._data and _c._data._sortValues or _c._sortValues +local _d=ac._data and ac._data._sortValues or ac._sortValues +if not _c or not ac or not bc or not cc then return false end;local ad,bd;if dc and dc[da]then ad=dc[da]else ad=bc[da]end;if _d and _d[da]then +bd=_d[da]else bd=cc[da]end +if +type(ad)=="number"and type(bd)=="number"then if bb=="asc"then return adbd end else +local cd=tostring(ad or"")local dd=tostring(bd or"") +if bb=="asc"then return cd
dd end end end)end;self.set("items",ab)return self end +function ba:onRowSelect(da)self:registerCallback("rowSelect",da)return self end +function ba:mouse_click(da,_b,ab) +if not _a.mouse_click(self,da,_b,ab)then return false end;local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("width")local _c=self.get("height")local ac=self.get("items") +local bc=self.get("showScrollBar")local cc=_c-1 +if bc and#ac>cc and bb==db and cb>1 then local dc=_c-1 +local _d=#ac-cc +local ad=math.max(1,math.floor((cc/#ac)*dc)) +local bd=_d>0 and(self.get("offset")/_d*100)or 0 +local cd=math.floor((bd/100)* (dc-ad))+1;local dd=cb-1 +if dd>=cd and dd=ad and bb1 then local dc=cb-2 +self.get("offset") +if dc>=0 and dc<#ac then +local _d=dc+1;for ad,bd in ipairs(ac)do +if bd._data then bd._data.selected=false else bd.selected=false end end +if ac[_d]then if ac[_d]._data then +ac[_d]._data.selected=true else ac[_d].selected=true end +self:fireEvent("rowSelect",_d,ac[_d])self:updateRender()end end;return true end;return true end +function ba:mouse_drag(da,_b,ab) +if self._scrollBarDragging then local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("items")local _c=self.get("height")local ac=_c-1;local bc=_c-1 +local cc=math.max(1,math.floor((ac/#db)*bc))local dc=#db-ac;local _d=cb-1 +_d=math.max(1,math.min(bc,_d))local ad=_d- (self._scrollBarDragOffset or 0)local bd=( +(ad-1)/ (bc-cc))*100 +local cd=math.floor((bd/100)*dc+0.5) +self.set("offset",math.max(0,math.min(dc,cd)))return true end;return +_a.mouse_drag and _a.mouse_drag(self,da,_b,ab)or false end +function ba:mouse_up(da,_b,ab)if self._scrollBarDragging then self._scrollBarDragging=false +self._scrollBarDragOffset=nil;return true end +return _a.mouse_up and +_a.mouse_up(self,da,_b,ab)or false end +function ba:mouse_scroll(da,_b,ab) +if _a.mouse_scroll(self,da,_b,ab)then local bb=self.get("items") +local cb=self.get("height")local db=cb-1;local _c=math.max(0,#bb-db) +local ac=math.min(_c,math.max(0, +self.get("offset")+da))self.set("offset",ac)self:updateRender()return true end;return false end +function ba:render()_a.render(self)local da=self.getResolved("columns") +local _b=self.getResolved("items")local ab=self.getResolved("sortColumn") +local bb=self.getResolved("offset")local cb=self.get("height")local db=self.get("width") +local _c=self.getResolved("showScrollBar")local ac=cb-1;local bc=_c and#_b>ac;local cc=bc and db-1 or db +local dc=self:calculateColumnWidths(da,cc)local _d=0;local ad=#dc +for cd,dd in ipairs(dc)do +if _d+dd.visibleWidth>cc then ad=cd-1;break end;_d=_d+dd.visibleWidth end;local bd=1 +for cd,dd in ipairs(dc)do if cd>ad then break end;local __a=dd.name;if cd==ab then +__a=__a.. ( +self.get("sortDirection")=="asc"and"\30"or"\31")end +self:textFg(bd,1,__a:sub(1,dd.visibleWidth),self.get("headerColor"))bd=bd+dd.visibleWidth end;if bd<=cc then +self:textBg(bd,1,string.rep(" ",cc-bd+1),self.get("background"))end +for y=2,cb do local cd=y-2 +bb;local dd=_b[cd+1] +if +dd then +local __a=dd._data and dd._data.cells or dd.cells +local a_a=dd._data and dd._data.selected or dd.selected +if __a then bd=1;local b_a=a_a and self.get("selectedBackground")or +self.get("background") +for c_a,d_a in +ipairs(dc)do if c_a>ad then break end;local _aa=tostring(__a[c_a]or"") +local aaa=_aa..string.rep(" ", +d_a.visibleWidth-#_aa)if c_a0 and(bb/__a*100)or 0 +local b_a=math.floor(( +a_a/100)* (cd-dd))+1;local c_a=self.getResolved("scrollBarSymbol") +local d_a=self.getResolved("scrollBarBackground")local _aa=self.getResolved("scrollBarColor") +local aaa=self.getResolved("scrollBarBackgroundColor")local baa=self.getResolved("foreground")for i=2,cb do +self:blit(db,i,d_a,aa[baa],aa[aaa])end;for i=b_a,math.min(cd,b_a+dd-1)do +self:blit(db,i+1,c_a,aa[_aa],aa[aaa])end end end;return ba end +project["elements/Menu.lua"] = function(...) local _a=require("elements/VisualElement") +local aa=require("elements/List")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"separatorColor",{default=colors.gray,type="color"}) +ca.defineProperty(ca,"spacing",{default=1,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"horizontalOffset",{default=0,type="number",canTriggerRender=true,setter=function(da,_b) +local ab=math.max(0,da:getTotalWidth()-da.get("width"))return math.min(ab,math.max(0,_b))end}) +ca.defineProperty(ca,"maxWidth",{default=nil,type="number",canTriggerRender=true}) +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",30)da.set("height",1) +da.set("background",colors.gray)return da end +function ca:init(da,_b)aa.init(self,da,_b)self.set("type","Menu") +self:observe("items",function() +local ab=self.get("maxWidth")if ab then +self.set("width",math.min(ab,self:getTotalWidth()),true)else +self.set("width",self:getTotalWidth(),true)end end)return self end +function ca:getTotalWidth()local da=self.get("items")local _b=self.get("spacing") +local ab=0;for bb,cb in ipairs(da)do if type(cb)=="table"then ab=ab+#cb.text else ab= +ab+#tostring(cb)+2 end +if bb<#da then ab=ab+_b end end;return ab end +function ca:render()_a.render(self)local da=self.get("width") +local _b=self.get("spacing")local ab=self.get("horizontalOffset") +local bb=self.get("items")local cb={}local db=1 +for _c,ac in ipairs(bb)do if type(ac)=="string"then +ac={text=" "..ac.." "}bb[_c]=ac end +cb[_c]={startX=db,endX=db+#ac.text-1,text=ac.text,item=ac}db=db+#ac.text;if _c<#bb and _b>0 then db=db+_b end end +for _c,ac in ipairs(cb)do local bc=ac.item;local cc=ac.startX-ab;local dc=ac.endX-ab +if cc>da then break end +if dc>=1 then local _d=math.max(1,cc)local ad=math.min(da,dc) +local bd=math.max(1,1 -cc+1) +local cd=math.min(#ac.text,#ac.text- (dc-da))local dd=ac.text:sub(bd,cd) +if#dd>0 then local __a=bc.selected +local a_a= +bc.selectable==false and self.get("separatorColor")or(__a and(bc.selectedForeground or +self.get("selectedForeground"))or(bc.foreground or +self.get("foreground"))) +local b_a= +__a and(bc.selectedBackground or self.get("selectedBackground"))or(bc.background or self.get("background")) +self:blit(_d,1,dd,string.rep(ba[a_a],#dd),string.rep(ba[b_a],#dd))end +if _c<#bb and _b>0 then local __a=ac.endX+1 -ab;local a_a=__a+_b-1 +if a_a>=1 and +__a<=da then local b_a=math.max(1,__a)local c_a=math.min(da,a_a) +local d_a=c_a-b_a+1 +if d_a>0 then local _aa=string.rep(" ",d_a) +self:blit(b_a,1,_aa,string.rep(ba[self.get("foreground")],d_a),string.rep(ba[self.get("background")],d_a))end end end end end end +function ca:mouse_click(da,_b,ab) +if not _a.mouse_click(self,da,_b,ab)then return false end +if(self.get("selectable")==false)then return false end +local bb=select(1,self:getRelativePosition(_b,ab))local cb=self.get("horizontalOffset") +local db=self.get("spacing")local _c=self.get("items")local ac=bb+cb;local bc=1 +for cc,dc in ipairs(_c)do local _d=#dc.text +if ac>= +bc and ac0 then bc=bc+db end end;return false end +function ca:mouse_scroll(da,_b,ab) +if _a.mouse_scroll(self,da,_b,ab)then +local bb=self.get("horizontalOffset") +local cb=math.max(0,self:getTotalWidth()-self.get("width"))bb=math.min(cb,math.max(0,bb+ (da*3))) +self.set("horizontalOffset",bb)return true end;return false end;return ca end +project["elements/Slider.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"step",{default=1,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"max",{default=100,type="number"}) +aa.defineProperty(aa,"horizontal",{default=true,type="boolean",canTriggerRender=true,setter=function(ba,ca)if ca then ba.set("backgroundEnabled",false)else +ba.set("backgroundEnabled",true)end end}) +aa.defineProperty(aa,"barColor",{default=colors.gray,type="color",canTriggerRender=true}) +aa.defineProperty(aa,"sliderColor",{default=colors.blue,type="color",canTriggerRender=true})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"mouse_drag")aa.defineEvent(aa,"mouse_up") +aa.defineEvent(aa,"mouse_scroll") +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",8)ba.set("height",1) +ba.set("backgroundEnabled",false)return ba end +function aa:init(ba,ca)d.init(self,ba,ca)self.set("type","Slider")end +function aa:getValue()local ba=self.get("step")local ca=self.get("max") +local da= +self.get("horizontal")and self.get("width")or self.get("height")return math.floor((ba-1)* (ca/ (da-1)))end +function aa:mouse_click(ba,ca,da) +if self:isInBounds(ca,da)then +local _b,ab=self:getRelativePosition(ca,da) +local bb=self.get("horizontal")and _b or ab;local cb=self.get("horizontal")and self.get("width")or +self.get("height") +self.set("step",math.min(cb,math.max(1,bb)))self:updateRender()return true end;return false end;aa.mouse_drag=aa.mouse_click +function aa:mouse_scroll(ba,ca,da) +if self:isInBounds(ca,da)then +local _b=self.get("step")local ab=self.get("horizontal")and self.get("width")or +self.get("height") +self.set("step",math.min(ab,math.max(1, +_b+ba)))self:updateRender()return true end;return false end +function aa:render()d.render(self)local ba=self.get("width") +local ca=self.get("height")local da=self.get("horizontal")local _b=self.get("step")local ab= +da and"\140"or" " +local bb=string.rep(ab,da and ba or ca) +if da then self:textFg(1,1,bb,self.get("barColor")) +self:textBg(_b,1," ",self.get("sliderColor"))else local cb=self.get("background") +for y=1,ca do self:textBg(1,y," ",cb)end +self:textBg(1,_b," ",self.get("sliderColor"))end end;return aa end +project["elements/ScrollBar.lua"] = function(...) local aa=require("elements/VisualElement") +local ba=require("libraries/colorHex")local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"value",{default=0,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"min",{default=0,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"max",{default=100,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"step",{default=10,type="number"}) +ca.defineProperty(ca,"dragMultiplier",{default=1,type="number"}) +ca.defineProperty(ca,"symbol",{default=" ",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"symbolColor",{default=colors.gray,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"symbolBackgroundColor",{default=colors.black,type="color",canTriggerRender=true}) +ca.defineProperty(ca,"backgroundSymbol",{default="\127",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"attachedElement",{default=nil,type="table"}) +ca.defineProperty(ca,"attachedProperty",{default=nil,type="string"}) +ca.defineProperty(ca,"minValue",{default=0,type="number"}) +ca.defineProperty(ca,"maxValue",{default=100,type="number"}) +ca.defineProperty(ca,"orientation",{default="vertical",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"handleSize",{default=2,type="number",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_release")ca.defineEvent(ca,"mouse_drag") +ca.defineEvent(ca,"mouse_scroll") +function ca.new()local ab=setmetatable({},ca):__init() +ab.class=ca;ab.set("width",1)ab.set("height",10)return ab end;function ca:init(ab,bb)aa.init(self,ab,bb)self.set("type","ScrollBar")return +self end +function ca:attach(ab,bb) +self.set("attachedElement",ab)self.set("attachedProperty",bb.property)self.set("minValue", +bb.min or 0) +self.set("maxValue",bb.max or 100) +ab:observe(bb.property,function(cb,db) +if db then local _c=self.get("minValue") +local ac=self.get("maxValue")if _c==ac then return end +self.set("value",math.floor((db-_c)/ (ac-_c)*100 +0.5))end end)return self end +function ca:updateAttachedElement()local ab=self.get("attachedElement") +if not ab then return end;local bb=self.get("value")local cb=self.get("minValue") +local db=self.get("maxValue")if type(cb)=="function"then cb=cb()end;if type(db)=="function"then +db=db()end;local _c=cb+ (bb/100)* (db-cb)ab.set(self.get("attachedProperty"),math.floor( +_c+0.5)) +return self end;local function da(ab) +return +ab.get("orientation")=="vertical"and ab.get("height")or ab.get("width")end +local function _b(ab,bb,cb) +local db,_c=ab:getRelativePosition(bb,cb)return +ab.get("orientation")=="vertical"and _c or db end +function ca:mouse_click(ab,bb,cb) +if aa.mouse_click(self,ab,bb,cb)then local db=da(self) +local _c=self.get("value")local ac=self.get("handleSize")local bc= +math.floor((_c/100)* (db-ac))+1;local cc=_b(self,bb,cb) +if +cc>=bc and cc0 and-1 or 1;local db=self.get("step") +local _c=self.get("value")local ac=_c-ab*db +self.set("value",math.min(100,math.max(0,ac)))self:updateAttachedElement()return true end +function ca:render()aa.render(self)local ab=da(self)local bb=self.get("value") +local cb=self.get("handleSize")local db=self.get("symbol")local _c=self.get("symbolColor") +local ac=self.get("symbolBackgroundColor")local bc=self.get("backgroundSymbol")local cc=self.get("orientation")== +"vertical"local dc= +math.floor((bb/100)* (ab-cb))+1 +for i=1,ab do +if cc then +self:blit(1,i,bc,ba[self.get("foreground")],ba[self.get("background")])else +self:blit(i,1,bc,ba[self.get("foreground")],ba[self.get("background")])end end +for i=dc,dc+cb-1 do if cc then self:blit(1,i,db,ba[_c],ba[ac])else +self:blit(i,1,db,ba[_c],ba[ac])end end end;return ca end +project["elements/VisualElement.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("BaseElement")local da=require("libraries/colorHex") +local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"x",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"y",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"z",{default=1,type="number",canTriggerRender=true,setter=function(cb,db) +if cb.parent then cb.parent:sortChildren()end;return db end}) +_b.defineProperty(_b,"constraints",{default={},type="table"}) +_b.defineProperty(_b,"width",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"height",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"background",{default=colors.black,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"foreground",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"backgroundEnabled",{default=true,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderTop",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderBottom",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderLeft",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderRight",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"borderColor",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"visible",{default=true,type="boolean",canTriggerRender=true,setter=function(cb,db) +if(cb.parent~=nil)then +cb.parent.set("childrenSorted",false)cb.parent.set("childrenEventsSorted",false)end;if(db==false)then cb:unsetState("clicked")end;return db end}) +_b.defineProperty(_b,"ignoreOffset",{default=false,type="boolean"}) +_b.defineProperty(_b,"layoutConfig",{default={},type="table"})_b.combineProperties(_b,"position","x","y") +_b.combineProperties(_b,"size","width","height") +_b.combineProperties(_b,"color","foreground","background")_b.defineEvent(_b,"focus") +_b.defineEvent(_b,"blur") +_b.registerEventCallback(_b,"Click","mouse_click","mouse_up") +_b.registerEventCallback(_b,"ClickUp","mouse_up","mouse_click") +_b.registerEventCallback(_b,"Drag","mouse_drag","mouse_click","mouse_up") +_b.registerEventCallback(_b,"Scroll","mouse_scroll") +_b.registerEventCallback(_b,"Enter","mouse_enter","mouse_move") +_b.registerEventCallback(_b,"LeEave","mouse_leave","mouse_move")_b.registerEventCallback(_b,"Focus","focus","blur") +_b.registerEventCallback(_b,"Blur","blur","focus")_b.registerEventCallback(_b,"Key","key","key_up") +_b.registerEventCallback(_b,"Char","char")_b.registerEventCallback(_b,"KeyUp","key_up","key") +local ab,bb=math.max,math.min;function _b.new()local cb=setmetatable({},_b):__init() +cb.class=_b;return cb end +function _b:init(cb,db) +ca.init(self,cb,db)self.set("type","VisualElement") +self:registerState("disabled",nil,1000)self:registerState("clicked",nil,500) +self:registerState("hover",nil,400)self:registerState("focused",nil,300) +self:registerState("dragging",nil,600) +self:observe("x",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("y",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("width",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("height",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("visible",function()if self.parent then +self.parent.set("childrenSorted",false)end end)end +function _b:setConstraint(cb,db,_c,ac)local bc=self.get("constraints")if bc[cb]then +self:_removeConstraintObservers(cb,bc[cb])end +bc[cb]={element=db,property=_c,offset=ac or 0}self.set("constraints",bc) +self:_addConstraintObservers(cb,bc[cb])self._constraintsDirty=true;self:updateRender()return self end;function _b:setLayoutConfigProperty(cb,db)local _c=self.get("layoutConfig")_c[cb]=db +self.set("layoutConfig",_c)return self end;function _b:getLayoutConfigProperty(cb) +local db=self.get("layoutConfig")return db[cb]end +function _b:resolveAllConstraints()if not +self._constraintsDirty then return self end +local cb=self.get("constraints")if not cb or not next(cb)then return self end +local db={"width","height","left","right","top","bottom","x","y","centerX","centerY"} +for _c,ac in ipairs(db)do if cb[ac]then local bc=self:_resolveConstraint(ac,cb[ac]) +self:_applyConstraintValue(ac,bc,cb)end end;self._constraintsDirty=false;return self end +function _b:_applyConstraintValue(cb,db,_c) +if cb=="x"or cb=="left"then self.set("x",db)elseif cb=="y"or +cb=="top"then self.set("y",db)elseif cb=="right"then +if _c.left then +local ac=self:_resolveConstraint("left",_c.left)local bc=db-ac+1;self.set("width",bc)self.set("x",ac)else +local ac=self.get("width")self.set("x",db-ac+1)end elseif cb=="bottom"then +if _c.top then +local ac=self:_resolveConstraint("top",_c.top)local bc=db-ac+1;self.set("height",bc)self.set("y",ac)else +local ac=self.get("height")self.set("y",db-ac+1)end elseif cb=="centerX"then local ac=self.get("width") +self.set("x",db-math.floor(ac/2))elseif cb=="centerY"then local ac=self.get("height") +self.set("y",db-math.floor(ac/2))elseif cb=="width"then self.set("width",db)elseif cb=="height"then +self.set("height",db)end end +function _b:_addConstraintObservers(cb,db)local _c=db.element;local ac=db.property +if _c=="parent"then _c=self.parent end;if not _c then return end +local bc=function()self._constraintsDirty=true +self:resolveAllConstraints()self:updateRender()end +if not self._constraintObserverCallbacks then self._constraintObserverCallbacks={}end;if not self._constraintObserverCallbacks[cb]then +self._constraintObserverCallbacks[cb]={}end;local cc={} +if +ac=="left"or ac=="x"then cc={"x"}elseif ac=="right"then cc={"x","width"}elseif ac=="top"or ac=="y"then cc={"y"}elseif ac== +"bottom"then cc={"y","height"}elseif ac=="centerX"then cc={"x","width"}elseif ac=="centerY"then +cc={"y","height"}elseif ac=="width"then cc={"width"}elseif ac=="height"then cc={"height"}end;for dc,_d in ipairs(cc)do _c:observe(_d,bc) +table.insert(self._constraintObserverCallbacks[cb],{element=_c,property=_d,callback=bc})end end +function _b:_removeConstraintObservers(cb,db) +if not self._constraintObserverCallbacks or not +self._constraintObserverCallbacks[cb]then return end;for _c,ac in ipairs(self._constraintObserverCallbacks[cb])do +ac.element:removeObserver(ac.property,ac.callback)end;self._constraintObserverCallbacks[cb]= +nil end +function _b:_removeAllConstraintObservers() +if not self._constraintObserverCallbacks then return end +for cb,db in pairs(self._constraintObserverCallbacks)do for _c,ac in ipairs(db)do +ac.element:removeObserver(ac.property,ac.callback)end end;self._constraintObserverCallbacks=nil end +function _b:removeConstraint(cb)local db=self.get("constraints")db[cb]=nil +self.set("constraints",db)self:updateConstraints()return self end +function _b:updateConstraints()local cb=self.get("constraints") +for db,_c in pairs(cb)do +local ac=self:_resolveConstraint(db,_c) +if db=="x"or db=="left"then self.set("x",ac)elseif db=="y"or db=="top"then +self.set("y",ac)elseif db=="right"then local bc=self.get("width") +self.set("x",ac-bc+1)elseif db=="bottom"then local bc=self.get("height") +self.set("y",ac-bc+1)elseif db=="centerX"then local bc=self.get("width") +self.set("x",ac-math.floor(bc/2))elseif db=="centerY"then local bc=self.get("height") +self.set("y",ac-math.floor(bc/2))elseif db=="width"then self.set("width",ac)elseif db=="height"then +self.set("height",ac)end end end +function _b:_resolveConstraint(cb,db)local _c=db.element;local ac=db.property;local bc=db.offset;if _c=="parent"then +_c=self.parent end +if not _c then return self.get(cb)or 1 end;local cc +if ac=="left"or ac=="x"then cc=_c.get("x")elseif ac=="right"then cc=_c.get("x")+ +_c.get("width")-1 elseif ac=="top"or ac=="y"then +cc=_c.get("y")elseif ac=="bottom"then +cc=_c.get("y")+_c.get("height")-1 elseif ac=="centerX"then +cc=_c.get("x")+math.floor(_c.get("width")/2)elseif ac=="centerY"then +cc=_c.get("y")+math.floor(_c.get("height")/2)elseif ac=="width"then cc=_c.get("width")elseif ac=="height"then cc=_c.get("height")end +if type(bc)=="number"then if bc>-1 and bc<1 and bc~=0 then +return math.floor(cc*bc)else return cc+bc end end;return cc end;function _b:alignRight(cb,db)db=db or 0 +return self:setConstraint("right",cb,"right",db)end;function _b:alignLeft(cb,db)db=db or 0;return +self:setConstraint("left",cb,"left",db)end +function _b:alignTop(cb,db)db= +db or 0;return self:setConstraint("top",cb,"top",db)end;function _b:alignBottom(cb,db)db=db or 0 +return self:setConstraint("bottom",cb,"bottom",db)end +function _b:centerHorizontal(cb,db)db=db or 0;return +self:setConstraint("centerX",cb,"centerX",db)end;function _b:centerVertical(cb,db)db=db or 0 +return self:setConstraint("centerY",cb,"centerY",db)end;function _b:centerIn(cb)return +self:centerHorizontal(cb):centerVertical(cb)end +function _b:rightOf(cb,db) +db=db or 0;return self:setConstraint("left",cb,"right",db)end;function _b:leftOf(cb,db)db=db or 0 +return self:setConstraint("right",cb,"left",-db)end;function _b:below(cb,db)db=db or 0;return +self:setConstraint("top",cb,"bottom",db)end +function _b:above(cb,db) +db=db or 0;return self:setConstraint("bottom",cb,"top",-db)end;function _b:stretchWidth(cb,db)db=db or 0 +return self:setConstraint("left",cb,"left",db):setConstraint("right",cb,"right", +-db)end;function _b:stretchHeight(cb,db)db= +db or 0 +return self:setConstraint("top",cb,"top",db):setConstraint("bottom",cb,"bottom", +-db)end;function _b:stretch(cb,db)return +self:stretchWidth(cb,db):stretchHeight(cb,db)end +function _b:widthPercent(cb,db)return self:setConstraint("width",cb,"width", +db/100)end;function _b:heightPercent(cb,db) +return self:setConstraint("height",cb,"height",db/100)end;function _b:matchWidth(cb,db)db=db or 0;return +self:setConstraint("width",cb,"width",db)end;function _b:matchHeight(cb,db)db= +db or 0 +return self:setConstraint("height",cb,"height",db)end;function _b:fillParent(cb)return +self:stretch("parent",cb)end;function _b:fillWidth(cb)return +self:stretchWidth("parent",cb)end;function _b:fillHeight(cb)return +self:stretchHeight("parent",cb)end;function _b:center()return +self:centerIn("parent")end;function _b:toRight(cb)return +self:alignRight("parent",- (cb or 0))end;function _b:toLeft(cb)return self:alignLeft("parent", +cb or 0)end;function _b:toTop(cb)return self:alignTop("parent", +cb or 0)end +function _b:toBottom(cb)return self:alignBottom("parent", +- (cb or 0))end +function _b:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d,ad=self:calculatePosition()cb=cb+_d-1 +db=db+ad-1;self.parent:multiBlit(cb,db,_c,ac,bc,cc,dc)end +function _b:textFg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 +db=db+cc-1;self.parent:textFg(cb,db,_c,ac)end +function _b:textBg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 +db=db+cc-1;self.parent:textBg(cb,db,_c,ac)end +function _b:drawText(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawText(cb,db,_c)end +function _b:drawFg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawFg(cb,db,_c)end +function _b:drawBg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawBg(cb,db,_c)end +function _b:blit(cb,db,_c,ac,bc)local cc,dc=self:calculatePosition()cb=cb+cc-1 +db=db+dc-1;self.parent:blit(cb,db,_c,ac,bc)end +function _b:isInBounds(cb,db)local _c,ac=self.get("x"),self.get("y") +local bc,cc=self.get("width"),self.get("height")if(self.get("ignoreOffset"))then +if(self.parent)then +cb=cb-self.parent.get("offsetX")db=db-self.parent.get("offsetY")end end;return +cb>=_c and cb<= +_c+bc-1 and db>=ac and db<=ac+cc-1 end +function _b:mouse_click(cb,db,_c)if self:isInBounds(db,_c)then self:setState("clicked") +self:fireEvent("mouse_click",cb,self:getRelativePosition(db,_c))return true end;return +false end +function _b:mouse_up(cb,db,_c) +if self:isInBounds(db,_c)then self:unsetState("clicked") +self:unsetState("dragging") +self:fireEvent("mouse_up",cb,self:getRelativePosition(db,_c))return true end;return false end +function _b:mouse_release(cb,db,_c) +self:fireEvent("mouse_release",cb,self:getRelativePosition(db,_c))self:unsetState("clicked") +self:unsetState("dragging")end +function _b:mouse_move(cb,db,_c)if(db==nil)or(_c==nil)then return false end +local ac=self.get("hover") +if(self:isInBounds(db,_c))then if(not ac)then self.set("hover",true) +self:fireEvent("mouse_enter",self:getRelativePosition(db,_c))end;return true else if(ac)then +self.set("hover",false) +self:fireEvent("mouse_leave",self:getRelativePosition(db,_c))end end;return false end +function _b:mouse_scroll(cb,db,_c)if(self:isInBounds(db,_c))then +self:fireEvent("mouse_scroll",cb,self:getRelativePosition(db,_c))return true end;return false end +function _b:mouse_drag(cb,db,_c)if(self:hasState("clicked"))then +self:fireEvent("mouse_drag",cb,self:getRelativePosition(db,_c))return true end;return false end +function _b:setFocused(cb,db)local _c=self:hasState("focused") +if cb==_c then return self end +if cb then self:setState("focused")self:focus() +if +not db and self.parent then self.parent:setFocusedChild(self)end else self:unsetState("focused")self:blur() +if +not db and self.parent then self.parent:setFocusedChild(nil)end end;return self end +function _b:isFocused()return self:hasState("focused")end;function _b:focus()self:fireEvent("focus")end;function _b:blur() +self:fireEvent("blur") +pcall(function() +self:setCursor(1,1,false,self.get and self.getResolved("foreground"))end)end;function _b:isFocused()return +self:hasState("focused")end +function _b:addBorder(cb,db)local _c=nil;local ac=nil +if +type(cb)== +"table"and(cb.color or cb.top~=nil or cb.left~=nil)then _c=cb.color;ac=cb else _c=cb;ac=db end +if ac then +if ac.top~=nil then self.set("borderTop",ac.top)end +if ac.bottom~=nil then self.set("borderBottom",ac.bottom)end +if ac.left~=nil then self.set("borderLeft",ac.left)end +if ac.right~=nil then self.set("borderRight",ac.right)end else self.set("borderTop",true) +self.set("borderBottom",true)self.set("borderLeft",true) +self.set("borderRight",true)end;if _c then self.set("borderColor",_c)end;return self end +function _b:removeBorder()self.set("borderTop",false) +self.set("borderBottom",false)self.set("borderLeft",false) +self.set("borderRight",false)return self end;function _b:key(cb,db) +if(self:hasState("focused"))then self:fireEvent("key",cb,db)end end +function _b:key_up(cb)if +(self:hasState("focused"))then self:fireEvent("key_up",cb)end end;function _b:char(cb) +if(self:hasState("focused"))then self:fireEvent("char",cb)end end +function _b:calculatePosition() +self:resolveAllConstraints()local cb,db=self.get("x"),self.get("y") +if +not self.get("ignoreOffset")then if self.parent~=nil then +local _c,ac=self.parent.get("offsetX"),self.parent.get("offsetY")cb=cb-_c;db=db-ac end end;return cb,db end +function _b:getAbsolutePosition(cb,db)local _c,ac=self.get("x"),self.get("y")if(cb~=nil)then +_c=_c+cb-1 end;if(db~=nil)then ac=ac+db-1 end;local bc=self.parent +while bc do +local cc,dc=bc.get("x"),bc.get("y")_c=_c+cc-1;ac=ac+dc-1;bc=bc.parent end;return _c,ac end +function _b:getRelativePosition(cb,db)if(cb==nil)or(db==nil)then +cb,db=self.get("x"),self.get("y")end;local _c,ac=1,1;if self.parent then +_c,ac=self.parent:getRelativePosition()end +local bc,cc=self.get("x"),self.get("y")return cb- (bc-1)- (_c-1),db- (cc-1)- (ac-1)end +function _b:setCursor(cb,db,_c,ac) +if self.parent then local bc,cc=self:calculatePosition() +if +(cb+bc-1 <1)or( +cb+bc-1 >self.parent.get("width"))or(db+cc-1 <1)or(db+cc-1 > +self.parent.get("height"))then return self.parent:setCursor( +cb+bc-1,db+cc-1,false)end +return self.parent:setCursor(cb+bc-1,db+cc-1,_c,ac)end;return self end +function _b:prioritize() +if(self.parent)then local cb=self.parent;cb:removeChild(self) +cb:addChild(self)self:updateRender()end;return self end +function _b:render() +if(not self.getResolved("backgroundEnabled"))then return end;local cb,db=self.get("width"),self.get("height") +local _c=da[self.getResolved("foreground")]local ac=da[self.getResolved("background")] +local bc,cc,dc,_d=self.getResolved("borderTop"),self.getResolved("borderBottom"),self.getResolved("borderLeft"),self.getResolved("borderRight")self:multiBlit(1,1,cb,db," ",_c,ac) +if +(bc or cc or dc or _d)then +local ad=self.getResolved("borderColor")or self.getResolved("foreground")local bd=da[ad]or _c;if bc then +self:textFg(1,1,("\131"):rep(cb),ad)end;if cc then +self:multiBlit(1,db,cb,1,"\143",ac,bd)end;if dc then +self:multiBlit(1,1,1,db,"\149",bd,ac)end;if _d then +self:multiBlit(cb,1,1,db,"\149",ac,bd)end +if bc and dc then self:blit(1,1,"\151",bd,ac)end;if bc and _d then self:blit(cb,1,"\148",ac,bd)end;if +cc and dc then self:blit(1,db,"\138",ac,bd)end;if cc and _d then +self:blit(cb,db,"\133",ac,bd)end end end;function _b:postRender()end +function _b:destroy() +self:_removeAllConstraintObservers()self.set("visible",false)ca.destroy(self)end;return _b end +project["elements/ProgressBar.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"progress",{default=0,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"showPercentage",{default=false,type="boolean"}) +aa.defineProperty(aa,"progressColor",{default=colors.black,type="color"}) +aa.defineProperty(aa,"direction",{default="right",type="string"}) +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",25)ba.set("height",3)return ba end;function aa:init(ba,ca)d.init(self,ba,ca) +self.set("type","ProgressBar")end +function aa:render()d.render(self) +local ba=self.get("width")local ca=self.get("height") +local da=math.min(100,math.max(0,self.get("progress")))local _b=math.floor((ba*da)/100) +local ab=math.floor((ca*da)/100)local bb=self.get("direction") +local cb=self.get("progressColor") +if bb=="right"then +self:multiBlit(1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="left"then +self:multiBlit(ba-_b+1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="up"then +self:multiBlit(1,ca-ab+1,ba,ab," ",_a[self.get("foreground")],_a[cb])elseif bb=="down"then +self:multiBlit(1,1,ba,ab," ",_a[self.get("foreground")],_a[cb])end +if self.get("showPercentage")then local db=tostring(da).."%"local _c=math.floor( +(ba-#db)/2)+1 +local ac=math.floor((ca-1)/2)+1 +self:textFg(_c,ac,db,self.get("foreground"))end end;return aa end +project["elements/CheckBox.lua"] = function(...) local c=require("elements/VisualElement") +local d=setmetatable({},c)d.__index=d +d.defineProperty(d,"checked",{default=false,type="boolean",canTriggerRender=true}) +d.defineProperty(d,"text",{default=" ",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("checkedText") +local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) +d.defineProperty(d,"checkedText",{default="x",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("text") +local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) +d.defineProperty(d,"autoSize",{default=true,type="boolean"})d.defineEvent(d,"mouse_click") +d.defineEvent(d,"mouse_up")function d.new()local _a=setmetatable({},d):__init()_a.class=d +_a.set("backgroundEnabled",false)return _a end +function d:init(_a,aa) +c.init(self,_a,aa)self.set("type","CheckBox")end +function d:mouse_click(_a,aa,ba)if c.mouse_click(self,_a,aa,ba)then +self.set("checked",not self.get("checked"))return true end;return false end +function d:render()c.render(self)local _a=self.getResolved("checked") +local aa=self.getResolved("text")local ba=self.getResolved("checkedText") +local ca=string.sub(_a and ba or aa,1,self.get("width")) +self:textFg(1,1,ca,self.getResolved("foreground"))end;return d end +project["elements/BaseElement.lua"] = function(...) local _a=require("propertySystem") +local aa=require("libraries/utils").uuid;local ba=require("errorManager")local ca=setmetatable({},_a) +ca.__index=ca +ca.defineProperty(ca,"type",{default={"BaseElement"},type="string",setter=function(da,_b)if type(_b)=="string"then +table.insert(da._values.type,1,_b)return da._values.type end;return _b end,getter=function(da,_b,ab)if +ab~=nil and ab<1 then return da._values.type end;return da._values.type[ +ab or 1]end}) +ca.defineProperty(ca,"id",{default="",type="string",readonly=true}) +ca.defineProperty(ca,"name",{default="",type="string"}) +ca.defineProperty(ca,"eventCallbacks",{default={},type="table"}) +ca.defineProperty(ca,"enabled",{default=true,type="boolean"}) +ca.defineProperty(ca,"states",{default={},type="table",canTriggerRender=true}) +function ca.defineEvent(da,_b,ab) +if not rawget(da,'_eventConfigs')then da._eventConfigs={}end;da._eventConfigs[_b]={requires=ab and ab or _b}end +function ca.registerEventCallback(da,_b,...) +local ab=_b:match("^on")and _b or"on".._b;local bb={...}local cb=bb[1] +da[ab]=function(db,...) +for _c,ac in ipairs(bb)do if not db._registeredEvents[ac]then +db:listenEvent(ac,true)end end;db:registerCallback(cb,...)return db end end;function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;return da end +function ca:init(da,_b) +if self._initialized then return self end;self._initialized=true;self._props=da;self._values.id=aa() +self.basalt=_b;self._registeredEvents={}self._registeredStates={} +local ab=getmetatable(self).__index;local bb={}ab=self.class +while ab do +if type(ab)=="table"and ab._eventConfigs then for cb,db in +pairs(ab._eventConfigs)do if not bb[cb]then bb[cb]=db end end end +ab=getmetatable(ab)and getmetatable(ab).__index end +for cb,db in pairs(bb)do self._registeredEvents[db.requires]=true end;if self._callbacks then +for cb,db in pairs(self._callbacks)do self[db]=function(_c,...) +_c:registerCallback(cb,...)return _c end end end +return self end +function ca:postInit()if self._postInitialized then return self end +self._postInitialized=true;if(self._props)then +for da,_b in pairs(self._props)do self.set(da,_b)end end;self._props=nil;return self end;function ca:isType(da) +for _b,ab in ipairs(self._values.type)do if ab==da then return true end end;return false end +function ca:listenEvent(da,_b)_b= +_b~=false +if +_b~= (self._registeredEvents[da]or false)then +if _b then self._registeredEvents[da]=true;if self.parent then +self.parent:registerChildEvent(self,da)end else self._registeredEvents[da]=nil +if +self.parent then self.parent:unregisterChildEvent(self,da)end end end;return self end +function ca:registerCallback(da,_b)if not self._registeredEvents[da]then +self:listenEvent(da,true)end +if +not self._values.eventCallbacks[da]then self._values.eventCallbacks[da]={}end +table.insert(self._values.eventCallbacks[da],_b)return self end;function ca:registerState(da,_b,ab) +self._registeredStates[da]={condition=_b,priority=ab or 0}return self end +function ca:setState(da,_b) +local ab=self.get("states")if not _b and self._registeredStates[da]then +_b=self._registeredStates[da].priority end;ab[da]=_b or 0 +self.set("states",ab)return self end +function ca:unsetState(da)local _b=self.get("states")if _b[da]~=nil then _b[da]=nil +self.set("states",_b)end;return self end +function ca:hasState(da)local _b=self.get("states")return _b[da]~=nil end +function ca:getCurrentState()local da=self.get("states")local _b=-math.huge;local ab=nil;for bb,cb in +pairs(da)do if cb>_b then _b=cb;ab=bb end end;return ab end +function ca:getActiveStates()local da=self.get("states")local _b={}for ab,bb in pairs(da)do +table.insert(_b,{name=ab,priority=bb})end +table.sort(_b,function(ab,bb) +return ab.priority>bb.priority end)return _b end +function ca:updateConditionalStates() +for da,_b in pairs(self._registeredStates)do +if _b.condition then if _b.condition(self)then +self:setState(da,_b.priority)else self:unsetState(da)end end end;return self end;function ca:unregisterState(da)self._stateRegistry[da]=nil +self:unsetState(da)return self end +function ca:fireEvent(da,...) +if +self.get("eventCallbacks")[da]then local _b;for ab,bb in ipairs(self.get("eventCallbacks")[da])do +_b=bb(self,...)end;return _b end;return self end +function ca:dispatchEvent(da,...) +if self.get("enabled")==false then return false end;if self[da]then return self[da](self,...)end;return +self:handleEvent(da,...)end;function ca:handleEvent(da,...)return false end;function ca:onChange(da,_b) +self:observe(da,_b)return self end +function ca:getBaseFrame()if self.parent then return +self.parent:getBaseFrame()end;return self end;function ca:destroy() +if(self.parent)then self.parent:removeChild(self)end;self._destroyed=true;self:removeAllObservers() +self:setFocused(false)end;function ca:updateRender() +if +(self.parent)then self.parent:updateRender()else self._renderUpdate=true end;return self end;return ca end +project["elements/ContextMenu.lua"] = function(...) local aa=require("elementManager") +local ba=require("elements/VisualElement")local ca=aa.getElement("Container") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"items",{default={},type="table",canTriggerRender=true}) +_b.defineProperty(_b,"isOpen",{default=false,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"openSubmenu",{default=nil,type="table",allowNil=true}) +_b.defineProperty(_b,"itemHeight",{default=1,type="number",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +function _b.new() +local ab=setmetatable({},_b):__init()ab.class=_b;ab.set("width",10)ab.set("height",10) +ab.set("visible",false)return ab end;function _b:init(ab,bb)ca.init(self,ab,bb) +self.set("type","ContextMenu")end +function _b:setItems(ab) +self.set("items",ab or{})self:calculateSize()return self end +function _b:calculateSize()local ab=self.get("items") +local bb=self.get("itemHeight") +if#ab==0 then self.set("width",10)self.set("height",2)return end;local cb=8 +for _c,ac in ipairs(ab)do if ac.label then local bc=#ac.label;local cc=bc+3 +if ac.submenu then cc=cc+1 end;if cc>cb then cb=cc end end end;local db=#ab*bb;self.set("width",cb) +self.set("height",db)end;function _b:open()self.set("isOpen",true) +self.set("visible",true)self:updateRender()self:dispatchEvent("opened") +return self end +function _b:close() +self.set("isOpen",false)self.set("visible",false) +local ab=self.get("openSubmenu")if ab and ab.menu then ab.menu:close()end +self.set("openSubmenu",nil)self:updateRender()self:dispatchEvent("closed") +return self end;function _b:closeAll()local ab=self;while ab.parentMenu do ab=ab.parentMenu end +ab:close()return self end +function _b:getItemAt(ab) +local bb=self.get("items")local cb=self.get("itemHeight") +local db=math.floor((ab-1)/cb)+1;if db>=1 and db<=#bb then return db,bb[db]end;return nil,nil end +function _b:createSubmenu(ab,bb)local cb=self.parent:addContextMenu() +cb:setItems(ab) +cb.set("background",self.get("background")) +cb.set("foreground",self.get("foreground"))cb.parentMenu=self;local db=self.get("x")local _c=self.get("y") +local ac=self.get("width")local bc=self.get("itemHeight")local cc=bb._index or 1 +cb.set("x",db+ac)cb.set("y",_c+ (cc-1)*bc) +cb.set("z",self.get("z")+1)return cb end +function _b:mouse_click(ab,bb,cb)if not ba.mouse_click(self,ab,bb,cb)then self:close() +return false end +local db,_c=ba.getRelativePosition(self,bb,cb)local ac,bc=self:getItemAt(_c) +if bc then if bc.disabled then return true end +if bc.submenu then +local cc=self.get("openSubmenu") +if cc and cc.index==ac then cc.menu:close() +self.set("openSubmenu",nil)else if cc and cc.menu then cc.menu:close()end;bc._index=ac +local dc=self:createSubmenu(bc.submenu,bc)dc:open() +self.set("openSubmenu",{index=ac,menu=dc})end;return true end;if bc.onClick then bc.onClick(bc)end;self:closeAll() +return true end;return true end +function _b:render()local ab=self.get("items")local bb=self.get("width") +local cb=self.get("height")local db=self.get("itemHeight") +local _c=self.get("background")local ac=self.get("foreground") +for bc,cc in ipairs(ab)do local dc=(bc-1)*db+1;local _d= +cc.background or _c;local ad=cc.foreground or ac;local bd=da[_d] +local cd=da[ad]local dd=string.rep(" ",bb)local __a=string.rep(bd,bb) +local a_a=string.rep(cd,bb)self:blit(1,dc,dd,a_a,__a)local b_a=cc.label or""if#b_a>bb-3 then b_a=b_a:sub(1, +bb-3)end +self:textFg(2,dc,b_a,ad)if cc.submenu then self:textFg(bb-1,dc,">",ad)end end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(bc)end end +for bc,cc in ipairs(self.get("visibleChildren")or{})do if cc==self then +error("CIRCULAR REFERENCE DETECTED!")return end;cc:render()cc:postRender()end end;return _b end +project["elements/List.lua"] = function(...) local _a=require("elements/Collection") +local aa=require("libraries/colorHex")local ba=setmetatable({},_a)ba.__index=ba +ba.defineProperty(ba,"offset",{default=0,type="number",canTriggerRender=true,setter=function(da,_b) +local ab=math.max(0,# +da.get("items")-da.get("height"))return math.min(ab,math.max(0,_b))end}) +ba.defineProperty(ba,"emptyText",{default="No items",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"showScrollBar",{default=true,type="boolean",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarSymbol",{default=" ",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackground",{default="\127",type="string",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarColor",{default=colors.lightGray,type="color",canTriggerRender=true}) +ba.defineProperty(ba,"scrollBarBackgroundColor",{default=colors.gray,type="color",canTriggerRender=true})ba.defineEvent(ba,"mouse_click") +ba.defineEvent(ba,"mouse_up")ba.defineEvent(ba,"mouse_drag") +ba.defineEvent(ba,"mouse_scroll")ba.defineEvent(ba,"key") +local ca={text={type="string",default="Entry"},bg={type="number",default=nil},fg={type="number",default= +nil},selectedBg={type="number",default=nil},selectedFg={type="number",default=nil},callback={type="function",default=nil}} +function ba.new()local da=setmetatable({},ba):__init() +da.class=ba;da.set("width",16)da.set("height",8)da.set("z",5) +da.set("background",colors.gray)return da end +function ba:init(da,_b)_a.init(self,da,_b)self._entrySchema=ca +self.set("type","List") +self:observe("items",function() +local ab=math.max(0,#self.get("items")-self.get("height")) +if self.get("offset")>ab then self.set("offset",ab)end end) +self:observe("height",function() +local ab=math.max(0,#self.get("items")-self.get("height")) +if self.get("offset")>ab then self.set("offset",ab)end end)return self end +function ba:mouse_click(da,_b,ab) +if _a.mouse_click(self,da,_b,ab)then +local bb,cb=self:getRelativePosition(_b,ab)local db=self.get("width")local _c=self.get("items") +local ac=self.get("height")local bc=self.get("showScrollBar") +if bc and#_c>ac and bb==db then local cc= +#_c-ac +local dc=math.max(1,math.floor((ac/#_c)*ac)) +local _d=cc>0 and(self.get("offset")/cc*100)or 0 +local ad=math.floor((_d/100)* (ac-dc))+1 +if cb>=ad and cb +ab+_b then self.set("offset",da-_b)end;return self end +function ba:key(da) +if _a.key(self,da)and self.get("selectable")then +local _b=self.get("items")local ab=self:getSelectedIndex() +if da==keys.up then +self:selectPrevious()if ab and ab>1 then self:scrollToItem(ab-1)end +return true elseif da==keys.down then self:selectNext()if ab and ab<#_b then +self:scrollToItem(ab+1)end;return true elseif da==keys.home then +self:clearItemSelection()self:selectItem(1)self:scrollToTop()return true elseif +da==keys["end"]then self:clearItemSelection()self:selectItem(#_b) +self:scrollToBottom()return true elseif da==keys.pageUp then local bb=self.get("height") +local cb=math.max(1,(ab or 1)-bb)self:clearItemSelection()self:selectItem(cb) +self:scrollToItem(cb)return true elseif da==keys.pageDown then local bb=self.get("height") +local cb=math.min(#_b,(ab or 1)+bb)self:clearItemSelection()self:selectItem(cb) +self:scrollToItem(cb)return true end end;return false end +function ba:render(da)da=da or 0;_a.render(self)local _b=self.get("items") +local ab=self.get("height")local bb=self.get("offset")local cb=self.get("width") +local db=self.getResolved("background")local _c=self.getResolved("foreground") +local ac=self.get("showScrollBar")local bc=ac and#_b>ab;local cc=bc and cb-1 or cb +if#_b==0 then +local dc=self.get("emptyText")local _d=math.floor(ab/2)+da;local ad=math.max(1, +math.floor((cb-#dc)/2)+1)for i=1,ab do +self:textBg(1,i,string.rep(" ",cb),db)end;if _d>=1 and _d<=ab then +self:textFg(ad,_d+da,dc,colors.gray)end;return end +for i=1,ab do local dc=i+bb;local _d=_b[dc] +if _d then +if _d.separator then +local ad=( +(_d.text or"-")~=""and _d.text or"-"):sub(1,1)local bd=string.rep(ad,cc)local cd=_d.fg or _c;local dd=_d.bg or db;self:textBg(1, +i+da,string.rep(" ",cc),dd)self:textFg(1,i+ +da,bd,cd)else local ad=_d.text or""local bd=_d.selected +local cd= +bd and( +_d.selectedBg or self.getResolved("selectedBackground"))or(_d.bg or db) +local dd=bd and +(_d.selectedFg or self.getResolved("selectedForeground"))or(_d.fg or _c)local __a=ad +if#__a>cc then __a=__a:sub(1,cc-3).."..."else __a=__a..string.rep(" ",cc- +#__a)end;self:textBg(1,i+da,string.rep(" ",cc),cd)self:textFg(1, +i+da,__a,dd)end else self:textBg(1,i+da,string.rep(" ",cc),db)end end +if bc then +local dc=math.max(1,math.floor((ab/#_b)*ab))local _d=#_b-ab;local ad=_d>0 and(bb/_d*100)or 0;local bd=math.floor((ad/ +100)* (ab-dc))+1 +local cd=self.getResolved("scrollBarSymbol")local dd=self.getResolved("scrollBarBackground") +local __a=self.getResolved("scrollBarColor")local a_a=self.getResolved("scrollBarBackgroundColor") +for i=1,ab do self:blit(cb, +i+da,dd,aa[_c],aa[a_a])end;for i=bd,math.min(ab,bd+dc-1)do +self:blit(cb,i+da,cd,aa[__a],aa[a_a])end end end;return ba end +project["elements/Collection.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/collectionentry")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"items",{default={},type="table",canTriggerRender=true}) +aa.defineProperty(aa,"selectable",{default=true,type="boolean"}) +aa.defineProperty(aa,"multiSelection",{default=false,type="boolean"}) +aa.defineProperty(aa,"selectedBackground",{default=colors.blue,type="color",canTriggerRender=true}) +aa.defineProperty(aa,"selectedForeground",{default=colors.white,type="color",canTriggerRender=true})function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;return ba end +function aa:init(ba,ca) +d.init(self,ba,ca)self._entrySchema={}self.set("type","Collection")return self end +function aa:addItem(ba)if type(ba)=="string"then ba={text=ba}end;if ba.selected==nil then +ba.selected=false end +local ca=_a.new(self,ba,self._entrySchema)table.insert(self.get("items"),ca) +self:updateRender()return ca end +function aa:removeItem(ba)local ca=self.get("items")if type(ba)=="number"then +table.remove(ca,ba)else +for da,_b in pairs(ca)do if _b==ba then table.remove(ca,da)break end end end +self:updateRender()return self end +function aa:clear()self.set("items",{})self:updateRender()return self end +function aa:getSelectedItems()local ba={}for ca,da in ipairs(self.get("items"))do +if type(da)=="table"and +da.selected then local _b=da;_b.index=ca;table.insert(ba,_b)end end;return ba end +function aa:getSelectedItem()local ba=self.get("items") +for ca,da in ipairs(ba)do if type(da)=="table"and +da.selected then return da end end;return nil end +function aa:selectItem(ba)local ca=self.get("items") +if type(ba)=="number"then +if ca[ba]and +type(ca[ba])=="table"then ca[ba].selected=true end else for da,_b in pairs(ca)do +if _b==ba then if type(_b)=="table"then _b.selected=true end;break end end end;self:updateRender()return self end +function aa:unselectItem(ba)local ca=self.get("items") +if type(ba)=="number"then +if ca[ba]and +type(ca[ba])=="table"then ca[ba].selected=false end else +for da,_b in pairs(ca)do if _b==ba then +if type(ca[da])=="table"then ca[da].selected=false end;break end end end;self:updateRender()return self end +function aa:clearItemSelection()local ba=self.get("items") +for ca,da in ipairs(ba)do da.selected=false end;self:updateRender()return self end +function aa:getSelectedIndex()local ba=self.get("items") +for ca,da in ipairs(ba)do if type(da)=="table"and +da.selected then return ca end end;return nil end +function aa:selectNext()local ba=self.get("items") +local ca=self:getSelectedIndex() +if not ca then if#ba>0 then self:selectItem(1)end elseif ca<#ba then +if not +self.get("multiSelection")then self:clearItemSelection()end;self:selectItem(ca+1)end;self:updateRender()return self end +function aa:selectPrevious()local ba=self.get("items") +local ca=self:getSelectedIndex() +if not ca then if#ba>0 then self:selectItem(#ba)end elseif ca>1 then +if not +self.get("multiSelection")then self:clearItemSelection()end;self:selectItem(ca-1)end;self:updateRender()return self end +function aa:onSelect(ba)self:registerCallback("select",ba)return self end;return aa end +project["elements/Accordion.lua"] = function(...) local aa=require("elementManager") +local ba=require("elements/VisualElement")local ca=aa.getElement("Container") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"panels",{default={},type="table"}) +_b.defineProperty(_b,"panelHeaderHeight",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"allowMultiple",{default=false,type="boolean"}) +_b.defineProperty(_b,"headerBackground",{default=colors.gray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"headerTextColor",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"expandedHeaderBackground",{default=colors.lightGray,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"expandedHeaderTextColor",{default=colors.black,type="color",canTriggerRender=true})_b.defineEvent(_b,"mouse_click") +_b.defineEvent(_b,"mouse_up")function _b.new()local ab=setmetatable({},_b):__init() +ab.class=_b;ab.set("width",20)ab.set("height",10)ab.set("z",10)return +ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","Accordion")end +function _b:newPanel(ab,bb)local cb=self.get("panels")or{}local db=#cb+1 +local _c=self:addContainer()_c.set("x",1)_c.set("y",1) +_c.set("width",self.get("width"))_c.set("height",self.get("height")) +_c.set("visible",bb or false)_c.set("ignoreOffset",true) +table.insert(cb,{id=db,title=tostring(ab or("Panel "..db)),expanded= +bb or false,container=_c})self.set("panels",cb)self:updatePanelLayout()return _c end;_b.addPanel=_b.newPanel +function _b:updatePanelLayout() +local ab=self.get("panels")or{}local bb=self.get("panelHeaderHeight")or 1;local cb=1 +local db=self.get("width")local _c=self.get("height") +for dc,_d in ipairs(ab)do local ad=cb+bb +_d.container.set("x",1)_d.container.set("y",ad) +_d.container.set("width",db)_d.container.set("visible",_d.expanded) +_d.container.set("ignoreOffset",false)cb=cb+bb +if _d.expanded then local bd=0 +for dd,__a in +ipairs(_d.container._values.children or{})do +if not __a._destroyed then local a_a=__a.get("y")local b_a=__a.get("height")local c_a= +a_a+b_a-1;if c_a>bd then bd=c_a end end end;local cd=math.max(1,bd)_d.container.set("height",cd)cb= +cb+cd end end;local ac=cb-1;local bc=math.max(0,ac-_c) +local cc=self.get("offsetY")if cc>bc then self.set("offsetY",bc)end +self:updateRender()end +function _b:togglePanel(ab)local bb=self.get("panels")or{} +local cb=self.get("allowMultiple") +for db,_c in ipairs(bb)do +if _c.id==ab then _c.expanded=not _c.expanded +if not cb and _c.expanded then for ac,bc in +ipairs(bb)do if ac~=db then bc.expanded=false end end end;self:updatePanelLayout() +self:dispatchEvent("panelToggled",ab,_c.expanded)break end end;return self end +function _b:expandPanel(ab)local bb=self.get("panels")or{} +local cb=self.get("allowMultiple") +for db,_c in ipairs(bb)do +if _c.id==ab then +if not _c.expanded then _c.expanded=true +if not cb then for ac,bc in ipairs(bb)do if ac~=db then +bc.expanded=false end end end;self:updatePanelLayout() +self:dispatchEvent("panelToggled",ab,true)end;break end end;return self end +function _b:collapsePanel(ab)local bb=self.get("panels")or{} +for cb,db in ipairs(bb)do +if db.id==ab then if +db.expanded then db.expanded=false;self:updatePanelLayout() +self:dispatchEvent("panelToggled",ab,false)end;break end end;return self end +function _b:getPanel(ab)local bb=self.get("panels")or{}for cb,db in ipairs(bb)do if db.id==ab then return +db.container end end;return nil end +function _b:_getPanelMetrics()local ab=self.get("panels")or{}local bb= +self.get("panelHeaderHeight")or 1;local cb={}local db=1 +for _c,ac in ipairs(ab)do +table.insert(cb,{id=ac.id,title=ac.title,expanded=ac.expanded,headerY=db,headerHeight=bb})db=db+bb;if ac.expanded then +db=db+ac.container.get("height")end end;return{positions=cb,totalHeight=db-1}end +function _b:mouse_click(ab,bb,cb) +if not ba.mouse_click(self,ab,bb,cb)then return false end;local db,_c=ba.getRelativePosition(self,bb,cb) +local ac=self.get("offsetY")local bc=_c+ac;local cc=self:_getPanelMetrics() +for dc,_d in ipairs(cc.positions)do local ad= +_d.headerY+_d.headerHeight-1;if +bc>=_d.headerY and bc<=ad then self:togglePanel(_d.id) +self.set("focusedChild",nil)return true end end;return ca.mouse_click(self,ab,bb,cb)end +function _b:mouse_scroll(ab,bb,cb) +if ba.mouse_scroll(self,ab,bb,cb)then +local db=self:_getPanelMetrics()local _c=self.get("height")local ac=db.totalHeight +local bc=math.max(0,ac-_c) +if bc>0 then local cc=self.get("offsetY")local dc=cc+ab +dc=math.max(0,math.min(bc,dc))self.set("offsetY",dc)return true end;return ca.mouse_scroll(self,ab,bb,cb)end;return false end +function _b:render()ba.render(self)local ab=self.get("width") +local bb=self.get("offsetY")local cb=self:_getPanelMetrics() +for db,_c in ipairs(cb.positions)do +local ac=_c.expanded and +self.get("expandedHeaderBackground")or self.get("headerBackground") +local bc=_c.expanded and self.get("expandedHeaderTextColor")or +self.get("headerTextColor")local cc=_c.headerY-bb +if +cc>=1 and cc<=self.get("height")then +ba.multiBlit(self,1,cc,ab,_c.headerHeight," ",da[bc],da[ac])local dc=_c.expanded and"v"or">" +local _d=dc.." ".._c.title;ba.textFg(self,1,cc,_d,bc)end end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for db in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(db)end end +for db,_c in ipairs(self.get("visibleChildren")or{})do if _c==self then +error("CIRCULAR REFERENCE DETECTED!")return end;_c:render()_c:postRender()end end;return _b end +project["plugins/canvas.lua"] = function(...) local ba=require("libraries/colorHex") +local ca=require("errorManager")local da={}da.__index=da;local _b,ab=string.sub,string.rep +function da.new(cb) +local db=setmetatable({},da)db.commands={pre={},post={}}db.type="pre"db.element=cb;return db end +function da:clear()self.commands={pre={},post={}}return self end;function da:getValue(cb) +if type(cb)=="function"then return cb(self.element)end;return cb end +function da:setType(cb)if +cb=="pre"or cb=="post"then self.type=cb else +ca.error("Invalid type. Use 'pre' or 'post'.")end;return self end +function da:addCommand(cb) +local db=#self.commands[self.type]+1;self.commands[self.type][db]=cb;return db end +function da:setCommand(cb,db)self.commands[cb]=db;return self end;function da:removeCommand(cb) +table.remove(self.commands[self.type],cb)return self end +function da:text(cb,db,_c,ac,bc) +return +self:addCommand(function(cc) +local dc,_d=self:getValue(cb),self:getValue(db)local ad=self:getValue(_c)local bd=self:getValue(ac) +local cd=self:getValue(bc) +local dd=type(bd)=="number"and ba[bd]:rep(#_c)or bd +local __a=type(cd)=="number"and ba[cd]:rep(#_c)or cd;cc:drawText(dc,_d,ad) +if dd then cc:drawFg(dc,_d,dd)end;if __a then cc:drawBg(dc,_d,__a)end end)end;function da:bg(cb,db,_c)return +self:addCommand(function(ac)ac:drawBg(cb,db,_c)end)end +function da:fg(cb,db,_c)return self:addCommand(function(ac) +ac:drawFg(cb,db,_c)end)end +function da:rect(cb,db,_c,ac,bc,cc,dc) +return +self:addCommand(function(_d)local ad,bd=self:getValue(cb),self:getValue(db) +local cd,dd=self:getValue(_c),self:getValue(ac)local __a=self:getValue(bc)local a_a=self:getValue(cc) +local b_a=self:getValue(dc)if(type(a_a)=="number")then a_a=ba[a_a]end;if +(type(b_a)=="number")then b_a=ba[b_a]end +local c_a=b_a and _b(b_a:rep(cd),1,cd)local d_a=a_a and _b(a_a:rep(cd),1,cd)local _aa=__a and +_b(__a:rep(cd),1,cd) +for i=0,dd-1 do +if b_a then _d:drawBg(ad,bd+i,c_a)end;if a_a then _d:drawFg(ad,bd+i,d_a)end;if __a then +_d:drawText(ad,bd+i,_aa)end end end)end +function da:line(cb,db,_c,ac,bc,cc,dc) +local function _d(cd,dd,__a,a_a)local b_a={}local c_a=0;local d_a=math.abs(__a-cd) +local _aa=math.abs(a_a-dd)local aaa=(cd<__a)and 1 or-1 +local baa=(dd-_aa then caa=caa-_aa;cd=cd+aaa end;if daa0 do +aaa=aaa-1;daa=daa-2 *c_a;if baa>0 then baa=baa+c_a-daa else _aa=_aa+1 +caa=caa+2 *d_a;baa=baa+c_a-daa+caa end +_ba(_aa,aaa)end +return a_a end;local ad=_d(cb,db,_c,ac) +return +self:addCommand(function(bd)local cd=self:getValue(bc) +local dd=self:getValue(cc)local __a=self:getValue(dc) +local a_a=type(dd)=="number"and ba[dd]or dd +local b_a=type(__a)=="number"and ba[__a]or __a +for c_a,d_a in pairs(ad)do local _aa=math.floor(d_a.x)local aaa=math.floor(d_a.y)if cd then +bd:drawText(_aa,aaa,cd)end;if a_a then bd:drawFg(_aa,aaa,a_a)end;if b_a then +bd:drawBg(_aa,aaa,b_a)end end end)end;local bb={hooks={}} +function bb.setup(cb) +cb.defineProperty(cb,"canvas",{default=nil,type="table",getter=function(db)if not db._values.canvas then +db._values.canvas=da.new(db)end;return db._values.canvas end})end;function bb.hooks.render(cb)local db=cb.get("canvas") +if +db and#db.commands.pre>0 then for _c,ac in pairs(db.commands.pre)do ac(cb)end end end +function bb.hooks.postRender(cb) +local db=cb.get("canvas")if db and#db.commands.post>0 then for _c,ac in pairs(db.commands.post)do +ac(cb)end end end;return{VisualElement=bb,API=da} end +project["plugins/theme.lua"] = function(...) local ab=require("errorManager") +local bb={default={background=colors.lightGray,foreground=colors.black},BaseFrame={background=colors.white,foreground=colors.black,Frame={background=colors.black,names={basaltDebugLogClose={background=colors.blue,foreground=colors.white}}},Button={background=colors.cyan,foreground=colors.black},names={basaltDebugLog={background=colors.red,foreground=colors.white}}}}local cb={default=bb}local db="default" +local _c={hooks={postInit={pre=function(ad)if ad._postInitialized then return ad end +ad:applyTheme()end}}} +function _c.____getElementPath(ad,bd)if bd then table.insert(bd,1,ad._values.type)else +bd={ad._values.type}end;local cd=ad.parent;if cd then return +cd.____getElementPath(cd,bd)else return bd end end +local function ac(ad,bd)local cd=ad +for i=1,#bd do local dd=false;local __a=bd[i]for a_a,b_a in ipairs(__a)do +if cd[b_a]then cd=cd[b_a]dd=true;break end end;if not dd then return nil end end;return cd end +local function bc(ad,bd)local cd={} +if ad.default then for dd,__a in pairs(ad.default)do +if type(__a)~="table"then cd[dd]=__a end end;if ad.default[bd]then +for dd,__a in +pairs(ad.default[bd])do if type(__a)~="table"then cd[dd]=__a end end end end;return cd end +local function cc(ad,bd,cd,dd,__a) +if +bd.default and bd.default.names and bd.default.names[dd]then for a_a,b_a in pairs(bd.default.names[dd])do +if type(b_a)~="table"then ad[a_a]=b_a end end end +if + +bd.default and bd.default[cd]and bd.default[cd].names and bd.default[cd].names[dd]then +for a_a,b_a in pairs(bd.default[cd].names[dd])do if +type(b_a)~="table"then ad[a_a]=b_a end end end;if __a and __a.names and __a.names[dd]then +for a_a,b_a in pairs(__a.names[dd])do if +type(b_a)~="table"then ad[a_a]=b_a end end end end +local function dc(ad,bd,cd,dd)local __a={}local a_a=ac(ad,bd) +if a_a then for b_a,c_a in pairs(a_a)do +if type(c_a)~="table"then __a[b_a]=c_a end end end;if next(__a)==nil then __a=bc(ad,cd)end +cc(__a,ad,cd,dd,a_a)return __a end +function _c:applyTheme(ad)local bd=self:getTheme() +if(bd~=nil)then +for cd,dd in pairs(bd)do +local __a=self._properties[cd] +if(__a)then +if( (__a.type)=="color")then if(type(dd)=="string")then +if(colors[dd])then dd=colors[dd]end end end;self.set(cd,dd)end end end +if(ad~=false)then if(self:isType("Container"))then local cd=self.get("children") +for dd,__a in +ipairs(cd)do if(__a and __a.applyTheme)then __a:applyTheme()end end end end;return self end +function _c:getTheme()local ad=self:____getElementPath() +local bd=self.get("type")local cd=self.get("name")return dc(cb[db],ad,bd,cd)end;local _d={}function _d.setTheme(ad)cb.default=ad end +function _d.getTheme()return cb.default end +function _d.loadTheme(ad)local bd=fs.open(ad,"r") +if bd then local cd=bd.readAll()bd.close() +cb.default=textutils.unserializeJSON(cd)if not cb.default then +ab.error("Failed to load theme from "..ad)end else +ab.error("Could not open theme file: "..ad)end end;return{BaseElement=_c,API=_d} end +project["plugins/reactive.lua"] = function(...) local cb=require("errorManager") +local db=require("propertySystem")local _c={colors=true,math=true,clamp=true,round=true} +local ac={clamp=function(__a,a_a,b_a)return +math.min(math.max(__a,a_a),b_a)end,round=function(__a) +return math.floor(__a+0.5)end,floor=math.floor,ceil=math.ceil,abs=math.abs} +local function bc(__a)return +{parent=__a:find("parent%."),self=__a:find("self%."),other=__a:find("[^(parent)][^(self)]%.")}end +local function cc(__a,a_a,b_a)local c_a=bc(__a) +if c_a.parent and not a_a.parent then +cb.header="Reactive evaluation error" +cb.error("Expression uses parent but no parent available")return function()return nil end end;__a=__a:gsub("^{(.+)}$","%1") +__a=__a:gsub("([%w_]+)%$([%w_]+)",function(baa,caa) +if baa=="self"then return +string.format('__getState("%s")',caa)elseif baa=="parent"then return +string.format('__getParentState("%s")',caa)else return +string.format('__getElementState("%s", "%s")',baa,caa)end end) +__a=__a:gsub("([%w_]+)%.([%w_]+)",function(baa,caa)if _c[baa]then return baa.."."..caa end;if +tonumber(baa)then return baa.."."..caa end;return +string.format('__getProperty("%s", "%s")',baa,caa)end) +local d_a=setmetatable({colors=colors,math=math,tostring=tostring,tonumber=tonumber,__getState=function(baa)return a_a:getState(baa)end,__getParentState=function(baa)return +a_a.parent:getState(baa)end,__getElementState=function(baa,caa)if tonumber(baa)then return nil end +local daa=a_a:getBaseFrame():getChild(baa)if not daa then cb.header="Reactive evaluation error" +cb.error("Could not find element: "..baa)return nil end;return +daa:getState(caa).value end,__getProperty=function(baa,caa)if +tonumber(baa)then return nil end +if baa=="self"then if a_a._properties[caa]then +return a_a.get(caa)end;if +a_a._registeredStates and a_a._registeredStates[caa]then return a_a:hasState(caa)end +local daa=a_a.get("states")if daa and daa[caa]~=nil then return true end +cb.header="Reactive evaluation error" +cb.error("Property or state '"..caa.. +"' not found in element '"..a_a:getType().."'")return nil elseif baa=="parent"then if a_a.parent._properties[caa]then return +a_a.parent.get(caa)end;if a_a.parent._registeredStates and +a_a.parent._registeredStates[caa]then +return a_a.parent:hasState(caa)end +local daa=a_a.parent.get("states")if daa and daa[caa]~=nil then return true end +cb.header="Reactive evaluation error" +cb.error("Property or state '"..caa.."' not found in parent element")return nil else local daa=a_a.parent:getChild(baa)if not daa then +cb.header="Reactive evaluation error" +cb.error("Could not find element: "..baa)return nil end;if +daa._properties[caa]then return daa.get(caa)end +if daa._registeredStates and +daa._registeredStates[caa]then return daa:hasState(caa)end;local _ba=daa.get("states") +if _ba and _ba[caa]~=nil then return true end;cb.header="Reactive evaluation error" +cb.error("Property or state '"..caa.. +"' not found in element '"..baa.."'")return nil end end},{__index=ac})if(a_a._properties[b_a].type=="string")then +__a="tostring("..__a..")"elseif(a_a._properties[b_a].type=="number")then +__a="tonumber("..__a..")"end;local _aa,aaa=load( +"return "..__a,"reactive","t",d_a) +if not _aa then +cb.header="Reactive evaluation error"cb.error("Invalid expression: "..aaa)return +function()return nil end end;return _aa end +local function dc(__a,a_a) +for b_a in __a:gmatch("([%w_]+)%.")do +if not _c[b_a]then +if b_a=="self"then elseif b_a=="parent"then +if not a_a.parent then +cb.header="Reactive evaluation error"cb.error("No parent element available")return false end else +if(tonumber(b_a)==nil)then local c_a=a_a.parent:getChild(b_a)if not c_a then +cb.header="Reactive evaluation error" +cb.error("Referenced element not found: "..b_a)return false end end end end end;return true end;local _d=setmetatable({},{__mode="k"}) +local ad=setmetatable({},{__mode="k",__index=function(__a,a_a)__a[a_a]={}return +__a[a_a]end}) +local bd=setmetatable({},{__mode="k",__index=function(__a,a_a)__a[a_a]={}return __a[a_a]end}) +local function cd(__a,a_a,b_a)local c_a=bc(a_a) +if ad[__a][b_a]then for _aa,aaa in ipairs(ad[__a][b_a])do +aaa.target:removeObserver(aaa.property,aaa.callback)end end;local d_a={} +for _aa,aaa in a_a:gmatch("([%w_]+)%.([%w_]+)")do +if not _c[_aa]then local baa +if +_aa=="self"and c_a.self then baa=__a elseif _aa=="parent"and c_a.parent then baa=__a.parent elseif c_a.other then +baa=__a:getBaseFrame():getChild(_aa)end +if baa then local caa=false +if baa._properties[aaa]then caa=false elseif baa._registeredStates and +baa._registeredStates[aaa]then caa=true else local _ba=baa.get("states")if _ba and +_ba[aaa]~=nil then caa=true end end +local daa={target=baa,property=caa and"states"or aaa,callback=function()local _ba=bd[__a][b_a]local aba=__a.get(b_a) +if +_ba~=aba then bd[__a][b_a]=aba +if +__a._observers and __a._observers[b_a]then for bba,cba in ipairs(__a._observers[b_a])do cba()end end;__a:updateRender()end end}baa:observe(daa.property,daa.callback) +table.insert(d_a,daa)end end end;ad[__a][b_a]=d_a end +db.addSetterHook(function(__a,a_a,b_a,c_a) +if type(b_a)=="string"and b_a:match("^{.+}$")then +local d_a=b_a:gsub("^{(.+)}$","%1")local _aa=bc(d_a) +if _aa.parent and not __a.parent then return c_a.default end;if not dc(d_a,__a)then return c_a.default end +cd(__a,d_a,a_a)if not _d[__a]then _d[__a]={}end;if not _d[__a][b_a]then +local aaa=cc(b_a,__a,a_a)_d[__a][b_a]=aaa end +return +function(aaa) +if __a._destroyed or(_aa.parent and not +__a.parent)then return c_a.default end;local baa,caa=pcall(_d[__a][b_a]) +if not baa then +if caa and +caa:match("attempt to index.-nil value")then return c_a.default end;cb.header="Reactive evaluation error"if type(caa)=="string"then cb.error( +"Error evaluating expression: "..caa)else +cb.error("Error evaluating expression")end +return c_a.default end;bd[__a][a_a]=caa;return caa end end end)local dd={} +dd.hooks={destroy=function(__a) +if ad[__a]then +for a_a,b_a in pairs(ad[__a])do for c_a,d_a in ipairs(b_a)do +d_a.target:removeObserver(d_a.property,d_a.callback)end end;ad[__a]=nil;bd[__a]=nil;_d[__a]=nil end end}return{BaseElement=dd} end +project["plugins/xml.lua"] = function(...) local bb=require("errorManager")local cb=require("log") +local db={new=function(cd) +return +{tag=cd,value=nil,attributes={},children={},addChild=function(dd,__a) +table.insert(dd.children,__a)end,addAttribute=function(dd,__a,a_a)dd.attributes[__a]=a_a end}end} +local _c=function(cd,dd) +local __a,a_a=string.gsub(dd,"([%w:]+)=([\"'])(.-)%2",function(d_a,_aa,aaa) +cd:addAttribute(d_a,"\""..aaa.."\"")end) +local b_a,c_a=string.gsub(dd,"([%w:]+)={(.-)}",function(d_a,_aa)cd:addAttribute(d_a,_aa)end)end;local ac={} +ac={_customTagHandlers={},registerTagHandler=function(cd,dd)ac._customTagHandlers[cd]=dd +cb.info( +"XMLParser: Registered custom tag handler for '"..cd.."'")end,unregisterTagHandler=function(cd)ac._customTagHandlers[cd]= +nil +cb.info("XMLParser: Unregistered custom tag handler for '"..cd.."'")end,getTagHandler=function(cd)return +ac._customTagHandlers[cd]end,parseText=function(cd)local dd={}local __a=db.new() +table.insert(dd,__a)local a_a,b_a,c_a,d_a,_aa;local aaa,baa=1,1 +while true do +a_a,baa,b_a,c_a,d_a,_aa=string.find(cd,"<(%/?)([%w_:]+)(.-)(%/?)>",aaa)if not a_a then break end;local caa=string.sub(cd,aaa,a_a-1)if not +string.find(caa,"^%s*$")then local daa=(__a.value or"")..caa +dd[#dd].value=daa end +if _aa=="/"then local daa=db.new(c_a) +_c(daa,d_a)__a:addChild(daa)elseif b_a==""then local daa=db.new(c_a)_c(daa,d_a) +table.insert(dd,daa)__a=daa else local daa=table.remove(dd)__a=dd[#dd] +if#dd<1 then bb.error( +"XMLParser: nothing to close with "..c_a)end;if daa.tag~=c_a then +bb.error("XMLParser: trying to close "..daa.tag.." with "..c_a)end;__a:addChild(daa)end;aaa=baa+1 end;if#dd>1 then +error("XMLParser: unclosed "..dd[#dd].tag)end;return __a.children end} +local function bc(cd)local dd={}local __a=1 +while true do local a_a,b_a,c_a=cd:find("%${([^}]+)}",__a) +if not a_a then break end +table.insert(dd,{start=a_a,ending=b_a,expression=c_a,raw=cd:sub(a_a,b_a)})__a=b_a+1 end;return dd end +local function cc(cd,dd)if not cd then return cd end;if +cd:sub(1,1)=="\""and cd:sub(-1)=="\""then cd=cd:sub(2,-2)end;local __a=bc(cd) +for a_a,b_a in ipairs(__a)do +local c_a=b_a.expression;local d_a=b_a.start-1;local _aa=b_a.ending+1;if dd[c_a]then cd=cd:sub(1,d_a).. +tostring(dd[c_a])..cd:sub(_aa)else +bb.error( +"XMLParser: variable '"..c_a.."' not found in scope")end end +if cd:match("^%s*%s*$")then +local a_a=cd:match("")local b_a=_ENV;for baa,caa in pairs(dd)do b_a[baa]=caa end +local c_a,d_a=load("return "..a_a,nil,"bt",b_a)if not c_a then +bb.error("XMLParser: CDATA syntax error: "..tostring(d_a))end;local _aa,aaa=pcall(c_a)if not _aa then +bb.error( +"XMLParser: CDATA execution error: "..tostring(aaa))end;return aaa end +if cd=="true"then return true elseif cd=="false"then return false elseif colors[cd]then return colors[cd]elseif tonumber(cd)then return +tonumber(cd)else return cd end end +local function dc(cd,dd)local __a={} +for a_a,b_a in pairs(cd.children)do +if b_a.tag=="item"or b_a.tag=="entry"then +local c_a={} +for d_a,_aa in pairs(b_a.attributes)do c_a[d_a]=cc(_aa,dd)end;for d_a,_aa in pairs(b_a.children)do +if _aa.value then c_a[_aa.tag]=cc(_aa.value,dd)elseif# +_aa.children>0 then c_a[_aa.tag]=dc(_aa)end end +table.insert(__a,c_a)else if b_a.value then __a[b_a.tag]=cc(b_a.value,dd)elseif#b_a.children>0 then +__a[b_a.tag]=dc(b_a)end end end;return __a end +local function _d(cd,dd,__a,a_a)local b_a,c_a=dd:match("^(.+)State:(.+)$") +if b_a and c_a then +c_a=c_a:gsub("^\"",""):gsub("\"$","") +local d_a=b_a:sub(1,1):upper()..b_a:sub(2)local _aa="set"..d_a.."State" +if cd[_aa]then +cd[_aa](cd,c_a,cc(__a,a_a))return true else +cb.warn("XMLParser: State method '".._aa.. +"' not found for element '"..cd:getType().."'")return true end end;return false end;local ad={}function ad.setup(cd) +cd.defineProperty(cd,"customXML",{default={attributes={},children={}},type="table"})end +function ad:fromXML(cd,dd) +if(cd.attributes)then +for __a,a_a in +pairs(cd.attributes)do +if not _d(self,__a,a_a,dd)then +if(self._properties[__a])then +self.set(__a,cc(a_a,dd))elseif self[__a]then +if(__a:sub(1,2)=="on")then local b_a=a_a:gsub("\"","") +if(dd[b_a])then if( +type(dd[b_a])~="function")then +bb.error("XMLParser: variable '".. +b_a.."' is not a function for element '"..self:getType().. +"' "..__a)end +self[__a](self,dd[b_a])else +bb.error("XMLParser: variable '"..b_a.."' not found in scope")end else +bb.error("XMLParser: property '"..__a.. +"' not found in element '"..self:getType().."'")end else local b_a=self.get("customXML") +b_a.attributes[__a]=cc(a_a,dd)end end end end +if(cd.children)then +for __a,a_a in pairs(cd.children)do +if a_a.tag=="state"then +local b_a=a_a.attributes and a_a.attributes.name;if not b_a then +bb.error("XMLParser: tag requires 'name' attribute")end +b_a=b_a:gsub("^\"",""):gsub("\"$","") +if a_a.children then +for c_a,d_a in ipairs(a_a.children)do local _aa=d_a.tag;local aaa +if +d_a.attributes and d_a.attributes.value then aaa=cc(d_a.attributes.value,dd)elseif d_a.value then +aaa=cc(d_a.value,dd)else +cb.warn("XMLParser: State property '".._aa.."' has no value")aaa=nil end +if aaa~=nil then +local baa=_aa:sub(1,1):upper().._aa:sub(2)local caa="set"..baa.."State"if self[caa]then +self[caa](self,b_a,aaa)else +cb.warn("XMLParser: State method '"..caa.. +"' not found for element '"..self:getType().."'")end end end end elseif(self._properties[a_a.tag])then if +(self._properties[a_a.tag].type=="table")then self.set(a_a.tag,dc(a_a,dd))else +self.set(a_a.tag,cc(a_a.value,dd))end else local b_a={} +if(a_a.children)then +for c_a,d_a in +pairs(a_a.children)do +if(d_a.tag=="param")then +table.insert(b_a,cc(d_a.value,dd))elseif(d_a.tag=="table")then table.insert(b_a,dc(d_a,dd))end end end +if(self[a_a.tag])then if(#b_a>0)then +self[a_a.tag](self,table.unpack(b_a))elseif(a_a.value)then self[a_a.tag](self,cc(a_a.value,dd))else +self[a_a.tag](self)end else +local c_a=self.get("customXML")a_a.value=cc(a_a.value,dd)c_a.children[a_a.tag]=a_a end end end end;return self end;local bd={} +function bd:loadXML(cd,dd)dd=dd or{}local __a=ac.parseText(cd) +self:fromXML(__a,dd) +if(__a)then +for a_a,b_a in ipairs(__a)do +local c_a=b_a.tag:sub(1,1):upper()..b_a.tag:sub(2)if self["add"..c_a]then local d_a=self["add"..c_a](self) +d_a:fromXML(b_a,dd)end end end;return self end +function bd:fromXML(cd,dd)ad.fromXML(self,cd,dd) +if(cd.children)then +for __a,a_a in ipairs(cd.children)do local b_a= +a_a.tag:sub(1,1):upper()..a_a.tag:sub(2) +local c_a=ac.getTagHandler(a_a.tag) +if c_a then local d_a=c_a(a_a,self,dd)elseif self["add"..b_a]then +local d_a=self["add"..b_a](self)d_a:fromXML(a_a,dd)else +cb.warn("XMLParser: Unknown tag '".. +a_a.tag.."' - no handler or element found")end end end;return self end;return{API=ac,Container=bd,BaseElement=ad} end +project["plugins/debug.lua"] = function(...) local _b=require("log")local ab=require("libraries/colorHex") +local bb=10;local cb=false;local db={ERROR=1,WARN=2,INFO=3,DEBUG=4} +local function _c(dc) +local _d={renderCount=0,eventCount={},lastRender=os.epoch("utc"),properties={},children={}} +return +{trackProperty=function(ad,bd)_d.properties[ad]=bd end,trackRender=function() +_d.renderCount=_d.renderCount+1;_d.lastRender=os.epoch("utc")end,trackEvent=function(ad)_d.eventCount[ad]=( +_d.eventCount[ad]or 0)+1 end,dump=function()return +{type=dc.get("type"),id=dc.get("id"),stats=_d}end}end;local ac={} +function ac.debug(dc,_d)dc._debugger=_c(dc)dc._debugLevel=_d or db.INFO;return dc end;function ac.dumpDebug(dc)if not dc._debugger then return end +return dc._debugger.dump()end;local bc={} +function bc.openConsole(dc) +if +not dc._debugFrame then local _d=dc.get("width")local ad=dc.get("height") +dc._debugFrame=dc:addFrame("basaltDebugLog"):setWidth(_d):setHeight(ad):listenEvent("mouse_scroll",true) +dc._debugFrame:addButton("basaltDebugLogClose"):setWidth(9):setHeight(1):setX( +_d-8):setY(ad):setText("Close"):onClick(function() +dc:closeConsole()end)dc._debugFrame._scrollOffset=0 +dc._debugFrame._processedLogs={} +local function bd(b_a,c_a)local d_a={}while#b_a>0 do local _aa=b_a:sub(1,c_a)table.insert(d_a,_aa)b_a=b_a:sub( +c_a+1)end;return d_a end +local function cd()local b_a={}local c_a=dc._debugFrame.get("width") +for d_a,_aa in +ipairs(_b._logs)do local aaa=bd(_aa.message,c_a)for baa,caa in ipairs(aaa)do +table.insert(b_a,{text=caa,level=_aa.level})end end;return b_a end;local dd=#cd()-dc.get("height")dc._scrollOffset=dd +local __a=dc._debugFrame.render +dc._debugFrame.render=function(b_a)__a(b_a)b_a._processedLogs=cd() +local c_a=b_a.get("height")-2;local d_a=#b_a._processedLogs;local _aa=math.max(0,d_a-c_a) +b_a._scrollOffset=math.min(b_a._scrollOffset,_aa) +for i=1,c_a-2 do local aaa=i+b_a._scrollOffset +local baa=b_a._processedLogs[aaa] +if baa then +local caa= + +baa.level==_b.LEVEL.ERROR and colors.red or baa.level== +_b.LEVEL.WARN and colors.yellow or baa.level==_b.LEVEL.DEBUG and colors.lightGray or colors.white;b_a:textFg(2,i,baa.text,caa)end end end;local a_a=dc._debugFrame.dispatchEvent +dc._debugFrame.dispatchEvent=function(b_a,c_a,d_a,...) +if +(c_a=="mouse_scroll")then +b_a._scrollOffset=math.max(0,b_a._scrollOffset+d_a)b_a:updateRender()return true else return a_a(b_a,c_a,d_a,...)end end end +dc._debugFrame.set("width",dc.get("width")) +dc._debugFrame.set("height",dc.get("height"))dc._debugFrame.set("visible",true)return dc end +function bc.closeConsole(dc)if dc._debugFrame then +dc._debugFrame.set("visible",false)end;return dc end;function bc.toggleConsole(dc)if dc._debugFrame and dc._debugFrame:getVisible()then +dc:closeConsole()else dc:openConsole()end +return dc end +local cc={} +function cc.debugChildren(dc,_d)dc:debug(_d)for ad,bd in pairs(dc.get("children"))do if bd.debug then +bd:debug(_d)end end;return dc end;return{BaseElement=ac,Container=cc,BaseFrame=bc} end +project["plugins/animation.lua"] = function(...) local aa={} +local ba={linear=function(ab)return ab end,easeInQuad=function(ab)return ab*ab end,easeOutQuad=function(ab)return +1 - (1 -ab)* (1 -ab)end,easeInOutQuad=function(ab)if ab<0.5 then return 2 *ab*ab end;return 1 - ( +-2 *ab+2)^2 /2 end}local ca={}ca.__index=ca +function ca.new(ab,bb,cb,db,_c)local ac=setmetatable({},ca)ac.element=ab +ac.type=bb;ac.args=cb;ac.duration=db or 1;ac.startTime=0;ac.isPaused=false +ac.handlers=aa[bb]ac.easing=_c;return ac end;function ca:start()self.startTime=os.epoch("local")/1000;if +self.handlers.start then self.handlers.start(self)end +return self end +function ca:update(ab)local bb=math.min(1, +ab/self.duration) +local cb=ba[self.easing](bb)return self.handlers.update(self,cb)end;function ca:complete()if self.handlers.complete then +self.handlers.complete(self)end end +local da={}da.__index=da +function da.registerAnimation(ab,bb)aa[ab]=bb +da[ab]=function(cb,...)local db={...}local _c="linear" +if( +type(db[#db])=="string")then _c=table.remove(db,#db)end;local ac=table.remove(db,#db) +return cb:addAnimation(ab,db,ac,_c)end end;function da.registerEasing(ab,bb)ba[ab]=bb end +function da.new(ab)local bb={}bb.element=ab +bb.sequences={{}}bb.sequenceCallbacks={}bb.currentSequence=1;bb.timer=nil +setmetatable(bb,da)return bb end +function da:sequence()table.insert(self.sequences,{})self.currentSequence=# +self.sequences;self.sequenceCallbacks[self.currentSequence]={start=nil,update=nil,complete= +nil}return self end +function da:onStart(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].start=ab;return self end +function da:onUpdate(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].update=ab;return self end +function da:onComplete(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].complete=ab;return self end +function da:addAnimation(ab,bb,cb,db)local _c=ca.new(self.element,ab,bb,cb,db) +table.insert(self.sequences[self.currentSequence],_c)return self end +function da:start()self.currentSequence=1;self.timer=nil +if +(self.sequenceCallbacks[self.currentSequence])then if(self.sequenceCallbacks[self.currentSequence].start)then +self.sequenceCallbacks[self.currentSequence].start(self.element)end end +if +#self.sequences[self.currentSequence]>0 then self.timer=os.startTimer(0.05)for ab,bb in +ipairs(self.sequences[self.currentSequence])do bb:start()end end;return self end +function da:event(ab,bb) +if ab=="timer"and bb==self.timer then +local cb=os.epoch("local")/1000;local db=true;local _c={} +local ac=self.sequenceCallbacks[self.currentSequence] +for bc,cc in ipairs(self.sequences[self.currentSequence])do +local dc=cb-cc.startTime;local _d=dc/cc.duration;local ad=cc:update(dc)if ac and ac.update then +ac.update(self.element,_d)end;if not ad then table.insert(_c,cc)db=false else +cc:complete()end end +if db then +if ac and ac.complete then ac.complete(self.element)end +if self.currentSequence<#self.sequences then +self.currentSequence=self.currentSequence+1;_c={} +local bc=self.sequenceCallbacks[self.currentSequence]if bc and bc.start then bc.start(self.element)end +for cc,dc in +ipairs(self.sequences[self.currentSequence])do dc:start()table.insert(_c,dc)end end end;if#_c>0 then self.timer=os.startTimer(0.05)end +return true end end +function da:stop()if self.timer then pcall(os.cancelTimer,self.timer) +self.timer=nil end +for ab,bb in ipairs(self.sequences)do for cb,db in ipairs(bb)do +pcall(function()if db and +db.complete then db:complete()end end)end end;if +self.element and type(self.element.set)=="function"then +pcall(function()self.element.set("animation",nil)end)end end +da.registerAnimation("move",{start=function(ab)ab.startX=ab.element.get("x") +ab.startY=ab.element.get("y")end,update=function(ab,bb)local cb=ab.startX+ +(ab.args[1]-ab.startX)*bb;local db=ab.startY+ +(ab.args[2]-ab.startY)*bb +ab.element.set("x",math.floor(cb))ab.element.set("y",math.floor(db))return bb>=1 end,complete=function(ab) +ab.element.set("x",ab.args[1])ab.element.set("y",ab.args[2])end}) +da.registerAnimation("resize",{start=function(ab)ab.startW=ab.element.get("width") +ab.startH=ab.element.get("height")end,update=function(ab,bb)local cb=ab.startW+ +(ab.args[1]-ab.startW)*bb;local db=ab.startH+ +(ab.args[2]-ab.startH)*bb +ab.element.set("width",math.floor(cb))ab.element.set("height",math.floor(db)) +return bb>=1 end,complete=function(ab) +ab.element.set("width",ab.args[1])ab.element.set("height",ab.args[2])end}) +da.registerAnimation("moveOffset",{start=function(ab)ab.startX=ab.element.get("offsetX") +ab.startY=ab.element.get("offsetY")end,update=function(ab,bb)local cb=ab.startX+ (ab.args[1]-ab.startX)* +bb;local db=ab.startY+ (ab.args[2]- +ab.startY)*bb +ab.element.set("offsetX",math.floor(cb))ab.element.set("offsetY",math.floor(db))return +bb>=1 end,complete=function(ab) +ab.element.set("offsetX",ab.args[1])ab.element.set("offsetY",ab.args[2])end}) +da.registerAnimation("number",{start=function(ab) +ab.startValue=ab.element.get(ab.args[1])ab.targetValue=ab.args[2]end,update=function(ab,bb) +local cb= +ab.startValue+ (ab.targetValue-ab.startValue)*bb +ab.element.set(ab.args[1],math.floor(cb))return bb>=1 end,complete=function(ab) +ab.element.set(ab.args[1],ab.targetValue)end}) +da.registerAnimation("entries",{start=function(ab) +ab.startColor=ab.element.get(ab.args[1])ab.colorList=ab.args[2]end,update=function(ab,bb) +local cb=ab.colorList;local db=math.floor(#cb*bb)+1;if db>#cb then db=#cb end +ab.element.set(ab.args[1],cb[db])end,complete=function(ab) +ab.element.set(ab.args[1],ab.colorList[ +#ab.colorList])end}) +da.registerAnimation("morphText",{start=function(ab)local bb=ab.element.get(ab.args[1]) +local cb=ab.args[2]local db=math.max(#bb,#cb) +local _c=string.rep(" ",math.floor(db-#bb)/2)ab.startText=_c..bb.._c +ab.targetText=cb..string.rep(" ",db-#cb)ab.length=db end,update=function(ab,bb) +local cb="" +for i=1,ab.length do local db=ab.startText:sub(i,i) +local _c=ab.targetText:sub(i,i) +if bb<0.5 then +cb=cb.. (math.random()>bb*2 and db or" ")else cb=cb.. +(math.random()> (bb-0.5)*2 and" "or _c)end end;ab.element.set(ab.args[1],cb)return bb>=1 end,complete=function(ab) +ab.element.set(ab.args[1],ab.targetText:gsub("%s+$",""))end}) +da.registerAnimation("typewrite",{start=function(ab)ab.targetText=ab.args[2] +ab.element.set(ab.args[1],"")end,update=function(ab,bb) +local cb=math.floor(#ab.targetText*bb) +ab.element.set(ab.args[1],ab.targetText:sub(1,cb))return bb>=1 end}) +da.registerAnimation("fadeText",{start=function(ab)ab.chars={}for i=1,#ab.args[2]do +ab.chars[i]={char=ab.args[2]:sub(i,i),visible=false}end end,update=function(ab,bb) +local cb=""for db,_c in ipairs(ab.chars)do +if math.random()=1 end}) +da.registerAnimation("scrollText",{start=function(ab)ab.width=ab.element.get("width")ab.startText= +ab.element.get(ab.args[1])or"" +ab.targetText=ab.args[2]or""ab.startText=tostring(ab.startText) +ab.targetText=tostring(ab.targetText)end,update=function(ab,bb) +local cb=ab.width +if bb<0.5 then local db=bb/0.5;local _c=math.floor(cb*db) +local ac=( +ab.startText:sub(_c+1)..string.rep(" ",cb)):sub(1,cb)ab.element.set(ab.args[1],ac)else +local db=(bb-0.5)/0.5;local _c=math.floor(cb* (1 -db)) +local ac=string.rep(" ",_c)..ab.targetText;local bc=ac:sub(1,cb)ab.element.set(ab.args[1],bc)end;return bb>=1 end,complete=function(ab)local bb=( +ab.targetText..string.rep(" ",ab.width)) +ab.element.set(ab.args[1],bb)end}) +da.registerAnimation("marquee",{start=function(ab)ab.width=ab.element.get("width")ab.text=tostring( +ab.args[2]or"") +ab.speed=tonumber(ab.args[3])or 0.15;ab.offset=0;ab.lastShift=-1 +ab.padded=ab.text..string.rep(" ",ab.width)end,update=function(ab,bb)local cb= +os.epoch("local")/1000 -ab.startTime +local db=math.max(0.01,ab.speed)local _c=math.floor(cb/db) +if _c~=ab.lastShift then ab.lastShift=_c +local ac=#ab.padded;local bc=(_c%ac)+1;local cc=ab.padded..ab.padded +local dc=cc:sub(bc,bc+ab.width-1)ab.element.set(ab.args[1],dc)end;return false end,complete=function(ab) +end})local _b={hooks={}} +function _b.hooks.handleEvent(ab,bb,...)if bb=="timer"then local cb=ab.get("animation")if cb then +cb:event(bb,...)end end end +function _b.setup(ab) +ab.defineProperty(ab,"animation",{default=nil,type="table"})ab.defineEvent(ab,"timer")end +function _b.stopAnimation(ab)local bb=ab.get("animation") +if +bb and type(bb.stop)=="function"then bb:stop()else ab.set("animation",nil)end;return ab end +function _b:animate()local ab=da.new(self)self.set("animation",ab)return ab end;return{VisualElement=_b} end +project["plugins/benchmark.lua"] = function(...) local ca=require("log")local da=setmetatable({},{__mode="k"})local function _b()return +{methods={}}end +local function ab(_c,ac)local bc=_c[ac] +if not da[_c]then da[_c]=_b()end +if not da[_c].methods[ac]then +da[_c].methods[ac]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=ac,originalMethod=bc}end +_c[ac]=function(cc,...)cc:startProfile(ac)local dc=bc(cc,...) +cc:endProfile(ac)return dc end end;local bb={} +function bb:startProfile(_c)local ac=da[self]if not ac then ac=_b()da[self]=ac end;if not +ac.methods[_c]then +ac.methods[_c]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=_c}end +local bc=ac.methods[_c]bc.startTime=os.clock()*1000;bc.path={}local cc=self;while cc do +table.insert(bc.path,1, +cc.get("name")or cc.get("id"))cc=cc.parent end;return self end +function bb:endProfile(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]local cc=os.clock()*1000 +local dc=cc-bc.startTime;bc.calls=bc.calls+1;bc.totalTime=bc.totalTime+dc +bc.minTime=math.min(bc.minTime,dc)bc.maxTime=math.max(bc.maxTime,dc)bc.lastTime=dc;return self end +function bb:benchmark(_c)if not self[_c]then +ca.error("Method ".._c.." does not exist")return self end;da[self]=_b() +da[self].methodName=_c;da[self].isRunning=true;ab(self,_c)return self end +function bb:logBenchmark(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c] +if bc then local cc= +bc.calls>0 and(bc.totalTime/bc.calls)or 0 +ca.info(string.format( +"Benchmark results for %s.%s: ".. +"Path: %s ".."Calls: %d ".. +"Average time: %.2fms ".."Min time: %.2fms ".."Max time: %.2fms ".. +"Last time: %.2fms ".."Total time: %.2fms",table.concat(bc.path,"."),bc.methodName,table.concat(bc.path,"/"),bc.calls,cc, +bc.minTime~=math.huge and bc.minTime or 0,bc.maxTime,bc.lastTime,bc.totalTime))end;return self end +function bb:stopBenchmark(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]if bc and bc.originalMethod then +self[_c]=bc.originalMethod end;ac.methods[_c]=nil;if +not next(ac.methods)then da[self]=nil end;return self end +function bb:getBenchmarkStats(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return nil end;local bc=ac.methods[_c]return +{averageTime=bc.totalTime/bc.calls,totalTime=bc.totalTime,calls=bc.calls,minTime=bc.minTime,maxTime=bc.maxTime,lastTime=bc.lastTime}end;local cb={} +function cb:benchmarkContainer(_c)self:benchmark(_c) +for ac,bc in +pairs(self.get("children"))do bc:benchmark(_c)if bc:isType("Container")then +bc:benchmarkContainer(_c)end end;return self end +function cb:logContainerBenchmarks(_c,ac)ac=ac or 0;local bc=string.rep(" ",ac)local cc=0;local dc={} +for ad,bd in +pairs(self.get("children"))do local cd=da[bd] +if cd and cd.methods[_c]then local dd=cd.methods[_c] +cc=cc+dd.totalTime +table.insert(dc,{element=bd,type=bd.get("type"),calls=dd.calls,totalTime=dd.totalTime,avgTime=dd.totalTime/dd.calls})end end;local _d=da[self] +if _d and _d.methods[_c]then local ad=_d.methods[_c] +local bd=ad.totalTime-cc;local cd=bd/ad.calls +ca.info(string.format("%sBenchmark %s (%s): ".."%.2fms/call (Self: %.2fms/call) ".. +"[Total: %dms, Calls: %d]",bc,self.get("type"),_c, +ad.totalTime/ad.calls,cd,ad.totalTime,ad.calls)) +if#dc>0 then +for dd,__a in ipairs(dc)do +if __a.element:isType("Container")then __a.element:logContainerBenchmarks(_c, +ac+1)else +ca.info(string.format("%s> %s: %.2fms/call [Total: %dms, Calls: %d]", +bc.." ",__a.type,__a.avgTime,__a.totalTime,__a.calls))end end end end;return self end +function cb:stopContainerBenchmark(_c) +for ac,bc in pairs(self.get("children"))do if bc:isType("Container")then +bc:stopContainerBenchmark(_c)else bc:stopBenchmark(_c)end end;self:stopBenchmark(_c)return self end;local db={} +function db.start(_c,ac)ac=ac or{}local bc=_b()bc.name=_c +bc.startTime=os.clock()*1000;bc.custom=true;bc.calls=0;bc.totalTime=0;bc.minTime=math.huge;bc.maxTime=0 +bc.lastTime=0;da[_c]=bc end +function db.stop(_c)local ac=da[_c]if not ac or not ac.custom then return end;local bc= +os.clock()*1000;local cc=bc-ac.startTime;ac.calls=ac.calls+1;ac.totalTime= +ac.totalTime+cc;ac.minTime=math.min(ac.minTime,cc) +ac.maxTime=math.max(ac.maxTime,cc)ac.lastTime=cc +ca.info(string.format("Custom Benchmark '%s': ".. +"Calls: %d ".."Average time: %.2fms ".. +"Min time: %.2fms ".. +"Max time: %.2fms ".."Last time: %.2fms ".."Total time: %.2fms",_c,ac.calls, +ac.totalTime/ac.calls,ac.minTime,ac.maxTime,ac.lastTime,ac.totalTime))end +function db.getStats(_c)local ac=da[_c]if not ac then return nil end;return +{averageTime=ac.totalTime/ac.calls,totalTime=ac.totalTime,calls=ac.calls,minTime=ac.minTime,maxTime=ac.maxTime,lastTime=ac.lastTime}end;function db.clear(_c)da[_c]=nil end;function db.clearAll()for _c,ac in pairs(da)do +if ac.custom then da[_c]=nil end end end;return +{BaseElement=bb,Container=cb,API=db} end +project["elementManager.lua"] = function(...) local _c=table.pack(...) +local ac=fs.getDir(_c[2]or"basalt")local bc=_c[1]if(ac==nil)then +error("Unable to find directory ".. +_c[2].." please report this bug to our discord.")end +local cc=require("log")local dc=package.path;local _d="path;/path/?.lua;/path/?/init.lua;" +local ad=_d:gsub("path",ac)local bd={}bd._elements={}bd._plugins={}bd._APIs={} +bd._config={autoLoadMissing=false,allowRemoteLoading=false,allowDiskLoading=true,remoteSources={},diskMounts={},useGlobalCache=false,globalCacheName="_BASALT_ELEMENT_CACHE"}local cd=fs.combine(ac,"elements") +local dd=fs.combine(ac,"plugins")cc.info("Loading elements from "..cd) +if +fs.exists(cd)then +for d_a,_aa in ipairs(fs.list(cd))do local aaa=_aa:match("(.+).lua")if aaa then cc.debug( +"Found element: "..aaa) +bd._elements[aaa]={class=nil,plugins={},loaded=false,source="local",path=nil}end end end;cc.info("Loading plugins from "..dd) +if +fs.exists(dd)then +for d_a,_aa in ipairs(fs.list(dd))do local aaa=_aa:match("(.+).lua") +if aaa then cc.debug("Found plugin: ".. +aaa) +local baa=require(fs.combine("plugins",aaa)) +if type(baa)=="table"then +for caa,daa in pairs(baa)do +if(caa~="API")then if(bd._plugins[caa]==nil)then +bd._plugins[caa]={}end +table.insert(bd._plugins[caa],daa)else bd._APIs[aaa]=daa end end end end end end +if(minified)then if(minified_elementDirectory==nil)then +error("Unable to find minified_elementDirectory please report this bug to our discord.")end;for d_a,_aa in +pairs(minified_elementDirectory)do +bd._elements[d_a:gsub(".lua","")]={class=nil,plugins={},loaded=false,source="local",path=nil}end;if( +minified_pluginDirectory==nil)then +error("Unable to find minified_pluginDirectory please report this bug to our discord.")end +for d_a,_aa in +pairs(minified_pluginDirectory)do local aaa=d_a:gsub(".lua","") +local baa=require(fs.combine("plugins",aaa)) +if type(baa)=="table"then +for caa,daa in pairs(baa)do +if(caa~="API")then if(bd._plugins[caa]==nil)then +bd._plugins[caa]={}end +table.insert(bd._plugins[caa],daa)else bd._APIs[aaa]=daa end end end end end +local function __a(d_a,_aa)if not bd._config.useGlobalCache then return end +if not +_G[bd._config.globalCacheName]then _G[bd._config.globalCacheName]={}end;_G[bd._config.globalCacheName][d_a]=_aa;cc.debug( +"Cached element in _G: "..d_a)end +local function a_a(d_a)if not bd._config.useGlobalCache then return nil end +if + +_G[bd._config.globalCacheName]and _G[bd._config.globalCacheName][d_a]then +cc.debug("Loaded element from _G cache: "..d_a)return _G[bd._config.globalCacheName][d_a]end;return nil end +function bd.configure(d_a)for _aa,aaa in pairs(d_a)do +if bd._config[_aa]~=nil then bd._config[_aa]=aaa end end end +function bd.registerDiskMount(d_a)if not fs.exists(d_a)then +error("Disk mount path does not exist: "..d_a)end +table.insert(bd._config.diskMounts,d_a)cc.info("Registered disk mount: "..d_a) +local _aa=fs.combine(d_a,"elements") +if fs.exists(_aa)then +for aaa,baa in ipairs(fs.list(_aa))do +local caa=baa:match("(.+).lua") +if caa then +if not bd._elements[caa]then +cc.debug("Found element on disk: "..caa) +bd._elements[caa]={class=nil,plugins={},loaded=false,source="disk",path=fs.combine(_aa,baa)}end end end end end +function bd.registerRemoteSource(d_a,_aa)if not bd._config.allowRemoteLoading then +error("Remote loading is disabled. Enable with ElementManager.configure({allowRemoteLoading = true})")end +bd._config.remoteSources[d_a]=_aa +if not bd._elements[d_a]then +bd._elements[d_a]={class=nil,plugins={},loaded=false,source="remote",path=_aa}else bd._elements[d_a].source="remote" +bd._elements[d_a].path=_aa end +cc.info("Registered remote source for "..d_a..": ".._aa)end +local function b_a(d_a)if not http then +error("HTTP API is not available. Enable it in your CC:Tweaked config.")end +cc.info("Loading element from remote: "..d_a)local _aa=http.get(d_a)if not _aa then +error("Failed to download from: "..d_a)end;local aaa=_aa.readAll()_aa.close()if +not aaa or aaa==""then +error("Empty response from: "..d_a)end;local baa,caa=load(aaa,d_a,"t",_ENV)if not baa then +error( +"Failed to load element from "..d_a..": "..tostring(caa))end;local daa=baa()return daa end +local function c_a(d_a)if not fs.exists(d_a)then +error("Element file does not exist: "..d_a)end +cc.info("Loading element from disk: "..d_a)local _aa,aaa=loadfile(d_a)if not _aa then +error("Failed to load element from ".. +d_a..": "..tostring(aaa))end;local baa=_aa()return baa end +function bd.tryAutoLoad(d_a) +if bd._config.allowDiskLoading then +for _aa,aaa in ipairs(bd._config.diskMounts)do +local baa=fs.combine(aaa,"elements")local caa=fs.combine(baa,d_a..".lua") +if fs.exists(caa)then +bd._elements[d_a]={class= +nil,plugins={},loaded=false,source="disk",path=caa}bd.loadElement(d_a)return true end end end +if +bd._config.allowRemoteLoading and bd._config.remoteSources[d_a]then bd.loadElement(d_a)return true end;return false end +function bd.loadElement(d_a) +if not bd._elements[d_a]then +if bd._config.autoLoadMissing then +local _aa=bd.tryAutoLoad(d_a)if not _aa then +error("Element '"..d_a.."' not found and could not be auto-loaded")end else +error("Element '"..d_a.."' not found")end end +if not bd._elements[d_a].loaded then local _aa=bd._elements[d_a].source or +"local"local aaa;local baa=false;aaa=a_a(d_a) +if aaa then +baa=true +cc.info("Loaded element from _G cache: "..d_a)elseif _aa=="local"then package.path=ad.."rom/?" +aaa=require(fs.combine("elements",d_a))package.path=dc elseif _aa=="disk"then if not bd._config.allowDiskLoading then +error( +"Disk loading is disabled for element: "..d_a)end +aaa=c_a(bd._elements[d_a].path)__a(d_a,aaa)elseif _aa=="remote"then if not bd._config.allowRemoteLoading then +error( +"Remote loading is disabled for element: "..d_a)end +aaa=b_a(bd._elements[d_a].path)__a(d_a,aaa)else +error("Unknown source type: ".._aa)end +bd._elements[d_a]={class=aaa,plugins=aaa.plugins,loaded=true,source=baa and"cache"or _aa,path=bd._elements[d_a].path}if not baa then +cc.debug("Loaded element: "..d_a.." from ".._aa)end +if(bd._plugins[d_a]~=nil)then +for caa,daa in +pairs(bd._plugins[d_a])do if(daa.setup)then daa.setup(aaa)end +if(daa.hooks)then +for _ba,aba in pairs(daa.hooks)do +local bba=aaa[_ba]if(type(bba)~="function")then +error("Element ".. +d_a.." does not have a method ".._ba)end +if(type(aba)=="function")then +aaa[_ba]=function(cba,...) +local dba=bba(cba,...)local _ca=aba(cba,...)return _ca==nil and dba or _ca end elseif(type(aba)=="table")then +aaa[_ba]=function(cba,...)if aba.pre then aba.pre(cba,...)end +local dba=bba(cba,...)if aba.post then aba.post(cba,...)end;return dba end end end end;for _ba,aba in pairs(daa)do +if _ba~="setup"and _ba~="hooks"then aaa[_ba]=aba end end end end end end +function bd.getElement(d_a) +if not bd._elements[d_a]then +if bd._config.autoLoadMissing then +local _aa=bd.tryAutoLoad(d_a)if not _aa then +error("Element '"..d_a.."' not found")end else +error("Element '"..d_a.."' not found")end end +if not bd._elements[d_a].loaded then bd.loadElement(d_a)end;return bd._elements[d_a].class end;function bd.getElementList()return bd._elements end;function bd.getAPI(d_a) +return bd._APIs[d_a]end +function bd.hasElement(d_a)return bd._elements[d_a]~=nil end +function bd.isElementLoaded(d_a)return +bd._elements[d_a]and bd._elements[d_a].loaded or false end +function bd.clearGlobalCache()if _G[bd._config.globalCacheName]then _G[bd._config.globalCacheName]= +nil +cc.info("Cleared global element cache")end end +function bd.getCacheStats()if not _G[bd._config.globalCacheName]then +return{size=0,elements={}}end;local d_a={}for _aa,aaa in +pairs(_G[bd._config.globalCacheName])do table.insert(d_a,_aa)end;return +{size=#d_a,elements=d_a}end +function bd.preloadElements(d_a)for _aa,aaa in ipairs(d_a)do +if bd._elements[aaa]and +not bd._elements[aaa].loaded then bd.loadElement(aaa)end end end;return bd end +project["log.lua"] = function(...) local aa={}aa._logs={}aa._enabled=false;aa._logToFile=false +aa._logFile="basalt.log"fs.delete(aa._logFile) +aa.LEVEL={DEBUG=1,INFO=2,WARN=3,ERROR=4} +local ba={[aa.LEVEL.DEBUG]="Debug",[aa.LEVEL.INFO]="Info",[aa.LEVEL.WARN]="Warn",[aa.LEVEL.ERROR]="Error"} +local ca={[aa.LEVEL.DEBUG]=colors.lightGray,[aa.LEVEL.INFO]=colors.white,[aa.LEVEL.WARN]=colors.yellow,[aa.LEVEL.ERROR]=colors.red}function aa.setLogToFile(ab)aa._logToFile=ab end +function aa.setEnabled(ab)aa._enabled=ab end;local function da(ab) +if aa._logToFile then local bb=io.open(aa._logFile,"a")if bb then +bb:write(ab.."\n")bb:close()end end end +local function _b(ab,...)if +not aa._enabled then return end;local bb=os.date("%H:%M:%S") +local cb=debug.getinfo(3,"Sl")local db=cb.source:match("@?(.*)")local _c=cb.currentline +local ac=string.format("[%s:%d]",db:match("([^/\\]+)%.lua$"),_c)local bc="["..ba[ab].."]"local cc="" +for _d,ad in ipairs(table.pack(...))do if _d>1 then cc= +cc.." "end;cc=cc..tostring(ad)end;local dc=string.format("%s %s%s %s",bb,ac,bc,cc)da(dc) +table.insert(aa._logs,{time=bb,level=ab,message=cc})end;function aa.debug(...)_b(aa.LEVEL.DEBUG,...)end;function aa.info(...) +_b(aa.LEVEL.INFO,...)end +function aa.warn(...)_b(aa.LEVEL.WARN,...)end;function aa.error(...)_b(aa.LEVEL.ERROR,...)end;return aa end +project["propertySystem.lua"] = function(...) local ba=require("libraries/utils").deepCopy +local ca=require("libraries/expect")local da=require("errorManager")local _b={}_b.__index=_b +_b._properties={}local ab={}_b._setterHooks={}function _b.addSetterHook(cb) +table.insert(_b._setterHooks,cb)end +local function bb(cb,db,_c,ac)for bc,cc in ipairs(_b._setterHooks)do +local dc=cc(cb,db,_c,ac)if dc~=nil then _c=dc end end;return _c end +function _b.defineProperty(cb,db,_c) +if not rawget(cb,'_properties')then cb._properties={}end +cb._properties[db]={type=_c.type,default=_c.default,canTriggerRender=_c.canTriggerRender,getter=_c.getter,setter=_c.setter,allowNil=_c.allowNil}local ac=db:sub(1,1):upper()..db:sub(2) +cb[ +"get"..ac]=function(bc,...)ca(1,bc,"element")local cc=bc._values[db] +if type(cc)== +"function"and _c.type~="function"then cc=cc(bc)end +return _c.getter and _c.getter(bc,cc,...)or cc end +cb["set"..ac]=function(bc,cc,...)ca(1,bc,"element")cc=bb(bc,db,cc,_c)if +type(cc)~="function"then +if _c.type=="table"then if cc==nil then +if not _c.allowNil then ca(2,cc,_c.type)end end else ca(2,cc,_c.type)end end;if +_c.setter then cc=_c.setter(bc,cc,...)end +bc:_updateProperty(db,cc)return bc end +cb["get"..ac.."State"]=function(bc,cc,...)ca(1,bc,"element")return +bc.getPropertyState(db,cc,...)end +cb["set"..ac.."State"]=function(bc,cc,dc,...)ca(1,bc,"element") +bc.setPropertyState(db,cc,dc,...)return bc end end +function _b.combineProperties(cb,db,...)local _c={...}for bc,cc in pairs(_c)do +if not cb._properties[cc]then da.error("Property not found: ".. +cc)end end;local ac= +db:sub(1,1):upper()..db:sub(2) +cb["get"..ac]=function(bc) +ca(1,bc,"element")local cc={} +for dc,_d in pairs(_c)do table.insert(cc,bc.get(_d))end;return table.unpack(cc)end +cb["set"..ac]=function(bc,...)ca(1,bc,"element")local cc={...}for dc,_d in pairs(_c)do +bc.set(_d,cc[dc])end;return bc end end +function _b.blueprint(cb,db,_c,ac) +if not ab[cb]then +local cc={basalt=_c,__isBlueprint=true,_values=db or{},_events={},render=function()end,dispatchEvent=function()end,init=function()end} +cc.loaded=function(_d,ad)_d.loadedCallback=ad;return cc end +cc.create=function(_d)local ad=cb.new()ad:init({},_d.basalt)for bd,cd in pairs(_d._values)do +ad._values[bd]=cd end;for bd,cd in pairs(_d._events)do +for dd,__a in ipairs(cd)do ad[bd](ad,__a)end end +if(ac~=nil)then ac:addChild(ad)end;ad:updateRender()_d.loadedCallback(ad) +ad:postInit()return ad end;local dc=cb +while dc do +if rawget(dc,'_properties')then for _d,ad in pairs(dc._properties)do +if +type(ad.default)=="table"then cc._values[_d]=ba(ad.default)else cc._values[_d]=ad.default end end end +dc=getmetatable(dc)and rawget(getmetatable(dc),'__index')end;ab[cb]=cc end;local bc={_values={},_events={},loadedCallback=function()end} +bc.get=function(cc) +local dc=bc._values[cc]local _d=cb._properties[cc]if +type(dc)=="function"and _d.type~="function"then dc=dc(bc)end;return dc end +bc.set=function(cc,dc)bc._values[cc]=dc;return bc end +setmetatable(bc,{__index=function(cc,dc) +if dc:match("^on%u")then return +function(_d,ad) +cc._events[dc]=cc._events[dc]or{}table.insert(cc._events[dc],ad)return cc end end +if dc:match("^get%u")then +local _d=dc:sub(4,4):lower()..dc:sub(5)return function()return cc._values[_d]end end;if dc:match("^set%u")then +local _d=dc:sub(4,4):lower()..dc:sub(5) +return function(ad,bd)cc._values[_d]=bd;return cc end end +return ab[cb][dc]end})return bc end +function _b.createFromBlueprint(cb,db,_c)local ac=cb.new({},_c) +for bc,cc in pairs(db._values)do if type(cc)=="table"then +ac._values[bc]=ba(cc)else ac._values[bc]=cc end end;return ac end +function _b:__init()self._values={}self._observers={}self._states={} +self.set=function(bc,cc,...) +local dc=self._values[bc]local _d=self._properties[bc] +if(_d~=nil)then if(_d.setter)then +cc=_d.setter(self,cc,...)end +if _d.canTriggerRender then self:updateRender()end;self._values[bc]=bb(self,bc,cc,_d)if +dc~=cc and self._observers[bc]then +for ad,bd in ipairs(self._observers[bc])do bd(self,cc,dc)end end end end +self.get=function(bc,...)local cc=self._values[bc]local dc=self._properties[bc] +if +(dc==nil)then da.error("Property not found: "..bc)return end;if type(cc)=="function"and dc.type~="function"then +cc=cc(self)end;return +dc.getter and dc.getter(self,cc,...)or cc end +self.setPropertyState=function(bc,cc,dc,...)local _d=self._properties[bc] +if(_d~=nil)then if(_d.setter)then +dc=_d.setter(self,dc,...)end;dc=bb(self,bc,dc,_d)if +not self._states[cc]then self._states[cc]={}end +self._states[cc][bc]=dc;local ad=self._values.currentState +if ad==cc then if _d.canTriggerRender then +self:updateRender()end +if self._observers[bc]then for bd,cd in +ipairs(self._observers[bc])do cd(self,dc,nil)end end end end end +self.getPropertyState=function(bc,cc,...)local dc=self._states and self._states[cc]and +self._states[cc][bc]local _d= +dc~=nil and dc or self._values[bc] +local ad=self._properties[bc]if(ad==nil)then da.error("Property not found: "..bc) +return end;if +type(_d)=="function"and ad.type~="function"then _d=_d(self)end;return +ad.getter and ad.getter(self,_d,...)or _d end +self.getResolved=function(bc,...)local cc=self:getCurrentState()local dc +if +cc and self._states and +self._states[cc]and self._states[cc][bc]~=nil then dc=self._states[cc][bc]else dc=self._values[bc]end;local _d=self._properties[bc]if(_d==nil)then +da.error("Property not found: "..bc)return end;if +type(dc)=="function"and _d.type~="function"then dc=dc(self)end;return +_d.getter and _d.getter(self,dc,...)or dc end;local cb={}local db=getmetatable(self).__index +while db do if +rawget(db,'_properties')then +for bc,cc in pairs(db._properties)do if not cb[bc]then cb[bc]=cc end end end;db=getmetatable(db)and +rawget(getmetatable(db),'__index')end;self._properties=cb;local _c=getmetatable(self)local ac=_c.__index +setmetatable(self,{__index=function(bc,cc) +local dc=self._properties[cc] +if dc then local _d=self._values[cc]if +type(_d)=="function"and dc.type~="function"then _d=_d(self)end;return _d end +if type(ac)=="function"then return ac(bc,cc)else return ac[cc]end end,__newindex=function(bc,cc,dc) +local _d=self._properties[cc] +if _d then if _d.setter then dc=_d.setter(self,dc)end +dc=bb(self,cc,dc,_d)self:_updateProperty(cc,dc)else rawset(bc,cc,dc)end end,__tostring=function(bc)return +string.format("Object: %s (id: %s)",bc._values.type,bc.id)end}) +for bc,cc in pairs(cb)do if self._values[bc]==nil then +if type(cc.default)=="table"then +self._values[bc]=ba(cc.default)else self._values[bc]=cc.default end end end;return self end +function _b:_updateProperty(cb,db)local _c=self._values[cb] +if type(_c)=="function"then _c=_c(self)end;self._values[cb]=db +local ac=type(db)=="function"and db(self)or db +if _c~=ac then +if self._properties[cb].canTriggerRender then self:updateRender()end +if self._observers[cb]then for bc,cc in ipairs(self._observers[cb])do +cc(self,ac,_c)end end end;return self end +function _b:observe(cb,db) +self._observers[cb]=self._observers[cb]or{}table.insert(self._observers[cb],db)return self end +function _b:removeObserver(cb,db) +if self._observers[cb]then +for _c,ac in ipairs(self._observers[cb])do if ac==db then +table.remove(self._observers[cb],_c) +if#self._observers[cb]==0 then self._observers[cb]=nil end;break end end end;return self end;function _b:removeAllObservers(cb) +if cb then self._observers[cb]=nil else self._observers={}end;return self end +function _b:instanceProperty(cb,db) +_b.defineProperty(self,cb,db)self._values[cb]=db.default;return self end +function _b:removeProperty(cb)self._values[cb]=nil;self._properties[cb]=nil;self._observers[cb]= +nil +local db=cb:sub(1,1):upper()..cb:sub(2)self["get"..db]=nil;self["set"..db]=nil;self["get"..db.."State"]= +nil;self["set"..db.."State"]=nil;return self end +function _b:getPropertyConfig(cb)return self._properties[cb]end;return _b end +project["main.lua"] = function(...) local ad=require("elementManager") +local bd=require("errorManager")local cd=require("propertySystem") +local dd=require("libraries/expect")local __a={}__a.traceback=true;__a._events={}__a._schedule={} +__a._eventQueue={}__a._plugins={}__a.isRunning=false;__a.LOGGER=require("log") +if(minified)then +__a.path=fs.getDir(shell.getRunningProgram())else __a.path=fs.getDir(select(2,...))end;local a_a=nil;local b_a=nil;local c_a={}local d_a=type;local _aa={}local aaa=10;local baa=0;local caa=false +local function daa() +if(caa)then return end;baa=os.startTimer(0.2)caa=true end +local function _ba(aca)for _=1,aca do local bca=_aa[1]if(bca)then bca:create()end +table.remove(_aa,1)end end;local function aba(aca,bca) +if(aca=="timer")then if(bca==baa)then _ba(aaa)caa=false;baa=0;if(#_aa>0)then daa()end +return true end end end +function __a.create(aca,bca,cca,dca)if( +d_a(bca)=="string")then bca={name=bca}end +if(bca==nil)then bca={name=aca}end;local _da=ad.getElement(aca) +if(cca)then +local ada=cd.blueprint(_da,bca,__a,dca)table.insert(_aa,ada)daa()return ada else local ada=_da.new() +ada:init(bca,__a)return ada end end +function __a.createFrame()local aca=__a.create("BaseFrame")aca:postInit()if +(a_a==nil)then a_a=tostring(term.current()) +__a.setActiveFrame(aca,true)end;return aca end;function __a.getElementManager()return ad end +function __a.getErrorManager()return bd end +function __a.getMainFrame()local aca=tostring(term.current())if(c_a[aca]==nil)then +a_a=aca;__a.createFrame()end;return c_a[aca]end +function __a.setActiveFrame(aca,bca)local cca=aca:getTerm()if(bca==nil)then bca=true end +if(cca~=nil)then c_a[tostring(cca)]= +bca and aca or nil;aca:updateRender()end end;function __a.getActiveFrame(aca)if(aca==nil)then aca=term.current()end;return +c_a[tostring(aca)]end +function __a.setFocus(aca)if +(b_a==aca)then return end +if(b_a~=nil)then b_a:dispatchEvent("blur")end;b_a=aca +if(b_a~=nil)then b_a:dispatchEvent("focus")end end;function __a.getFocus()return b_a end +function __a.schedule(aca)dd(1,aca,"function") +local bca=coroutine.create(aca)local cca,dca=coroutine.resume(bca) +if(cca)then +table.insert(__a._schedule,{coroutine=bca,filter=dca})else bd.header="Basalt Schedule Error"bd.error(dca)end;return bca end +function __a.removeSchedule(aca) +for bca,cca in ipairs(__a._schedule)do if(cca.coroutine==aca)then +table.remove(__a._schedule,bca)return true end end;return false end +local bba={mouse_click=true,mouse_up=true,mouse_scroll=true,mouse_drag=true}local cba={key=true,key_up=true,char=true} +local function dba(aca,...)if(aca=="terminate")then __a.stop() +return end;if aba(aca,...)then return end;local bca={...} +local function cca() +if(bba[aca])then if +c_a[a_a]then +c_a[a_a]:dispatchEvent(aca,table.unpack(bca))end elseif(cba[aca])then if(b_a~=nil)then +b_a:dispatchEvent(aca,table.unpack(bca))end else for bda,cda in pairs(c_a)do +cda:dispatchEvent(aca,table.unpack(bca))end end end +for bda,cda in pairs(__a._eventQueue)do +if +coroutine.status(cda.coroutine)=="suspended"then +if cda.filter==aca or cda.filter==nil then cda.filter=nil +local dda,__b=coroutine.resume(cda.coroutine,aca,...) +if not dda then bd.header="Basalt Event Error"bd.error(__b)end;cda.filter=__b end end;if coroutine.status(cda.coroutine)=="dead"then +table.remove(__a._eventQueue,bda)end end;local dca={coroutine=coroutine.create(cca),filter=aca} +local _da,ada=coroutine.resume(dca.coroutine,aca,...) +if(not _da)then bd.header="Basalt Event Error"bd.error(ada)end;if(ada~=nil)then dca.filter=ada end +table.insert(__a._eventQueue,dca) +for bda,cda in ipairs(__a._schedule)do +if +coroutine.status(cda.coroutine)=="suspended"then +if aca==cda.filter or cda.filter==nil then cda.filter=nil +local dda,__b=coroutine.resume(cda.coroutine,aca,...) +if(not dda)then bd.header="Basalt Schedule Error"bd.error(__b)end;cda.filter=__b end end;if(coroutine.status(cda.coroutine)=="dead")then +__a.removeSchedule(cda.coroutine)end end;if __a._events[aca]then +for bda,cda in ipairs(__a._events[aca])do cda(...)end end end;local function _ca() +for aca,bca in pairs(c_a)do bca:render()bca:postRender()end end +function __a.update(...)local aca=function(...)__a.isRunning=true +dba(...)_ca()end +local bca,cca=pcall(aca,...) +if not(bca)then bd.header="Basalt Runtime Error"bd.error(cca)end;__a.isRunning=false end;function __a.stop()__a.isRunning=false;term.clear() +term.setCursorPos(1,1)end +function __a.run(aca)if(__a.isRunning)then +bd.error("Basalt is already running")end;if(aca==nil)then __a.isRunning=true else +__a.isRunning=aca end +local function bca()_ca()while __a.isRunning do +dba(os.pullEventRaw())if(__a.isRunning)then _ca()end end end +while __a.isRunning do local cca,dca=pcall(bca)if not(cca)then bd.header="Basalt Runtime Error" +bd.error(dca)end end end;function __a.getElementClass(aca)return ad.getElement(aca)end;function __a.getAPI(aca)return +ad.getAPI(aca)end +function __a.onEvent(aca,bca)dd(1,aca,"string") +dd(2,bca,"function") +if not __a._events[aca]then __a._events[aca]={}end;table.insert(__a._events[aca],bca)end +function __a.removeEvent(aca,bca)dd(1,aca,"string")dd(2,bca,"function")if not +__a._events[aca]then return false end;for cca,dca in ipairs(__a._events[aca])do +if +dca==bca then table.remove(__a._events[aca],cca)return true end end;return false end +function __a.triggerEvent(aca,...)dd(1,aca,"string") +if __a._events[aca]then +for bca,cca in +ipairs(__a._events[aca])do local dca,_da=pcall(cca,...)if not dca then bd.header="Basalt Event Callback Error" +bd.error( +"Error in event callback for '"..aca.."': "..tostring(_da))end end end end +function __a.requireElements(aca,bca)if type(aca)=="string"then aca={aca}end +dd(1,aca,"table")if bca~=nil then dd(2,bca,"boolean")end;local cca={}local dca={}for _da,ada in +ipairs(aca)do +if not ad.hasElement(ada)then table.insert(cca,ada)elseif not +ad.isElementLoaded(ada)then table.insert(dca,ada)end end +if +#dca>0 then +for _da,ada in ipairs(dca)do local bda,cda=pcall(ad.loadElement,ada) +if not bda then +__a.LOGGER.warn( +"Failed to load element "..ada..": "..tostring(cda))table.insert(cca,ada)end end end +if#cca>0 then +if bca then local _da={}for ada,bda in ipairs(cca)do local cda=ad.tryAutoLoad(bda)if not cda then +table.insert(_da,bda)end end +if +#_da>0 then +local ada="Missing required elements: "..table.concat(_da,", ") +ada=ada.."\n\nThese elements could not be auto-loaded." +ada=ada.."\nPlease install them or register remote sources."bd.error(ada)end else +local _da="Missing required elements: "..table.concat(cca,", ")_da=_da.."\n\nSuggestions:" +_da=_da.."\n • Use basalt.requireElements({...}, true) to auto-load" +_da=_da.."\n • Register remote sources with elementManager.registerRemoteSource()" +_da=_da.."\n • Register disk mounts with elementManager.registerDiskMount()"bd.error(_da)end end +__a.LOGGER.info("All required elements are available: "..table.concat(aca,", "))return true end +function __a.loadManifest(aca)dd(1,aca,"string") +if not fs.exists(aca)then bd.error( +"Manifest file not found: "..aca)end;local bca;local cca,dca=pcall(dofile,aca)if not cca then +bd.error("Failed to load manifest: "..tostring(dca))end;bca=dca;if type(bca)~="table"then +bd.error("Manifest must return a table")end +if bca.config then +ad.configure(bca.config)__a.LOGGER.debug("Applied manifest config")end;if bca.diskMounts then +for _da,ada in ipairs(bca.diskMounts)do ad.registerDiskMount(ada)end end;if bca.remoteSources then +for _da,ada in +pairs(bca.remoteSources)do ad.registerRemoteSource(_da,ada)end end;if bca.requiredElements then local _da= +bca.autoLoadMissing~=false +__a.requireElements(bca.requiredElements,_da)end +if bca.optionalElements then for _da,ada in +ipairs(bca.optionalElements)do pcall(ad.loadElement,ada)end end +if bca.preloadElements then ad.preloadElements(bca.preloadElements)end +__a.LOGGER.info("Manifest loaded successfully: ".. (bca.name or aca))return bca end +function __a.install(aca,bca)dd(1,aca,"string") +if bca~=nil then dd(2,bca,"string")end +if ad.hasElement(aca)and ad.isElementLoaded(aca)then return true end +if bca then +if bca:match("^https?://")then ad.registerRemoteSource(aca,bca)else if not +fs.exists(bca)then +bd.error("Source file not found: "..bca)end end end;local cca=ad.tryAutoLoad(aca)if cca then return true else return false end end +function __a.configure(aca)dd(1,aca,"table")ad.configure(aca)end;return __a end +project["layoutManager.lua"] = function(...) local b={}b._cache={} +function b.load(c)if b._cache[c]then return b._cache[c]end +local d,_a=pcall(require,c)if not d then +error("Failed to load layout: "..c.."\n".._a)end;if type(_a)~="table"then +error("Layout must return a table: "..c)end;if type(_a.calculate)~="function"then +error( +"Layout must have a calculate() function: "..c)end;b._cache[c]=_a;return _a end +function b.apply(c,d)local _a=b.load(d)local aa={layout=_a,container=c,options={}} +_a.calculate(aa)b._applyPositions(aa)return aa end +function b._applyPositions(c)if not c._positions then return end +for d,_a in pairs(c._positions)do +if +not d._destroyed then d.set("x",_a.x)d.set("y",_a.y) +d.set("width",_a.width)d.set("height",_a.height) +d._layoutValues={x=_a.x,y=_a.y,width=_a.width,height=_a.height}end end end +function b._wasChangedByUser(c)if not c._layoutValues then return false end +local d=c.get("x")local _a=c.get("y")local aa=c.get("width")local ba=c.get("height") +return d~= +c._layoutValues.x or _a~=c._layoutValues.y or aa~= +c._layoutValues.width or +ba~=c._layoutValues.height end +function b.update(c) +if c and c.layout and c.layout.calculate then +if c._positions then for d,_a in pairs(c._positions)do +if not +d._destroyed then d._userModified=b._wasChangedByUser(d)end end end;c.layout.calculate(c)b._applyPositions(c)end end +function b.destroy(c)if c and c.layout and c.layout.destroy then +c.layout.destroy(c)end;if c then c._positions=nil end end;return b end +project["libraries/colorHex.lua"] = function(...) local b={}for i=0,15 do b[2 ^i]=("%x"):format(i) +b[("%x"):format(i)]=2 ^i end;return b end +project["libraries/utils.lua"] = function(...) local d,_a=math.floor,string.len;local aa={} +function aa.getCenteredPosition(ba,ca,da)local _b=_a(ba)local ab=d( +(ca-_b+1)/2 +0.5)local bb=d(da/2 +0.5)return ab,bb end +function aa.deepCopy(ba)if type(ba)~="table"then return ba end;local ca={}for da,_b in pairs(ba)do +ca[aa.deepCopy(da)]=aa.deepCopy(_b)end;return ca end +function aa.copy(ba)local ca={}for da,_b in pairs(ba)do ca[da]=_b end;return ca end;function aa.reverse(ba)local ca={}for i=#ba,1,-1 do table.insert(ca,ba[i])end +return ca end +function aa.uuid() +return +string.format('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',math.random(0,0xffff),math.random(0,0xffff),math.random(0,0xffff), +math.random(0,0x0fff)+0x4000,math.random(0,0x3fff)+0x8000,math.random(0,0xffff),math.random(0,0xffff),math.random(0,0xffff))end +function aa.split(ba,ca)local da={}for _b in(ba..ca):gmatch("(.-)"..ca)do +table.insert(da,_b)end;return da end;function aa.removeTags(ba)return ba:gsub("{[^}]+}","")end +function aa.wrapText(ba,ca)if +ba==nil then return{}end;ba=aa.removeTags(ba)local da={} +local _b=aa.split(ba,"\n\n") +for ab,bb in ipairs(_b)do +if#bb==0 then table.insert(da,"")if ab<#_b then +table.insert(da,"")end else local cb=aa.split(bb,"\n") +for db,_c in ipairs(cb)do +local ac=aa.split(_c," ")local bc="" +for cc,dc in ipairs(ac)do if#bc==0 then bc=dc elseif#bc+#dc+1 <=ca then bc=bc.." "..dc else +table.insert(da,bc)bc=dc end end;if#bc>0 then table.insert(da,bc)end end;if ab<#_b then table.insert(da,"")end end end;return da end;return aa end +project["libraries/collectionentry.lua"] = function(...) local b={} +b.__index=function(c,d)local _a=rawget(b,d)if _a then return _a end;if c._data[d]~=nil then return +c._data[d]end;local aa=c._parent[d]if aa then return aa end +return nil end +function b.new(c,d)local _a={_parent=c,_data=d}return setmetatable(_a,b)end +function b:_findIndex()for c,d in ipairs(self._parent:getItems())do +if d==self then return c end end;return nil end;function b:setText(c)self._data.text=c +self._parent:updateRender()return self end;function b:getText() +return self._data.text end +function b:moveUp(c)local d=self._parent:getItems() +local _a=self:_findIndex()if not _a then return self end;c=c or 1;local aa=math.max(1,_a-c)if _a~=aa then +table.remove(d,_a)table.insert(d,aa,self) +self._parent:updateRender()end;return self end +function b:moveDown(c)local d=self._parent:getItems() +local _a=self:_findIndex()if not _a then return self end;c=c or 1;local aa=math.min(#d,_a+c)if _a~=aa then +table.remove(d,_a)table.insert(d,aa,self) +self._parent:updateRender()end;return self end +function b:moveToTop()local c=self._parent:getItems() +local d=self:_findIndex()if not d or d==1 then return self end;table.remove(c,d) +table.insert(c,1,self)self._parent:updateRender()return self end +function b:moveToBottom()local c=self._parent:getItems() +local d=self:_findIndex()if not d or d==#c then return self end;table.remove(c,d) +table.insert(c,self)self._parent:updateRender()return self end;function b:getIndex()return self:_findIndex()end +function b:swapWith(c) +local d=self._parent:getItems()local _a=self:getIndex()local aa=c:getIndex() +if _a and aa and _a~=aa then +d[_a],d[aa]=d[aa],d[_a]self._parent:updateRender()end;return self end +function b:remove()if self._parent and self._parent.removeItem then +self._parent:removeItem(self)return true end;return false end +function b:select()if self._parent and self._parent.selectItem then +self._parent:selectItem(self)end;return self end +function b:unselect()if self._parent and self._parent.unselectItem then +self._parent:unselectItem(self)end end +function b:isSelected() +if self._parent and self._parent.getSelectedItem then return +self._parent:getSelectedItem()==self end;return false end;return b end +project["libraries/expect.lua"] = function(...) local c=require("errorManager") +local function d(_a,aa,ba)local ca=type(aa) +if ba=="element"then if ca=="table"and +aa.get("type")~=nil then return true end end +if ba=="color"then if ca=="number"then return true end;if +ca=="string"and colors[aa]then return true end end;if ca~=ba then c.header="Basalt Type Error" +c.error(string.format("Bad argument #%d: expected %s, got %s",_a,ba,ca))end;return true end;return d end +return project["main.lua"]() \ No newline at end of file