Guides for docs

This commit is contained in:
Robert Jelic
2025-02-23 13:24:59 +01:00
parent 781690e462
commit 1f10b7eadf
13 changed files with 309 additions and 1254 deletions

6
.gitignore vendored
View File

@@ -1 +1,5 @@
docs/getBasalt.lua
tests
ascii.lua
test.lua
test.xml
test2.lua

View File

@@ -1,97 +0,0 @@
local args = {...} -- example: bundle basalt main basalt.lua
local availableFiles = {}
local minifyURL = "https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/minify.lua"
local content = [[local bundled = true
local bundled_basaltContent = {}
local bundled_basaltLoaded = {}
local bundled_availableFiles = {}
local baseRequire = require
require = function(name)
if(bundled_basaltContent["basalt/"..name])then
if(bundled_basaltLoaded["basalt/"..name]==nil)then
bundled_basaltLoaded["basalt/"..name] = bundled_basaltContent["basalt/"..name]()
end
return bundled_basaltLoaded["basalt/"..name]
end
if(bundled_basaltContent["basalt/elements/"..name])then
if(bundled_basaltLoaded["basalt/elements/"..name]==nil)then
bundled_basaltLoaded["basalt/elements/"..name] = bundled_basaltContent["basalt/elements/"..name]()
end
return bundled_basaltLoaded["basalt/elements/"..name]
end
if(bundled_basaltContent["basalt/extensions/"..name])then
if(bundled_basaltLoaded["basalt/extensions/"..name]==nil)then
bundled_basaltLoaded["basalt/extensions/"..name] = bundled_basaltContent["basalt/extensions/"..name]()
end
return bundled_basaltLoaded["basalt/extensions/"..name]
end
if(bundled_basaltContent["basalt/libraries/"..name])then
if(bundled_basaltLoaded["basalt/libraries/"..name]==nil)then
bundled_basaltLoaded["basalt/libraries/"..name] = bundled_basaltContent["basalt/libraries/"..name]()
end
return bundled_basaltLoaded["basalt/libraries/"..name]
end
return baseRequire(name)
end
]]
local function bundleProject(mainFolder, mainFile, fileName, minify)
local function generateSingleFile(folder)
local newFolder = {}
for k,file in pairs(fs.list(folder)) do
if fs.isDir(fs.combine(folder, file)) then
generateSingleFile(fs.combine(folder, file))
else
local fileContent = fs.open(fs.combine(folder, file), "r")
local fileData = fileContent.readAll()
fileContent.close()
table.insert(newFolder, file)
local fName = file:gsub(".lua", "")
content = content .. "\nbundled_basaltContent[\"" .. fs.combine(folder, fName) .. "\"] = function(...)\n"..fileData.."\nend"
end
end
availableFiles[folder] = newFolder
end
generateSingleFile(mainFolder)
for k,v in pairs(availableFiles) do
content = content .. "\nbundled_availableFiles[\"" .. k .. "\"] = {"
for _,file in pairs(v) do
content = content .. "\"" .. file .. "\","
end
content = content .. "}"
end
content = content .. "\nreturn bundled_basaltContent['basalt/"..mainFile.."']()"
if(minify)then
local minScript = http.get(minifyURL)
print("Downloading minify script...")
if(minScript)then
local min = load(minScript.readAll(), nil, "t", _ENV)()
minScript.close()
local success, data = min(content)
if(success)then
content = data
else
error(data)
end
else
print("Failed to download minify script")
end
end
local file = fs.open(fileName, "w")
file.write(content:gsub("\t", " "):gsub("\n", " "))
file.close()
end
if(#args>=1)then
--bundleProject(args[1], args[2] or "main", args[3] or "basalt.lua", args[4] or false)
end
return bundleProject

View File

@@ -1,90 +0,0 @@
{
"versions": {
"elements": {
"BaseFrame": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/BaseFrame.lua", "The base frame is a element which contains all other elements. The difference to other containers is, it has no parent container."],
"BasicElement": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/BasicElement.lua", "The basic element is required for all elements to work. All elements inherit from this element."],
"Button": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Button.lua", "The button element, with a text in the center."],
"Checkbox": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Checkbox.lua", "The checkbox element is a element which can be checked or unchecked."],
"Container": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Container.lua", "The container element, this is the parent of all containers (frames, flexboxes, etc.)"],
"Dropdown": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Dropdown.lua", "The dropdown element can be opened and closed. It contains clickable items."],
"Frame": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Frame.lua", "The frame element can contain other elements."],
"Image": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Image.lua", "The image element display images."],
"Input": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Input.lua", "The input element is a element which can be typed in."],
"Label": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Label.lua", "The label element, this is a element which can display text."],
"List": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/List.lua", "The list element can contain clickable items. List's also can be connected to other lists."],
"BigMonitor": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/BigMonitor.lua", "The big monitor element is a element which can contain other elements. Big Monitors are used for big screens (multiple monitors)."],
"Menubar": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Menubar.lua", "The menubar element can contain clickable items, menubars scroll horizontally."],
"Monitor": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Monitor.lua", "The monitor element is a element which can contain other elements. It is used to manage one monitor."],
"MovableFrame": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/MovableFrame.lua", "The movable frame element allows you to move the frame with it's children around."],
"ScrollableFrame": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/ScrollableFrame.lua", "The scrollable frame element allows you to scroll through the content."],
"Progressbar": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Progressbar.lua", "The progressbar element, this is a element which can display progress."],
"Program": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Program.lua", "The program element can start any program."],
"Slider": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Slider.lua", "The slider element, this is a element which can be slided."],
"Textfield": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/Textfield.lua", "The textfield element can contain text, and the user can type in it."],
"VisualElement": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/elements/VisualElement.lua", "The visual element, this is the parent of all visual elements, required for visual elements to work."]
},
"extensions": {
"debug": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/debug.lua", "The debug extension is used for simple debugging."],
"dynamicValues": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/dynamicValues.lua", "The dynamic values extension can create more advanced properties. You put in a string (e.g. parent.width - self.width) and it will create a function based on that string."],
"templates": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/templates.lua", "The templates extension is used to create more advanced templates. You can also load templates from a JSON file. There are some examples on Github."],
"xml": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/xml.lua", "The xml extension is used to create elements from XML."],
"betterBackgrounds": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/betterBackgrounds.lua", "The better backgrounds extension is used to create some more advanced backgrounds."],
"borders": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/borders.lua", "The borders extension is used to create borders around the elements."],
"animations": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/animations.lua", "The animations extension is used to create animations. Instead of just reposioning elements, you can animate the position (just an example)."],
"shadows": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/extensions/shadows.lua", "The shadow extension is used to create shadows for the elements."]
},
"libraries": {
"log": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/libraries/log.lua"],
"expect": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/libraries/expect.lua"],
"utils": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/libraries/utils.lua"]
},
"init": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/init.lua"],
"main": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/main.lua"],
"renderSystem": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/renderSystem.lua"],
"basaltLoader": [1, "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/Basalt/basaltLoader.lua"]
},
"default": {
"elements": ["BaseFrame", "BasicElement", "Button", "Checkbox", "Container", "Frame", "Input", "Label", "VisualElement"],
"extensions": ["dynamicValues", "templates", "xml"],
"libraries": ["log", "expect", "utils"],
"core": ["init", "main", "renderSystem", "basaltLoader"]
},
"defaultSettings": {
"path": {
"description": "Basalt's default path",
"type": "string",
"default": "basalt"
},
"cacheGlobally": {
"description": "Cache the Basalt API globally",
"type": "boolean",
"default": false
},
"downloadFiles": {
"description": "Downloads the required files from Github",
"type": "boolean",
"default": true
},
"storeDownloadedFiles": {
"description": "Stores the downloaded files",
"type": "boolean",
"default": false
},
"autoUpdate": {
"description": "Automatically checks and downloads new updates on program start",
"type": "boolean",
"default": true
},
"versions": {
"description": "The versions of the files",
"type": "table",
"default": {}
},
"githubRepository": {
"description": "The Github repository to download the files from",
"type": "string",
"default": "https://raw.githubusercontent.com/pyroxenium/Basalt/basalt2/"
}
}
}

View File

@@ -65,6 +65,8 @@ export default defineConfig({
{ text: 'Download', link: '/guides/download' },
{ text: 'Annotations', link: '/guides/annotations' },
{ text: 'Animations', link: '/guides/animations' },
{ text: 'States', link: '/guides/states' },
{ text: 'FAQ', link: '/guides/faq' },
],
'/references/':[

View File

@@ -9,72 +9,91 @@ Animations in Basalt work with:
- **Chains**: Multiple sequences that can be controlled together
- **Timing**: Control over duration and easing of animations
## Available Animations
`element:animate()` creates a new Animation object. Each animation method accepts a duration parameter (in seconds).
### Movement
### Core Animation Methods
```lua
element:animate()
:move(x, y, duration) -- Moves to new position
:offset(x, y, duration) -- Animate offset
:size(w, h, duration) -- Animate size
:position(x, y, duration) -- Animate position
:textColor(color, duration) -- Animate text color
:background(color, duration) -- Animate background color
```
### Visual Effects
```lua
element:animate()
:size(width, height, duration)
```
### Text Animations
```lua
element:animate()
:typewrite(property, text, duration) -- Typing effect
:text(text, duration) -- Instant text change
```
## Animation Control
Control your animations using these methods:
### Animation Control
```lua
local anim = element:animate()
:move(10, 5, 1)
:start()
:offset(5, 0, 1)
:start() -- Start the animation
anim:pause() -- Pause animation
anim:resume() -- Resume animation
anim:stop() -- Stop animation
anim:cancel() -- Cancel animation
anim:pause() -- Pause animation
anim:resume() -- Resume animation
anim:stop() -- Stop animation
```
## Sequences
## Understanding Sequences
Chain multiple animations together:
Sequences allow you to create complex animations by controlling when each animation plays. By default, all animations in a chain play simultaneously. Using `:sequence()` creates a new group that waits for the previous animations to complete.
### Basic Example
```lua
-- Without sequences (animations play at the same time):
element:animate()
:move(10, 5, 1) -- First sequence
:sequence() -- Start new sequence
:move(20, 5, 1) -- Plays after first sequence
:position(10, 5, 1) -- These three animations
:size(5, 5, 1) -- all start and play
:background(colors.red, 1) -- simultaneously
:start()
-- With sequences (animations play one after another):
element:animate()
:position(10, 5, 1) -- Plays first
:sequence()
:background(colors.red, 0.5)
:size(5, 5, 1) -- Starts after position completes
:sequence()
:background(colors.red, 1) -- Starts after size completes
:start()
```
## Event Handling
### Advanced Usage
```lua
-- Complex movement pattern
element:animate()
:position(10, 5, 0.5) -- Move right
:sequence()
:position(10, 10, 0.5) -- Then down
:sequence()
:position(5, 10, 0.5) -- Then left
:sequence()
:position(5, 5, 0.5) -- Then up
:onDone(function()
-- Called when entire sequence completes
end)
:start()
Animations support various events:
-- Mixing simultaneous and sequential animations
element:animate()
-- These two happen together
:position(10, 5, 1)
:background(colors.blue, 1)
:sequence()
-- These two also happen together, but after the first group
:position(5, 5, 1)
:background(colors.red, 1)
:start()
```
### Callbacks
```lua
element:animate()
:move(10, 5, 1)
:onStart(function()
-- Called when animation starts
end)
:onDone(function()
-- Called when animation completes
end)
:offset(5, 0, 1)
:onStart(function() end) -- When animation starts
:onDone(function() end) -- When animation completes
:onStep(function() end) -- Every animation step
:start()
```
## Tips & Best Practices
- Use sequences for complex animations
- Keep animations short and responsive
- Consider using events for coordinating multiple animations
- Test animations on different computer tiers
- Keep duration times reasonable (0.1-2 seconds)
- Consider using callbacks for state management

View File

@@ -1,6 +1,6 @@
# Download
Basalt is available in two versions: the dev version, ideal for develpoement and the release version which is meant for production
Basalt is available in two versions: the dev version, ideal for develpoement and the release version which is meant for production. Basalt is also available on [PineStore](https://pinestore.cc/projects/15/basalt)
## Downloading Basalt
@@ -28,18 +28,4 @@ This is the default bundle version of Basalt, containing essential files for a U
```
wget run https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/install.lua release
```
## Update Basalt
The following command will update the project for you
To execute the update command, use the following:
```
wget run https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/install.lua update
```
::: info
This [config](https://github.com/Pyroxenium/Basalt2/config.json) file is used to check if a update needs to be done.
:::
```

83
docs/guides/faq.md Normal file
View File

@@ -0,0 +1,83 @@
# Frequently Asked Questions
## General
### What is Basalt?
Basalt is a UI framework for CC:Tweaked that helps you create user interfaces easily and efficiently. It provides pre-built components, event handling, and advanced features like animations and themes.
### Why should I use Basalt instead of direct terminal manipulation?
Basalt handles many complex aspects automatically:
- Event management
- Screen rendering
- Component positioning
- State management
- Layout organization
## Installation
### How do I install Basalt?
```lua
wget run https://raw.githubusercontent.com/Pyroxenium/Basalt2/main/install.lua
```
### Can I customize my installation?
Yes! The installer allows you to:
- Choose between Release/Dev versions
- Select specific components
- Include LuaLS definitions
- Enable minification
## Common Issues
### Why isn't my UI updating?
Remember to call `basalt.run()` at the end of your program. Without it, your UI won't start.
### Why are my elements not visible?
Check:
1. Element positions are within parent bounds
2. Parent container is large enough
3. Element's `visible` property is true
4. Z-index conflicts with other elements
### How do I handle screen resizes?
Use dynamic positioning with strings, or use functions:
```lua
element:setPosition("{parent.width - 5}", 5) -- 5 from right edge
element:setSize("{parent.width - 10}", 5) -- 5 padding on each side
element:setPosition(function(self) -- Another example, but as function call
return self:getParent() - 5
end, 5)
```
## Development
### How do I add custom plugins?
Create a new plugin in the plugins directory. See [pluginExample](https://github.com/Pyroxenium/Basalt2/blob/main/examples/pluginExample.lua) for a example on how to create plugins
### Where can I find more examples?
- Check the examples directory in the repository
- Visit our [GitHub](https://github.com/Pyroxenium/Basalt2)
- Join our [Discord](https://discord.gg/yNNnmBVBpE)
### How do I contribute?
1. Fork the repository
2. Create a feature branch
3. Submit a pull request
4. Join our Discord for discussion
## Performance
### How can I optimize my Basalt application?
Basalt does already a lot of optimization:
- The render loop only runs when something visually changed (color, position, size,..) which means it only runs once, even if Basalt gets spammed with events (timer events or mouse events).
- The event system is highly optimized:
- Events are only registered for elements that actually use them
- Events bubble up through the element hierarchy efficiently
- Event handlers are stored in a flat structure for quick access
- Events are automatically cleaned up when elements are removed
- Parent containers only receive events their children actually use
Additional tips for optimization:
- Group elements in Frames to reduce render calls
- Use `setVisible(false)` instead of removing elements you'll need again
- In case you need a LOT of elements you can use addDelayed{Element}, for example addDelayedButton instead of addButton

93
docs/guides/states.md Normal file
View File

@@ -0,0 +1,93 @@
# State Management in Basalt
States provide a powerful way to manage data and UI synchronization in your Basalt applications.
## Core Concepts
- **States**: Named values stored in frames
- **Computed States**: States that depend on other states
- **State Changes**: Automatic UI updates when states change
- **State Listeners**: React to state changes
## Basic State Methods
```lua
-- Initialize states
frame:initializeState("name", defaultValue, triggerRender)
frame:setState("name", newValue)
frame:getState("name")
-- Computed states
frame:computed("name", function(self)
-- Calculate and return value based on other states
end)
-- Listen to changes
frame:onStateChange("name", function(self, newValue)
-- React to state changes
end)
```
## Complete Form Example
Here's a comprehensive example showing state management in a form:
```lua
local main = basalt.getMainFrame()
local form = main:addFrame()
:setSize("{parent.width - 4}", "{parent.height - 4}")
-- Initialize multiple states
:initializeState("username", "")
:initializeState("email", "")
:initializeState("age", 0)
:initializeState("submitted", false)
-- Add computed validation state
:computed("isValid", function(self)
local username = self:getState("username")
local email = self:getState("email")
local age = self:getState("age")
return #username > 0 and email:match(".+@.+") and age > 0
end)
-- Input with state binding
form:addInput()
:onChange(function(self, value)
form:setState("username", value)
end)
-- Button reacting to computed state
form:addButton()
:onStateChange("isValid", function(self, isValid)
self:setBackground(isValid and colors.lime or colors.gray)
end)
```
## Best Practices
1. **State Initialization**
- Initialize all states at component creation
- Use meaningful default values
- Consider whether state changes should trigger renders
2. **Computed States**
- Use for values that depend on multiple states
- Keep computations simple and efficient
- Avoid circular dependencies
3. **State Updates**
- Update states through setState, not directly
- Use onStateChange for side effects
- Consider batching multiple state updates
4. **Form Validation**
- Use computed states for form validation
- Update UI elements based on validation state
- Trigger actions only when validation passes
## Tips
- Use states for data that affects multiple components
- Consider using tables for complex state
- Keep state updates minimal and efficient
- Use meaningful state names
- Document state dependencies

View File

@@ -1,25 +1,53 @@
# Welcome to The Basalt Wiki
Basalt is a user-friendly UI framework for CC:Tweaked (also known as "ComputerCraft: Tweaked") - a popular Minecraft mod. It was developed to enhance user interaction through visual displays. In this wiki, you'll find information on how to use Basalt as well as examples of functional Basalt code.
Basalt is a user-friendly UI framework for CC:Tweaked (also known as "ComputerCraft: Tweaked") - a popular Minecraft mod. It was developed to enhance user interaction through visual displays.
## About Basalt
## Installation
Basalt is an easy-to-understand UI framework designed to improve user interaction with CC:Tweaked. Some of its key features include:
```lua
wget run https://raw.githubusercontent.com/Pyroxenium/Basalt2/main/install.lua
```
## Features
- A set of pre-built UI components for creating interfaces quickly and easily.
- A flexible layout system that allows users to create custom designs.
- A powerful event handling system for managing user input and interaction.
- Support for multiple screen resolutions and aspect ratios.
- Extensive documentation and examples to help users get started quickly.
- **Pre-built Components:** Buttons, Lists, Textboxes, and more
- **Modern UI:** Animations, themes, and dynamic layouts
- **Event System:** Powerful event handling
- **Plugin System:** Extend Basalt with custom plugins
- **Developer Friendly:**
- Type definitions for better IDE support
- Extensive documentation
- Active community
- Minification support
If you want to learn more about basalt, check out our Guides page. To learn more about Basalt's API you can also check out the [References](/references/main) page.
## Quick Start
## Quick Demo
```lua
local basalt = require("basalt")
-- Create a simple UI
basalt.getMainFrame()
:addButton()
:setText("Hello Basalt!")
:setPosition(5, 5)
:onMouseClick(function()
-- Your code here
end)
basalt.run()
```
## Preview
![Basalt Demo GIF](https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/basaltPreview2.gif)
## Questions & Bugs
## Documentation
Bugs can be reported here: [Github](https://github.com/Pyroxenium/Basalt2/issues) or in our [discord](https://discord.gg/yNNnmBVBpE).
- [Getting Started Guide](/guides/getting-started)
- [API Reference](/references/main)
If you have questions about Basalt or how to make use of it, feel free to create a new discussion on [Basalt's Discussion Board (Github)](https://github.com/Pyroxenium/Basalt2/discussions), or ask in our [discord](https://discord.gg/yNNnmBVBpE).
## Community & Support
- Report bugs on [GitHub](https://github.com/Pyroxenium/Basalt2/issues)
- Join our [Discord](https://discord.gg/yNNnmBVBpE)
- Ask questions on [GitHub Discussions](https://github.com/Pyroxenium/Basalt2/discussions)
- Check out the [FAQ](/guides/faq)

View File

@@ -1,90 +0,0 @@
local config
local basalt = {}
local data = {}
local loaded = {}
local baseRequire = require
_ENV.require = function(path)
if(data[path]~=nil)then
if(loaded[path]==nil)then
loaded[path] = load(data[path], nil, "t", _ENV)()
end
return loaded[path]
end
if(data["libraries/"..path]~=nil)then
if(loaded["libraries/"..path]==nil)then
loaded["libraries/"..path] = load(data["libraries/"..path], nil, "t", _ENV)()
end
return loaded["libraries/"..path]
end
if(data["elements/"..path]~=nil)then
if(loaded["elements/"..path]==nil)then
loaded["elements/"..path] = load(data["elements/"..path], nil, "t", _ENV)()
end
return loaded["elements/"..path]
end
if(data["extensions/"..path]~=nil)then
if(loaded["extensions/"..path]==nil)then
loaded["extensions/"..path] = load(data["extensions/"..path], nil, "t", _ENV)()
end
return loaded["extensions/"..path]
end
return baseRequire(path)
end
local function getConfig()
if(config==nil)then
local github = "https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/config.json"
if(github~=nil)then
local response = http.get(github)
if(response==nil)then
error("Couldn't get the config file from github!")
end
config = textutils.unserializeJSON(response.readAll())
response.close()
return config
else
error("Couldn't find the github path in the settings basalt.github!")
end
end
return config
end
local files = getConfig().versions
local webAccess = {}
for k,v in pairs(files)do
if(k~="elements")and(k~="libraries")and(k~="extensions")then
webAccess[k] = v[2]
end
if(k=="libraries")then
for k,v in pairs(v)do
webAccess["libraries/"..k] = v[2]
end
end
if(k=="elements")then
for k,v in pairs(v)do
if(k=="BasicElement")or(k=="VisualElement")or(k=="Container")or(k=="BaseFrame")then
webAccess["elements/"..k] = v[2]
end
end
end
end
print("Loading the core files from github...")
local parallelAccess = {}
for k,v in pairs(webAccess)do
table.insert(parallelAccess, function()
local url = v
local response = http.get(url)
if(response==nil)then
error("Couldn't get the file "..k.." from github!")
end
local webData = response.readAll()
print("Loaded "..k.."!")
data[k] = webData
end)
end
parallel.waitForAll(unpack(parallelAccess))
basalt = load(data["main"], nil, "t", _ENV)()
return basalt

View File

@@ -1,477 +0,0 @@
-- BASALT INSTALLER
local githubPath = "https://raw.githubusercontent.com/Pyroxenium/Basalt/basalt2/"
local minifyURL = "https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/minify.lua"
local bundleURL = "https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/bundle.lua"
local installer = {}
local args = {...}
local config
local loggingList
local noLogging = false
local packager
function installer.getConfig(key)
if(config~=nil)then
return config[key]
end
local file = http.get("https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/config.json")
if(file == nil) then
error("Failed to download the Basalt config file")
end
config = textutils.unserializeJSON(file.readAll())
return config[key]
end
function installer.getPackager()
if(packager~=nil)then
return packager
end
packager = load(http.get(packagerURL).readAll())()
return packager
end
local function log(msg)
--require("basalt").log(msg)
if not(noLogging)then
if(loggingList~=nil)then
loggingList:addItem(msg)
else
print(msg)
end
end
end
local function downloadFile(path, url, desc)
local file = http.get(url)
if(file == nil) then
log("Failed to download: "..(desc or url))
else
local f = fs.open(path, "w")
f.write(file.readAll())
f.close()
log("Successfully downloaded: "..(desc or url))
end
end
local minScript
local function minify(folder)
if(minScript==nil)then
minScript = load(http.get(minifyURL).readAll())()
end
local files = fs.list(folder)
for _,file in pairs(files)do
if(not fs.isDir(fs.combine(folder, file)))then
if(file:sub(-4)==".lua")then
local f = fs.open(fs.combine(folder, file), "r")
local data = f.readAll()
f.close()
local success, minified = minScript(data)
if(success)then
f = fs.open(fs.combine(folder, file), "w")
f.write(minified:gsub("\t", " "):gsub("\n", " "))
f.close()
log("Successfully minified: "..file)
else
log("Failed to minify: "..file)
end
end
else
minify(fs.combine(folder, file))
end
end
end
function installer.minifyProject(path)
log("Minifying project...")
minify(path)
log("Minifying complete!")
end
function installer.bundleProject(path)
log("Bundling project...")
local bundle = load(http.get(bundleURL).readAll())()
bundle(path, "main", "basalt.lua", false)
log("Bundling complete!")
end
function installer.createDirectories()
local path = installer.getConfig("defaultSettings").path.default
log("Basalt path will be: "..path)
log("Creating Basalt directories")
fs.delete(path)
fs.makeDir(path)
fs.makeDir(fs.combine(path, "extensions"))
fs.makeDir(fs.combine(path, "elements"))
fs.makeDir(fs.combine(path, "libraries"))
end
function installer.createSettings()
log("Storing Basalt settings")
for k,v in pairs(installer.getConfig("defaultSettings"))do
settings.define(k, v)
end
end
function installer.downloadCoreFiles(packaged)
local path = installer.getConfig("defaultSettings").path.default
log("---Core files:---")
for k,_ in pairs(installer.getConfig("versions"))do
if(k~="elements" and k~="extensions" and k~="libraries")then
if(packaged)then
downloadFileMinified(fs.combine(path, k..".lua"), githubPath.."Basalt/"..k..".lua", k)
else
downloadFile(fs.combine(path, k..".lua"), githubPath.."Basalt/"..k..".lua", k)
end
end
end
end
function installer.downloadElementFiles(packaged, elements)
local path = installer.getConfig("defaultSettings").path.default
log("---Element files:---")
for _,v in pairs(elements)do
if(packaged)then
downloadFileMinified(fs.combine(path, "elements", v..".lua"), githubPath.."Basalt/elements/"..v..".lua", v)
else
downloadFile(fs.combine(path, "elements", v..".lua"), githubPath.."Basalt/elements/"..v..".lua", v)
end
end
end
function installer.downloadExtensionFiles(packaged, extensions)
local path = installer.getConfig("defaultSettings").path.default
log("---Extension files:---")
for _,v in pairs(extensions)do
if(packaged)then
downloadFileMinified(fs.combine(path, "extensions", v..".lua"), githubPath.."Basalt/extensions/"..v..".lua", v)
else
downloadFile(fs.combine(path, "extensions", v..".lua"), githubPath.."Basalt/extensions/"..v..".lua", v)
end
end
end
function installer.downloadLibraryFiles(packaged)
local path = installer.getConfig("defaultSettings").path.default
log("---Library files:---")
local libraries = installer.getConfig("versions").libraries
for k,v in pairs(libraries)do
if(packaged)then
downloadFileMinified(fs.combine(path, "libraries", k..".lua"), githubPath.."Basalt/libraries/"..k..".lua", k)
else
downloadFile(fs.combine(path, "libraries", k..".lua"), githubPath.."Basalt/libraries/"..k..".lua", k)
end
end
end
function installer.install(elements, extensions)
log("Downloading Basalt...")
installer.createDirectories()
installer.createSettings()
installer.downloadCoreFiles()
installer.downloadElementFiles(false, elements)
installer.downloadExtensionFiles(false, extensions)
installer.downloadLibraryFiles()
log("Download complete!")
end
local function Button(frame, x, y, w, h, bg, fg, text, onClick, clickedBg, clickedFg)
local button = frame:addButton():setPosition(x, y):setSize(w, h):setText(text):setBackground("{self.clicked ? "..(clickedBg or "black").." : "..(bg or "black").."}"):setForeground("{self.clicked ? "..(clickedFg or "white").." : "..(fg or "white").."}"):onClickUp(onClick)
return button
end
local function Label(frame, x, y, text, bg, fg)
local label = frame:addLabel():setPosition(x, y):setText(text):setBackground(bg or frame:getBackground()):setForeground(fg or frame:getForeground())
return label
end
local function List(frame, x, y, w, h, bg, fg, items, onChange, selBg, selFg)
local list = frame:addList():setPosition(x, y):setSize(w, h):setBackground(bg):setForeground(fg):setItems(items):onChange(onChange):setSelectionBackground(selBg or fg):setSelectionForeground(selFg or bg)
return list
end
local function ScrollFrame(frame, x, y, w, h, bg, fg)
local frame = frame:addScrollableFrame():setPosition(x, y):setSize(w, h):setBackground(bg):setForeground(fg)
return frame
end
local function Input(frame, x, y, w, h, bg, fg, text, defaultText)
local input = frame:addInput():setPosition(x, y):setSize(w, h):setValue(text):setBackground(bg):setForeground(fg):setPlaceholderBackground(bg)
if(defaultText~=nil)then
input:setPlaceholderText(defaultText)
end
return input
end
local function Checkbox(frame, x, y, bg, fg, checked)
local checkbox = frame:addCheckbox():setPosition(x, y):setChecked(checked):setBackground(bg):setForeground(fg)
return checkbox
end
local function checkForDefault(file, typ)
for k,v in pairs(installer.getConfig("default")[typ])do
if(file==v)then
return true
end
end
return false
end
local hintFrames = {}
local hintLabels = {}
local function drawHint(frame, text)
if(hintFrames[frame]==nil)then
hintFrames[frame] = frame:addScrollableFrame():setPosition(5, 6):setSize("{parent.w - 8}", "{parent.h - 12}"):setVisible(false):setBackground(colors.white):setForeground(colors.black):setBorder(true):setBorderColor(colors.black)
hintFrames[frame]:onClick(function(self)
self:setVisible(false)
end)
hintLabels[frame] = hintFrames[frame]:addLabel():setPosition(1, 1):setSize("{parent.w}", "{parent.h}"):setWrap(true):setBackground(colors.white):setForeground(colors.black)
end
hintFrames[frame]:setYOffset(0)
hintLabels[frame]:setText(text)
hintFrames[frame]:setVisible(true)
end
function installer.gui()
local basalt
if(fs.exists("basalt.lua"))then
basalt = require("Basalt")
else
basalt = load(http.get("https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/getBasalt.lua").readAll(), nil, "t", _ENV)()
end
basalt.requiredElement("button", "list", "frame", "input", "label", "scrollableFrame", "checkbox")
basalt.requiredExtension("dynamicValues", "templates", "animations", "borders")
local main = basalt.getMainFrame():setBackground(colors.black):setForeground(colors.white)
local installDescFrame = basalt.addFrame():setBackground(colors.black):setForeground(colors.white)
local settingsFrame = basalt.addFrame():setBackground(colors.black):setForeground(colors.white)
local installFrame1 = basalt.addFrame():setBackground(colors.black):setForeground(colors.white)
local installFrame2 = basalt.addFrame():setBackground(colors.black):setForeground(colors.white)
local loggingFrame = basalt.addFrame():setBackground(colors.black):setForeground(colors.white)
local doneBtn, backBtn
local elements = installer.getConfig("versions").elements
local extensions = installer.getConfig("versions").extensions
-- Install Description Frame ---------------------------------------
local textFrame = ScrollFrame(installDescFrame, 3, 3, "{parent.w - 4}", "{parent.h - 6}", colors.white, colors.white):setBorder(true):setBorderColor(colors.gray)
textFrame:addLabel():setWrap(true):setSize("{parent.w}", "{parent.h}"):setBackground(colors.white):setForeground(colors.black)
:setText([[
Installation
We will install the latest version of basalt on your computer. Please make sure that in case you have a modified version of basalt, you back it up before installing the new version.
You can choose the files you want to install. Don't worry you can add files later on as well.
Press "Next" to continue.
]])
Button(installDescFrame, 2, "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Back", function()
basalt.switchFrame(main)
end)
Button(installDescFrame, "{parent.w - self.w}", "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Next", function()
basalt.switchFrame(settingsFrame)
end)
-- Settings Frame ---------------------------------------------------
local settings = ScrollFrame(settingsFrame, 3, 3, "{parent.w - 4}", "{parent.h - 6}", colors.white, colors.black):setBorder(true):setBorderColor(colors.gray)
Label(settings, 2, 2, "Settings: (click for information)"):onClick(function(self, button)
drawHint(settingsFrame, "These are the settings for Basalt. These settings will be stored with CC:Tweaked's settings API. You can change these settings later on as well.")
end)
Label(settings, 2, 4, "Path:"):onClick(function(self, button)
drawHint(settingsFrame, "The path where Basalt will be installed. Default is 'basalt'.")
end)
Label(settings, 2, 6, "Cache:"):onClick(function(self, button)
drawHint(settingsFrame, "Caches the Basalt API globally. Restarting your program won't download data from Github, which aren't stored on your computer. Only affects basalt.required(file) files.")
end)
Label(settings, 2, 8, "Auto Update:"):onClick(function(self, button)
drawHint(settingsFrame, "This will automatically update basalt whenever you start your program (and load basalt into your program). Doesn't work with the bundled installation.")
end)
Label(settings, 2, 10, "Minify"):onClick(function(self, button)
drawHint(settingsFrame, "This will minify all the files to reduce the file size. But it will make the files harder to read. Also unexpected errors will be harder to understand.")
end)
Label(settings, 2, 12, "Bundle"):onClick(function(self, button)
drawHint(settingsFrame, "This will bundle all the files into one file. Making it easier to use Basalt on your computer. The bundled version is meant to be used for production. If you're developing a program, you should not use the bundled version.")
end)
Label(settings, 2, 14, "Annotations"):onClick(function(self, button)
drawHint(settingsFrame, "This will download the annotations file. It will make the developement with basalt easier, as you can see the documentation of the functions in your editor. Doesn't work with the bundled installation.")
end)
local path = Input(settings, 15, 4, "{parent.w - 21}", 1, "{self.focused ? black : lightGray}", "{self.focused ? white : black}", installer.getConfig("defaultSettings").path.default)
local cache = Checkbox(settings, "{parent.w - 7}", 6, colors.lightGray, colors.black, false)
local autoUpdate = Checkbox(settings, "{parent.w - 7}", 8, colors.lightGray, colors.black, false):setEnabled(false)
local minify = Checkbox(settings, "{parent.w - 7}", 10, colors.lightGray, colors.black, false)
local bundle = Checkbox(settings, "{parent.w - 7}", 12, colors.lightGray, colors.black, false)
local annotations = Checkbox(settings, "{parent.w - 7}", 14, colors.lightGray, colors.black, false)
Button(settingsFrame, 2, "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Back", function()
basalt.switchFrame(installDescFrame)
end)
Button(settingsFrame, "{parent.w - self.w}", "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Next", function()
basalt.switchFrame(installFrame1)
if(config~=nil)then
config.defaultSettings.path.default = path:getValue()
config.defaultSettings.cacheGlobally.default = cache:getChecked()
config.defaultSettings.autoUpdate.default = autoUpdate:getChecked()
end
end)
-- Install Frame ---------------------------------------------------
Label(installFrame1, 2, 2, "Select the elements you want to install:"):onClick(function(self, button)
drawHint(installFrame1, "Elements are the core files of Basalt. You can choose which elements you want to install. Don't worry, you can add elements later on as well. Right click on an element to get more information about it.")
end)
Button(installFrame1, 2, "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Back", function()
basalt.switchFrame(settingsFrame)
end)
Button(installFrame1, "{parent.w - self.w}", "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Next", function()
basalt.switchFrame(installFrame2)
end)
local eleList = List(installFrame1, 3, 5, "{parent.w - 4}", "{parent.h - 7}", colors.white, colors.lightGray, {}, function()
end, colors.white, colors.black):setBorder(true):setBorderColor(colors.gray):setMultiSelection(true):onClick(function(self, btn, x, y)
if(btn==2)then
local item = self:getItems()[y + self:getScrollIndex()-1]
if(item~=nil)then
if(elements[item]~=nil)then
if(elements[item][3]~=nil)then
drawHint(installFrame1, elements[item][3])
end
end
end
end
end)
for k,v in pairs(elements)do
eleList:addItem(k)
if(checkForDefault(k, "elements"))then
eleList:selectItem(k)
end
end
--------------------------------------------------------------------
-- Install Frame 2 -------------------------------------------------
Label(installFrame2, 2, 2, "Select the extensions you want to install:"):onClick(function(self, button)
drawHint(installFrame2, "Extensions are additional features for Basalt. You can choose which extensions you want to install. Don't worry, you can add extensions later on as well. Right click on an extension to get more information about it.")
end)
Button(installFrame2, 2, "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Back", function()
basalt.switchFrame(installFrame1)
end)
local extList = List(installFrame2, 3, 5, "{parent.w - 4}", "{parent.h - 7}", colors.white, colors.lightGray, {}, function()
end, colors.white, colors.black):setBorder(true):setBorderColor(colors.gray):setMultiSelection(true):onClick(function(self, btn, x, y)
if(btn==2)then
local item = self:getItems()[y + self:getScrollIndex()-1]
if(item~=nil)then
if(extensions[item]~=nil)then
if(extensions[item][3]~=nil)then
drawHint(installFrame2, extensions[item][3])
end
end
end
end
end)
for k,_ in pairs(extensions)do
extList:addItem(k)
if(checkForDefault(k, "extensions"))then
extList:selectItem(k)
end
end
Button(installFrame2, "{parent.w - self.w}", "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Install", function()
loggingList:clear()
basalt.switchFrame(loggingFrame)
basalt.thread(function()
installer.install(eleList:getSelectedItems(), extList:getSelectedItems())
local projPath = path:getValue()
if(minify:getChecked())then
installer.minifyProject(projPath)
end
if(bundle:getChecked())then
installer.bundleProject(projPath)
fs.delete(projPath)
end
if(annotations:getChecked())and not(bundle:getChecked())then
downloadFile(fs.combine(projPath, "annotations.lua"), "https://raw.githubusercontent.com/Pyroxenium/basalt-docs/main/bundle.lua", "Annotations")
end
backBtn:setVisible(false)
doneBtn:setVisible(true)
end)
end)
--------------------------------------------------------------------
-- Logging Frame ---------------------------------------------------
backBtn = Button(loggingFrame, 2, "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Back", function()
basalt.switchFrame(installFrame2)
end)
doneBtn = Button(loggingFrame, "{parent.w - self.w}", "{parent.h - self.h + 1}", 10, 1, colors.white, colors.black, "Done", function()
basalt.stop()
end):setVisible(false)
loggingList = List(loggingFrame, 3, 3, "{parent.w - 4}", "{parent.h - 6}", colors.white, colors.black, {}, function()
end):setSelection(false):setBorder(true):setBorderColor(colors.gray):setAutoScroll(true)
--------------------------------------------------------------------
-- Main Frame ------------------------------------------------------
local introFrame = ScrollFrame(main, 3, 3, "{parent.w - 4}", "{parent.h - 6}", colors.white, colors.white):setBorder(true):setBorderColor(colors.gray)
introFrame:addLabel():setWrap(true):setSize("{parent.w}", "{parent.h}"):setBackground(colors.white):setForeground(colors.black)
:setText([[
Welcome to Basalt!
Thanks for using Basalt! Before we install the project, i'd like to say that Basalt is just a hobby project, made by one person. This means that there might be bugs, and the documentation might not be perfect. If you find any bugs, please report them on the Github page. If you have any questions, feel free to ask them on the Github page or in discord. You can also do a pull request if you want to contribute to the project.
Also, i'm working on the project in my free time, so updates might not be as frequent as you'd like. I'm doing my best to keep the project up to date and add new features, but it might take some time.
]])
Button(main, "{parent.w - self.w}", "{parent.h}", 11, 1, "white", "black", "Install", function()
basalt.switchFrame(installDescFrame)
end)
Button(main, 2, "{parent.h}", 6, 1, "white", "black", "Exit", function()
basalt.stop()
end)
--------------------------------------------------------------------
basalt.autoUpdate()
end
if(args[1]=="source")then
installer.install()
if(args[2]=="true")then
installer.minifyProject(installer.getConfig("defaultSettings").path.default)
end
elseif(args[1]=="bundled")then
installer.install()
if(args[2]=="true")then
installer.minifyProject(installer.getConfig("defaultSettings").path.default)
end
installer.bundleProject(installer.getConfig("defaultSettings").path.default)
elseif(args[1]=="minify")then
installer.minifyProject(args[2])
elseif(args[1]=="bundle")then
installer.bundleProject(args[2] or "basalt")
else
installer.gui()
end

View File

@@ -1,398 +0,0 @@
-- The minify part is fully made by stravant and can be found here: https://github.com/stravant/LuaMinify/blob/master/RobloxPlugin/Minify.lua
-- Thanks to him for his awesome work!
--
--
-- A compilation of all of the neccesary code to Minify a source file, all into one single
-- script for usage on Roblox. Needed to deal with Roblox' lack of `require`.
--
function lookupify(cd)for dd,__a in pairs(cd)do cd[__a]=true end;return cd end
function CountTable(cd)local dd=0;for __a in pairs(cd)do dd=dd+1 end;return dd end
function PrintTable(cd,dd)if cd.Print then return cd.Print()end;dd=dd or 0
local __a=(CountTable(cd)>1)local a_a=string.rep(' ',dd+1)
local b_a="{".. (__a and'\n'or'')
for c_a,d_a in pairs(cd)do
if type(d_a)~='function'then
b_a=b_a.. (__a and a_a or'')
if type(c_a)=='number'then elseif type(c_a)=='string'and
c_a:match("^[A-Za-z_][A-Za-z0-9_]*$")then b_a=b_a..c_a.." = "elseif
type(c_a)=='string'then b_a=b_a.."[\""..c_a.."\"] = "else b_a=b_a.."["..
tostring(c_a).."] = "end
if type(d_a)=='string'then b_a=b_a.."\""..d_a.."\""elseif type(d_a)==
'number'then b_a=b_a..d_a elseif type(d_a)=='table'then b_a=b_a..
PrintTable(d_a,dd+ (__a and 1 or 0))else
b_a=b_a..tostring(d_a)end;if next(cd,c_a)then b_a=b_a..","end;if __a then b_a=b_a..'\n'end end end;b_a=b_a..
(__a and string.rep(' ',dd)or'').."}"return b_a end;local bb=lookupify{' ','\n','\t','\r'}
local cb={['\r']='\\r',['\n']='\\n',['\t']='\\t',['"']='\\"',["'"]="\\'"}
local db=lookupify{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
local _c=lookupify{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
local ac=lookupify{'0','1','2','3','4','5','6','7','8','9'}
local bc=lookupify{'0','1','2','3','4','5','6','7','8','9','A','a','B','b','C','c','D','d','E','e','F','f'}
local cc=lookupify{'+','-','*','/','^','%',',','{','}','[',']','(',')',';','#'}
local dc=lookupify{'and','break','do','else','elseif','end','false','for','function','goto','if','in','local','nil','not','or','repeat','return','then','true','until','while'}
function LexLua(cd)local dd={}
local __a,a_a=pcall(function()local _aa=1;local aaa=1;local baa=1
local function caa()local cba=cd:sub(_aa,_aa)if cba=='\n'then baa=1
aaa=aaa+1 else baa=baa+1 end;_aa=_aa+1;return cba end
local function daa(cba)cba=cba or 0;return cd:sub(_aa+cba,_aa+cba)end;local function _ba(cba)local dba=daa()
for i=1,#cba do if dba==cba:sub(i,i)then return caa()end end end;local function aba(cba)
return error(">> :"..aaa..":"..
baa..": "..cba,0)end
local function bba()local cba=_aa
if daa()=='['then local dba=0;while
daa(dba+1)=='='do dba=dba+1 end
if daa(dba+1)=='['then for _=0,dba+1 do caa()end
local _ca=_aa
while true do if daa()==''then
aba("Expected `]"..string.rep('=',dba).."]` near <eof>.",3)end;local cca=true;if daa()==']'then for i=1,dba do if daa(i)~='='then
cca=false end end
if daa(dba+1)~=']'then cca=false end else cca=false end;if cca then break else
caa()end end;local aca=cd:sub(_ca,_aa-1)for i=0,dba+1 do caa()end
local bca=cd:sub(cba,_aa-1)return aca,bca else return nil end else return nil end end
while true do local cba=''
while true do local dca=daa()
if bb[dca]then cba=cba..caa()elseif
dca=='-'and daa(1)=='-'then caa()caa()cba=cba..'--'local _da,ada=bba()
if ada then cba=cba..ada else while daa()~='\n'and
daa()~=''do cba=cba..caa()end end else break end end;local dba=aaa;local _ca=baa
local aca=":"..aaa..":"..baa..":> "local bca=daa()local cca=nil
if bca==''then cca={Type='Eof'}elseif
_c[bca]or db[bca]or bca=='_'then local dca=_aa;repeat caa()bca=daa()until not
(_c[bca]or db[bca]or ac[bca]or bca=='_')
local _da=cd:sub(dca,_aa-1)
if dc[_da]then cca={Type='Keyword',Data=_da}else cca={Type='Ident',Data=_da}end elseif ac[bca]or(daa()=='.'and ac[daa(1)])then local dca=_aa
if bca=='0'and
daa(1)=='x'then caa()caa()while bc[daa()]do caa()end;if _ba('Pp')then
_ba('+-')while ac[daa()]do caa()end end else
while ac[daa()]do caa()end;if _ba('.')then while ac[daa()]do caa()end end;if _ba('Ee')then
_ba('+-')while ac[daa()]do caa()end end end;cca={Type='Number',Data=cd:sub(dca,_aa-1)}elseif bca=='\''or bca==
'\"'then local dca=_aa;local _da=caa()local ada=_aa;while true do local dda=caa()
if dda=='\\'then caa()elseif
dda==_da then break elseif dda==''then aba("Unfinished string near <eof>")end end;local bda=cd:sub(ada,
_aa-2)local cda=cd:sub(dca,_aa-1)
cca={Type='String',Data=cda,Constant=bda}elseif bca=='['then local dca,_da=bba()
if _da then cca={Type='String',Data=_da,Constant=dca}else
caa()cca={Type='Symbol',Data='['}end elseif _ba('>=<')then if _ba('=')then cca={Type='Symbol',Data=bca..'='}else
cca={Type='Symbol',Data=bca}end elseif _ba('~')then
if _ba('=')then
cca={Type='Symbol',Data='~='}else aba("Unexpected symbol `~` in source.",2)end elseif _ba('.')then
if _ba('.')then if _ba('.')then cca={Type='Symbol',Data='...'}else
cca={Type='Symbol',Data='..'}end else cca={Type='Symbol',Data='.'}end elseif _ba(':')then if _ba(':')then cca={Type='Symbol',Data='::'}else
cca={Type='Symbol',Data=':'}end elseif cc[bca]then caa()
cca={Type='Symbol',Data=bca}else local dca,_da=bba()if dca then cca={Type='String',Data=_da,Constant=dca}else
aba("Unexpected Symbol `"..
bca.."` in source.",2)end end;cca.LeadingWhite=cba;cca.Line=dba;cca.Char=_ca
cca.Print=function()
return"<".. (cca.Type..string.rep(' ',7 -#
cca.Type))..
" ".. (cca.Data or'').." >"end;dd[#dd+1]=cca;if cca.Type=='Eof'then break end end end)if not __a then return false,a_a end;local b_a={}local c_a={}local d_a=1
function b_a:Peek(_aa)_aa=_aa or 0;return dd[math.min(
#dd,d_a+_aa)]end
function b_a:Get()local _aa=dd[d_a]d_a=math.min(d_a+1,#dd)return _aa end;function b_a:Is(_aa)return b_a:Peek().Type==_aa end;function b_a:Save()c_a[
#c_a+1]=d_a end
function b_a:Commit()c_a[#c_a]=nil end;function b_a:Restore()d_a=c_a[#c_a]c_a[#c_a]=nil end
function b_a:ConsumeSymbol(_aa)
local aaa=self:Peek()
if aaa.Type=='Symbol'then if _aa then
if aaa.Data==_aa then self:Get()return true else return nil end else self:Get()return aaa end else return
nil end end
function b_a:ConsumeKeyword(_aa)local aaa=self:Peek()if
aaa.Type=='Keyword'and aaa.Data==_aa then self:Get()return true else return nil end end;function b_a:IsKeyword(_aa)local aaa=b_a:Peek()return
aaa.Type=='Keyword'and aaa.Data==_aa end
function b_a:IsSymbol(_aa)
local aaa=b_a:Peek()return aaa.Type=='Symbol'and aaa.Data==_aa end
function b_a:IsEof()return b_a:Peek().Type=='Eof'end;return true,b_a end
function ParseLua(cd)local dd,__a=LexLua(cd)if not dd then return false,__a end
local function a_a(ada)local bda=">> :"..
__a:Peek().Line..":"..__a:Peek().Char..": "..ada.."\n"local cda=0
for dda in
cd:gmatch("[^\n]*\n?")do if dda:sub(-1,-1)=='\n'then dda=dda:sub(1,-2)end;cda=
cda+1
if cda==__a:Peek().Line then bda=bda..">> `"..
dda:gsub('\t',' ').."`\n"for i=1,__a:Peek().Char
do local __b=dda:sub(i,i)
if __b=='\t'then bda=bda..' 'else bda=bda..' 'end end
bda=bda.." ^---"break end end;return bda end;local b_a=0;local c_a={}local d_a={'_','a','b','c','d'}
local function _aa(ada)local bda={}bda.Parent=ada
bda.LocalList={}bda.LocalMap={}
function bda:RenameVars()
for cda,dda in pairs(bda.LocalList)do local __b;b_a=0
repeat b_a=b_a+1;local a_b=b_a
__b=''while a_b>0 do local b_b=a_b%#d_a;a_b=(a_b-b_b)/#d_a
__b=__b..d_a[b_b+1]end until
not c_a[__b]and
not ada:GetLocal(__b)and not bda.LocalMap[__b]dda.Name=__b;bda.LocalMap[__b]=dda end end
function bda:GetLocal(cda)local dda=bda.LocalMap[cda]if dda then return dda end;if bda.Parent then
local __b=bda.Parent:GetLocal(cda)if __b then return __b end end;return nil end
function bda:CreateLocal(cda)local dda={}dda.Scope=bda;dda.Name=cda;dda.CanRename=true;bda.LocalList[#
bda.LocalList+1]=dda
bda.LocalMap[cda]=dda;return dda end;bda.Print=function()return"<Scope>"end;return bda end;local aaa;local baa
local function caa(ada)local bda=_aa(ada)if not __a:ConsumeSymbol('(')then return false,
a_a("`(` expected.")end;local cda={}local dda=false
while not
__a:ConsumeSymbol(')')do
if __a:Is('Ident')then
local c_b=bda:CreateLocal(__a:Get().Data)cda[#cda+1]=c_b;if not __a:ConsumeSymbol(',')then
if
__a:ConsumeSymbol(')')then break else return false,a_a("`)` expected.")end end elseif
__a:ConsumeSymbol('...')then dda=true
if not __a:ConsumeSymbol(')')then return false,
a_a("`...` must be the last argument of a function.")end;break else return false,a_a("Argument name or `...` expected")end end;local __b,a_b=baa(bda)if not __b then return false,a_b end;if not
__a:ConsumeKeyword('end')then
return false,a_a("`end` expected after function body")end;local b_b={}
b_b.AstType='Function'b_b.Scope=bda;b_b.Arguments=cda;b_b.Body=a_b;b_b.VarArg=dda;return true,b_b end
local function daa(ada)
if __a:ConsumeSymbol('(')then local bda,cda=aaa(ada)
if not bda then return false,cda end
if not __a:ConsumeSymbol(')')then return false,a_a("`)` Expected.")end;cda.ParenCount=(cda.ParenCount or 0)+1;return true,cda elseif
__a:Is('Ident')then local bda=__a:Get()local cda=ada:GetLocal(bda.Data)if not cda then
c_a[bda.Data]=true end;local dda={}dda.AstType='VarExpr'dda.Name=bda.Data
dda.Local=cda;return true,dda else return false,a_a("primary expression expected")end end
local function _ba(ada,bda)local cda,dda=daa(ada)if not cda then return false,dda end
while true do
if __a:IsSymbol('.')or
__a:IsSymbol(':')then local __b=__a:Get().Data;if not __a:Is('Ident')then return false,
a_a("<Ident> expected.")end;local a_b=__a:Get()
local b_b={}b_b.AstType='MemberExpr'b_b.Base=dda;b_b.Indexer=__b;b_b.Ident=a_b;dda=b_b elseif not
bda and __a:ConsumeSymbol('[')then local __b,a_b=aaa(ada)if not __b then
return false,a_b end;if not __a:ConsumeSymbol(']')then
return false,a_a("`]` expected.")end;local b_b={}b_b.AstType='IndexExpr'
b_b.Base=dda;b_b.Index=a_b;dda=b_b elseif not bda and __a:ConsumeSymbol('(')then local __b={}
while not
__a:ConsumeSymbol(')')do local b_b,c_b=aaa(ada)if not b_b then return false,c_b end
__b[#__b+1]=c_b
if not __a:ConsumeSymbol(',')then if __a:ConsumeSymbol(')')then break else return false,
a_a("`)` Expected.")end end end;local a_b={}a_b.AstType='CallExpr'a_b.Base=dda;a_b.Arguments=__b;dda=a_b elseif not bda and
__a:Is('String')then local __b={}__b.AstType='StringCallExpr'__b.Base=dda
__b.Arguments={__a:Get()}dda=__b elseif not bda and __a:IsSymbol('{')then local __b,a_b=aaa(ada)if not __b then
return false,a_b end;local b_b={}b_b.AstType='TableCallExpr'b_b.Base=dda
b_b.Arguments={a_b}dda=b_b else break end end;return true,dda end
local function aba(ada)
if __a:Is('Number')then local bda={}bda.AstType='NumberExpr'bda.Value=__a:Get()return
true,bda elseif __a:Is('String')then local bda={}bda.AstType='StringExpr'
bda.Value=__a:Get()return true,bda elseif __a:ConsumeKeyword('nil')then local bda={}bda.AstType='NilExpr'
return true,bda elseif __a:IsKeyword('false')or __a:IsKeyword('true')then local bda={}
bda.AstType='BooleanExpr'bda.Value=(__a:Get().Data=='true')return true,bda elseif
__a:ConsumeSymbol('...')then local bda={}bda.AstType='DotsExpr'return true,bda elseif __a:ConsumeSymbol('{')then local bda={}
bda.AstType='ConstructorExpr'bda.EntryList={}
while true do
if __a:IsSymbol('[')then __a:Get()local cda,dda=aaa(ada)
if not cda then return
false,a_a("Key Expression Expected")end
if not __a:ConsumeSymbol(']')then return false,a_a("`]` Expected")end
if not __a:ConsumeSymbol('=')then return false,a_a("`=` Expected")end;local __b,a_b=aaa(ada)if not __b then
return false,a_a("Value Expression Expected")end
bda.EntryList[#bda.EntryList+1]={Type='Key',Key=dda,Value=a_b}elseif __a:Is('Ident')then local cda=__a:Peek(1)
if
cda.Type=='Symbol'and cda.Data=='='then local dda=__a:Get()if not __a:ConsumeSymbol('=')then
return false,a_a("`=` Expected")end;local __b,a_b=aaa(ada)if not __b then return false,
a_a("Value Expression Expected")end
bda.EntryList[
#bda.EntryList+1]={Type='KeyString',Key=dda.Data,Value=a_b}else local dda,__b=aaa(ada)
if not dda then return false,a_a("Value Exected")end
bda.EntryList[#bda.EntryList+1]={Type='Value',Value=__b}end elseif __a:ConsumeSymbol('}')then break else local cda,dda=aaa(ada)
bda.EntryList[#bda.EntryList+1]={Type='Value',Value=dda}if not cda then return false,a_a("Value Expected")end end
if __a:ConsumeSymbol(';')or __a:ConsumeSymbol(',')then elseif
__a:ConsumeSymbol('}')then break else return false,a_a("`}` or table entry Expected")end end;return true,bda elseif __a:ConsumeKeyword('function')then local bda,cda=caa(ada)if not bda then
return false,cda end;cda.IsLocal=true;return true,cda else return _ba(ada)end end;local bba=lookupify{'-','not','#'}local cba=8
local dba={['+']={6,6},['-']={6,6},['%']={7,7},['/']={7,7},['*']={7,7},['^']={10,9},['..']={5,4},['==']={3,3},['<']={3,3},['<=']={3,3},['~=']={3,3},['>']={3,3},['>=']={3,3},['and']={2,2},['or']={1,1}}
local function _ca(ada,bda)local cda,dda
if bba[__a:Peek().Data]then local __b=__a:Get().Data
cda,dda=_ca(ada,cba)if not cda then return false,dda end;local a_b={}a_b.AstType='UnopExpr'
a_b.Rhs=dda;a_b.Op=__b;dda=a_b else cda,dda=aba(ada)if not cda then return false,dda end end
while true do local __b=dba[__a:Peek().Data]
if __b and __b[1]>bda then
local a_b=__a:Get().Data;local b_b,c_b=_ca(ada,__b[2])if not b_b then return false,c_b end;local d_b={}
d_b.AstType='BinopExpr'd_b.Lhs=dda;d_b.Op=a_b;d_b.Rhs=c_b;dda=d_b else break end end;return true,dda end;aaa=function(ada)return _ca(ada,0)end
local function aca(ada)local bda=nil
if
__a:ConsumeKeyword('if')then local cda={}cda.AstType='IfStatement'cda.Clauses={}
repeat local dda,__b=aaa(ada)if not dda then
return false,__b end;if not __a:ConsumeKeyword('then')then return false,
a_a("`then` expected.")end
local a_b,b_b=baa(ada)if not a_b then return false,b_b end
cda.Clauses[#cda.Clauses+1]={Condition=__b,Body=b_b}until not __a:ConsumeKeyword('elseif')
if __a:ConsumeKeyword('else')then local dda,__b=baa(ada)
if not dda then return false,__b end;cda.Clauses[#cda.Clauses+1]={Body=__b}end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected.")end;bda=cda elseif __a:ConsumeKeyword('while')then
local cda={}cda.AstType='WhileStatement'local dda,__b=aaa(ada)
if not dda then return false,__b end;if not __a:ConsumeKeyword('do')then
return false,a_a("`do` expected.")end;local a_b,b_b=baa(ada)
if not a_b then return false,b_b end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected.")end;cda.Condition=__b;cda.Body=b_b;bda=cda elseif
__a:ConsumeKeyword('do')then local cda,dda=baa(ada)if not cda then return false,dda end
if not
__a:ConsumeKeyword('end')then return false,a_a("`end` expected.")end;local __b={}__b.AstType='DoStatement'__b.Body=dda;bda=__b elseif
__a:ConsumeKeyword('for')then
if not __a:Is('Ident')then return false,a_a("<ident> expected.")end;local cda=__a:Get()
if __a:ConsumeSymbol('=')then local dda=_aa(ada)
local __b=dda:CreateLocal(cda.Data)local a_b,b_b=aaa(ada)if not a_b then return false,b_b end
if not
__a:ConsumeSymbol(',')then return false,a_a("`,` Expected")end;local c_b,d_b=aaa(ada)if not c_b then return false,d_b end;local _ab,aab
if
__a:ConsumeSymbol(',')then _ab,aab=aaa(ada)if not _ab then return false,aab end end;if not __a:ConsumeKeyword('do')then
return false,a_a("`do` expected")end;local bab,cab=baa(dda)
if not bab then return false,cab end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected")end;local dab={}
dab.AstType='NumericForStatement'dab.Scope=dda;dab.Variable=__b;dab.Start=b_b;dab.End=d_b;dab.Step=aab
dab.Body=cab;bda=dab else local dda=_aa(ada)
local __b={dda:CreateLocal(cda.Data)}
while __a:ConsumeSymbol(',')do if not __a:Is('Ident')then return false,
a_a("for variable expected.")end
__b[#__b+1]=dda:CreateLocal(__a:Get().Data)end;if not __a:ConsumeKeyword('in')then
return false,a_a("`in` expected.")end;local a_b={}local b_b,c_b=aaa(ada)if not b_b then
return false,c_b end;a_b[#a_b+1]=c_b
while __a:ConsumeSymbol(',')do
local bab,cab=aaa(ada)if not bab then return false,cab end;a_b[#a_b+1]=cab end;if not __a:ConsumeKeyword('do')then
return false,a_a("`do` expected.")end;local d_b,_ab=baa(dda)
if not d_b then return false,_ab end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected.")end;local aab={}
aab.AstType='GenericForStatement'aab.Scope=dda;aab.VariableList=__b;aab.Generators=a_b;aab.Body=_ab;bda=aab end elseif __a:ConsumeKeyword('repeat')then local cda,dda=baa(ada)
if not cda then return false,dda end;if not __a:ConsumeKeyword('until')then
return false,a_a("`until` expected.")end;local __b,a_b=aaa(ada)
if not __b then return false,a_b end;local b_b={}b_b.AstType='RepeatStatement'b_b.Condition=a_b;b_b.Body=dda;bda=b_b elseif
__a:ConsumeKeyword('function')then if not __a:Is('Ident')then
return false,a_a("Function name expected")end;local cda,dda=_ba(ada,true)if not cda then
return false,dda end;local __b,a_b=caa(ada)if not __b then return false,a_b end
a_b.IsLocal=false;a_b.Name=dda;bda=a_b elseif __a:ConsumeKeyword('local')then
if __a:Is('Ident')then
local cda={__a:Get().Data}while __a:ConsumeSymbol(',')do if not __a:Is('Ident')then return false,
a_a("local var name expected")end
cda[#cda+1]=__a:Get().Data end;local dda={}if
__a:ConsumeSymbol('=')then
repeat local a_b,b_b=aaa(ada)if not a_b then return false,b_b end
dda[#dda+1]=b_b until not __a:ConsumeSymbol(',')end;for a_b,b_b in
pairs(cda)do cda[a_b]=ada:CreateLocal(b_b)end
local __b={}__b.AstType='LocalStatement'__b.LocalList=cda;__b.InitList=dda;bda=__b elseif
__a:ConsumeKeyword('function')then if not __a:Is('Ident')then
return false,a_a("Function name expected")end;local cda=__a:Get().Data
local dda=ada:CreateLocal(cda)local __b,a_b=caa(ada)if not __b then return false,a_b end;a_b.Name=dda
a_b.IsLocal=true;bda=a_b else
return false,a_a("local var or function def expected")end elseif __a:ConsumeSymbol('::')then if not __a:Is('Ident')then return false,
a_a('Label name expected')end
local cda=__a:Get().Data
if not __a:ConsumeSymbol('::')then return false,a_a("`::` expected")end;local dda={}dda.AstType='LabelStatement'dda.Label=cda;bda=dda elseif
__a:ConsumeKeyword('return')then local cda={}
if not __a:IsKeyword('end')then local __b,a_b=aaa(ada)
if __b then cda[1]=a_b;while
__a:ConsumeSymbol(',')do local b_b,c_b=aaa(ada)if not b_b then return false,c_b end
cda[#cda+1]=c_b end end end;local dda={}dda.AstType='ReturnStatement'dda.Arguments=cda;bda=dda elseif
__a:ConsumeKeyword('break')then local cda={}cda.AstType='BreakStatement'bda=cda elseif __a:IsKeyword('goto')then
if not
__a:Is('Ident')then return false,a_a("Label expected")end;local cda=__a:Get().Data;local dda={}dda.AstType='GotoStatement'
dda.Label=cda;bda=dda else local cda,dda=_ba(ada)if not cda then return false,dda end
if
__a:IsSymbol(',')or __a:IsSymbol('=')then
if(dda.ParenCount or 0)>0 then return false,
a_a("Can not assign to parenthesized expression, is not an lvalue")end;local __b={dda}
while __a:ConsumeSymbol(',')do local _ab,aab=_ba(ada)
if not _ab then return false,aab end;__b[#__b+1]=aab end
if not __a:ConsumeSymbol('=')then return false,a_a("`=` Expected.")end;local a_b={}local b_b,c_b=aaa(ada)if not b_b then return false,c_b end;a_b[1]=c_b;while
__a:ConsumeSymbol(',')do local _ab,aab=aaa(ada)if not _ab then return false,aab end
a_b[#a_b+1]=aab end;local d_b={}
d_b.AstType='AssignmentStatement'd_b.Lhs=__b;d_b.Rhs=a_b;bda=d_b elseif
dda.AstType=='CallExpr'or
dda.AstType=='TableCallExpr'or dda.AstType=='StringCallExpr'then local __b={}__b.AstType='CallStatement'__b.Expression=dda;bda=__b else return false,
a_a("Assignment Statement Expected")end end;bda.HasSemicolon=__a:ConsumeSymbol(';')return true,bda end
local bca=lookupify{'end','else','elseif','until'}
baa=function(ada)local bda={}bda.Scope=_aa(ada)bda.AstType='Statlist'local cda={}
while not
bca[__a:Peek().Data]and not __a:IsEof()do
local dda,__b=aca(bda.Scope)if not dda then return false,__b end;cda[#cda+1]=__b end;bda.Body=cda;return true,bda end;local function cca()local ada=_aa()return baa(ada)end;local dca,_da=cca()
return dca,_da end
local _d=lookupify{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
local ad=lookupify{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
local bd=lookupify{'0','1','2','3','4','5','6','7','8','9'}
function Format_Mini(cd)local dd,__a;local a_a=0
local function b_a(d_a,_aa,aaa)
if a_a>150 then a_a=0;return d_a.."\n".._aa end;aaa=aaa or' 'local baa,caa=d_a:sub(-1,-1),_aa:sub(1,1)
if
ad[baa]or _d[baa]or baa=='_'then
if not
(ad[caa]or _d[caa]or caa=='_'or bd[caa])then return d_a.._aa elseif caa=='('then
return d_a..aaa.._aa else return d_a..aaa.._aa end elseif bd[baa]then
if caa=='('then return d_a.._aa else return d_a..aaa.._aa end elseif baa==''then return d_a.._aa else
if caa=='('then return d_a..aaa.._aa else return d_a.._aa end end end
__a=function(d_a)local _aa=string.rep('(',d_a.ParenCount or 0)
if
d_a.AstType=='VarExpr'then if d_a.Local then _aa=_aa..d_a.Local.Name else
_aa=_aa..d_a.Name end elseif d_a.AstType=='NumberExpr'then _aa=_aa..
d_a.Value.Data elseif d_a.AstType=='StringExpr'then
_aa=_aa..d_a.Value.Data elseif d_a.AstType=='BooleanExpr'then _aa=_aa..tostring(d_a.Value)elseif
d_a.AstType=='NilExpr'then _aa=b_a(_aa,"nil")elseif d_a.AstType=='BinopExpr'then
_aa=b_a(_aa,__a(d_a.Lhs))_aa=b_a(_aa,d_a.Op)_aa=b_a(_aa,__a(d_a.Rhs))elseif d_a.AstType==
'UnopExpr'then _aa=b_a(_aa,d_a.Op)
_aa=b_a(_aa,__a(d_a.Rhs))elseif d_a.AstType=='DotsExpr'then _aa=_aa.."..."elseif d_a.AstType=='CallExpr'then _aa=_aa..
__a(d_a.Base)_aa=_aa.."("for i=1,#d_a.Arguments do _aa=_aa..
__a(d_a.Arguments[i])
if i~=#d_a.Arguments then _aa=_aa..","end end;_aa=_aa..")"elseif d_a.AstType==
'TableCallExpr'then _aa=_aa..__a(d_a.Base)_aa=_aa..
__a(d_a.Arguments[1])elseif d_a.AstType=='StringCallExpr'then
_aa=_aa..__a(d_a.Base)_aa=_aa..d_a.Arguments[1].Data elseif
d_a.AstType=='IndexExpr'then
_aa=_aa..__a(d_a.Base).."["..__a(d_a.Index).."]"elseif d_a.AstType=='MemberExpr'then _aa=_aa..__a(d_a.Base)..
d_a.Indexer..d_a.Ident.Data elseif
d_a.AstType=='Function'then d_a.Scope:RenameVars()
_aa=_aa.."function("
if#d_a.Arguments>0 then for i=1,#d_a.Arguments do
_aa=_aa..d_a.Arguments[i].Name
if i~=#d_a.Arguments then _aa=_aa..","elseif d_a.VarArg then _aa=_aa..",..."end end elseif
d_a.VarArg then _aa=_aa.."..."end;_aa=_aa..")"_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='ConstructorExpr'then _aa=_aa.."{"
for i=1,#d_a.EntryList do
local aaa=d_a.EntryList[i]
if aaa.Type=='Key'then _aa=_aa.."["..
__a(aaa.Key).."]="..__a(aaa.Value)elseif aaa.Type==
'Value'then _aa=_aa..__a(aaa.Value)elseif aaa.Type=='KeyString'then
_aa=_aa..
aaa.Key.."="..__a(aaa.Value)end;if i~=#d_a.EntryList then _aa=_aa..","end end;_aa=_aa.."}"end
_aa=_aa..string.rep(')',d_a.ParenCount or 0)a_a=a_a+#_aa;return _aa end
local c_a=function(d_a)local _aa=''
if d_a.AstType=='AssignmentStatement'then
for i=1,#d_a.Lhs do
_aa=_aa..__a(d_a.Lhs[i])if i~=#d_a.Lhs then _aa=_aa..","end end;if#d_a.Rhs>0 then _aa=_aa.."="
for i=1,#d_a.Rhs do
_aa=_aa..__a(d_a.Rhs[i])if i~=#d_a.Rhs then _aa=_aa..","end end end elseif
d_a.AstType=='CallStatement'then _aa=__a(d_a.Expression)elseif d_a.AstType=='LocalStatement'then
_aa=_aa.."local "
for i=1,#d_a.LocalList do _aa=_aa..d_a.LocalList[i].Name;if i~=#
d_a.LocalList then _aa=_aa..","end end
if#d_a.InitList>0 then _aa=_aa.."="for i=1,#d_a.InitList do _aa=_aa..
__a(d_a.InitList[i])
if i~=#d_a.InitList then _aa=_aa..","end end end elseif d_a.AstType=='IfStatement'then
_aa=b_a("if",__a(d_a.Clauses[1].Condition))_aa=b_a(_aa,"then")
_aa=b_a(_aa,dd(d_a.Clauses[1].Body))
for i=2,#d_a.Clauses do local aaa=d_a.Clauses[i]
if aaa.Condition then
_aa=b_a(_aa,"elseif")_aa=b_a(_aa,__a(aaa.Condition))
_aa=b_a(_aa,"then")else _aa=b_a(_aa,"else")end;_aa=b_a(_aa,dd(aaa.Body))end;_aa=b_a(_aa,"end")elseif d_a.AstType=='WhileStatement'then
_aa=b_a("while",__a(d_a.Condition))_aa=b_a(_aa,"do")_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='DoStatement'then _aa=b_a(_aa,"do")
_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"end")elseif d_a.AstType=='ReturnStatement'then _aa="return"
for i=1,#d_a.Arguments
do _aa=b_a(_aa,__a(d_a.Arguments[i]))if i~=
#d_a.Arguments then _aa=_aa..","end end elseif d_a.AstType=='BreakStatement'then _aa="break"elseif d_a.AstType=='RepeatStatement'then
_aa="repeat"_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"until")
_aa=b_a(_aa,__a(d_a.Condition))elseif d_a.AstType=='Function'then d_a.Scope:RenameVars()if d_a.IsLocal then
_aa="local"end;_aa=b_a(_aa,"function ")if d_a.IsLocal then
_aa=_aa..d_a.Name.Name else _aa=_aa..__a(d_a.Name)end;_aa=
_aa.."("
if#d_a.Arguments>0 then
for i=1,#d_a.Arguments do _aa=_aa..
d_a.Arguments[i].Name;if i~=#d_a.Arguments then _aa=_aa..","elseif d_a.VarArg then
_aa=_aa..",..."end end elseif d_a.VarArg then _aa=_aa.."..."end;_aa=_aa..")"_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='GenericForStatement'then d_a.Scope:RenameVars()
_aa="for "
for i=1,#d_a.VariableList do
_aa=_aa..d_a.VariableList[i].Name;if i~=#d_a.VariableList then _aa=_aa..","end end;_aa=_aa.." in"
for i=1,#d_a.Generators do
_aa=b_a(_aa,__a(d_a.Generators[i]))if i~=#d_a.Generators then _aa=b_a(_aa,',')end end;_aa=b_a(_aa,"do")_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='NumericForStatement'then _aa="for "_aa=_aa..
d_a.Variable.Name.."="_aa=_aa..
__a(d_a.Start)..","..__a(d_a.End)if d_a.Step then
_aa=_aa..","..__a(d_a.Step)end;_aa=b_a(_aa,"do")
_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"end")end;a_a=a_a+#_aa;return _aa end
dd=function(d_a)local _aa=''d_a.Scope:RenameVars()for aaa,baa in pairs(d_a.Body)do
_aa=b_a(_aa,c_a(baa),';')end;return _aa end;cd.Scope:RenameVars()return dd(cd)end
return function(cd)local dd,__a=ParseLua(cd)if not dd then return false,__a end
return true,Format_Mini(__a)end

View File

@@ -7,18 +7,14 @@ export {};
const __VLS_unref: typeof import('vue').unref;
const __VLS_placeholder: any;
const __VLS_nativeElements = {
...{} as SVGElementTagNameMap,
...{} as HTMLElementTagNameMap,
};
type __VLS_NativeElements = __VLS_SpreadMerge<SVGElementTagNameMap, HTMLElementTagNameMap>;
type __VLS_IntrinsicElements = import('vue/jsx-runtime').JSX.IntrinsicElements;
type __VLS_Element = import('vue/jsx-runtime').JSX.Element;
type __VLS_GlobalComponents = import('vue').GlobalComponents;
type __VLS_GlobalDirectives = import('vue').GlobalDirectives;
type __VLS_IsAny<T> = 0 extends 1 & T ? true : false;
type __VLS_PickNotAny<A, B> = __VLS_IsAny<A> extends true ? B : A;
type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void;
type __VLS_SpreadMerge<A, B> = Omit<A, keyof B> & B;
type __VLS_WithComponent<N0 extends string, LocalComponents, Self, N1 extends string, N2 extends string, N3 extends string> =
N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } :
N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N2] } :
@@ -81,19 +77,12 @@ export {};
};
type __VLS_UseTemplateRef<T> = Readonly<import('vue').ShallowRef<T | null>>;
function __VLS_getVForSourceType(source: number): [number, number][];
function __VLS_getVForSourceType(source: string): [string, number][];
function __VLS_getVForSourceType<T extends any[]>(source: T): [
item: T[number],
index: number,
][];
function __VLS_getVForSourceType<T extends { [Symbol.iterator](): Iterator<any> }>(source: T): [
item: T extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never,
index: number,
][];
// #3845
function __VLS_getVForSourceType<T extends number | { [Symbol.iterator](): Iterator<any> }>(source: T): [
item: number | (Exclude<T, number> extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never),
function __VLS_getVForSourceType<T extends number | string | any[] | Iterable<any>>(source: T): [
item: T extends number ? number
: T extends string ? string
: T extends any[] ? T[number]
: T extends Iterable<infer T1> ? T1
: any,
index: number,
][];
function __VLS_getVForSourceType<T>(source: T): [
@@ -109,21 +98,24 @@ export {};
? NonNullable<T['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']>
: T extends (...args: any) => any
? T
: __VLS_unknownDirective;
function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K;
: (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void;
function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] };
function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K):
T extends new (...args: any) => any
? (props: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>, ctx?: any) => __VLS_Element & { __ctx?: {
attrs?: any,
slots?: K extends { $slots: infer Slots } ? Slots : any,
emit?: K extends { $emit: infer Emit } ? Emit : any
} & { props?: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>; expose?(exposed: K): void; } }
? (props: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>, ctx?: any) => __VLS_Element & {
__ctx?: {
attrs?: any;
slots?: K extends { $slots: infer Slots } ? Slots : any;
emit?: K extends { $emit: infer Emit } ? Emit : any;
expose?(exposed: K): void;
props?: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>;
}
}
: T extends () => any ? (props: {}, ctx?: any) => ReturnType<T>
: T extends (...args: any) => any ? T
: (_: {} & Record<string, unknown>, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {} & Record<string, unknown> } };
function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (_: T & Record<string, unknown>) => void;
function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): 2 extends Parameters<T>['length'] ? [any] : [];
function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S;
function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (attrs: T & Record<string, unknown>) => void;
function __VLS_asFunctionalSlot<S>(slot: S): (props: NonNullable<S> extends (props: infer P) => any ? P : {}) => void;
function __VLS_tryAsConstant<const T>(t: T): T;
}