Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- "D:bin",
- "{\
- \"F:bg\",\
- \"\\\"\\\\\\\
- if not shell.launchProcess then\\\\\\\
- printError( \\\\\\\"Requires multishell\\\\\\\" )\\\\\\\
- return\\\\\\\
- end\\\\\\\
- \\\\\\\
- local tArgs = { ... }\\\\\\\
- if #tArgs > 0 then\\\\\\\
- shell.launchProcess( table.unpack( tArgs ) )\\\\\\\
- else\\\\\\\
- shell.launchProcess( \\\\\\\"shell\\\\\\\" )\\\\\\\
- end\\\"\",\
- \"F:cat\",\
- \"\\\"local tArgs = {...}\\\\\\\
- \\\\\\\
- if #tArgs >= 1 then\\\\\\\
- path = shell.resolve(tArgs[1])\\\\\\\
- if fs.isReadOnly(path) then\\\\\\\
- --return\\\\\\\
- end\\\\\\\
- if not fs.exists(path) or fs.isDir(path) then\\\\\\\
- print(\\\\\\\"File does not exist\\\\\\\")\\\\\\\
- else\\\\\\\
- textutils.pagedPrint(kreadfile(path))\\\\\\\
- end\\\\\\\
- else\\\\\\\
- print(\\\\\\\"Filename not specified\\\\\\\")\\\\\\\
- end\\\\\\\
- \\\"\",\
- \"F:df\",\
- \"\\\"local sz = fs.getSize(shell.dir())\\\\\\\
- local fspc = fs.getFreeSpace(shell.dir())\\\\\\\
- print(\\\\\\\"Type: \\\\\\\"..fs.getDrive(shell.dir()))\\\\\\\
- print(\\\\\\\"Size: \\\\\\\", tostring(sz)..\\\\\\\" B\\\\\\\")\\\\\\\
- print(\\\\\\\"Free space: \\\\\\\", tostring(fspc)..\\\\\\\" B\\\\\\\")\\\"\",\
- \"F:dism\",\
- \"\\\"local tArgs = {...}\\\\\\\
- \\\\\\\
- local FFormat = \\\\\\\".odi\\\\\\\"\\\\\\\
- local nFile, nDir, size = 0, 0\\\\\\\
- \\\\\\\
- local function getPath(input)\\\\\\\
- if string.sub(input, 1, 1)==\\\\\\\"/\\\\\\\" then\\\\\\\
- path = input\\\\\\\
- else\\\\\\\
- path=(\\\\\\\"/\\\\\\\" .. shell.dir() .. \\\\\\\"/\\\\\\\" .. input)\\\\\\\
- end\\\\\\\
- return path\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function fopen(path, mode)\\\\\\\
- local f = fs.open(path, mode)\\\\\\\
- if not f then \\\\\\\
- stderr(\\\\\\\"ERROR: Could not open \\\\\\\"..path..\\\\\\\" with mode \\\\\\\\\\\\\\\"\\\\\\\"..mode..\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\")\\\\\\\
- exit()\\\\\\\
- end\\\\\\\
- return f\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function skip(df)\\\\\\\
- local skip = {\\\\\\\"rom\\\\\\\", \\\\\\\"treasure\\\\\\\", \\\\\\\"tmp\\\\\\\"}\\\\\\\
- for _,v in ipairs(skip) do\\\\\\\
- if fs.getName(df) == v then\\\\\\\
- \\\\009 return true\\\\\\\
- \\\\009end\\\\\\\
- end\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function zip(file)\\\\\\\
- print(\\\\\\\"[DISM] Capturing from FS: \\\\\\\".. file)\\\\\\\
- local f = fopen(file, \\\\\\\"r\\\\\\\")\\\\\\\
- local z = textutils.serialize(f.readAll())\\\\\\\
- f.close()\\\\\\\
- return z\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function capture(path)\\\\\\\
- local list = fs.list(path)\\\\\\\
- local array = {}\\\\\\\
- local t, name, d = 0, \\\\\\\"\\\\\\\", 0\\\\\\\
- \\\\\\\
- for i = 2, #list * 2, 2 do\\\\\\\
- t = i/2\\\\\\\
- local tpath = path..\\\\\\\"/\\\\\\\"..list[t]\\\\\\\
- if fs.isDir(tpath) then\\\\\\\
- if not skip(tpath) then\\\\\\\
- name = \\\\\\\"D:\\\\\\\"..list[t]\\\\\\\
- array[i] = capture(tpath)\\\\\\\
- nDir = nDir + 1\\\\\\\
- end\\\\\\\
- else\\\\\\\
- name = \\\\\\\"F:\\\\\\\"..list[t]\\\\\\\
- array[i] = zip(tpath)\\\\\\\
- nFile = nFile + 1\\\\\\\
- end\\\\\\\
- array[i - 1] = name\\\\\\\
- end\\\\\\\
- \\\\\\\
- return textutils.serialize(array)\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function unzip(text, path)\\\\\\\
- print(\\\\\\\"[DISM] Applying to FS: \\\\\\\"..path)\\\\\\\
- local f = fopen(path, \\\\\\\"w\\\\\\\")\\\\\\\
- f.write(textutils.unserialize(text))\\\\\\\
- f.close()\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function apply(text, path)\\\\\\\
- local array = textutils.unserialize(text)\\\\\\\
- local unz, dp\\\\\\\
- local d = 0\\\\\\\
- for i = 2, #array, 2 do\\\\\\\
- if string.sub(array[i-1], 1, 1) == \\\\\\\"D\\\\\\\" then\\\\\\\
- dp = string.sub(array[i-1], 3, #array[i-1])\\\\\\\
- fs.makeDir(path..\\\\\\\"/\\\\\\\"..dp)\\\\\\\
- apply(array[i], path..\\\\\\\"/\\\\\\\"..dp)\\\\\\\
- nDir = nDir + 1\\\\\\\
- elseif string.sub(array[i-1], 1, 1) == \\\\\\\"F\\\\\\\" then\\\\\\\
- local p = string.sub(array[i-1], 3, #array[i-1])\\\\\\\
- unzip(array[i], path..\\\\\\\"/\\\\\\\"..p)\\\\\\\
- nFile = nFile + 1\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function result()\\\\\\\
- print(\\\\\\\"Operation completed.\\\\\\\"\\\\\\\
- ..\\\\\\\"\\\\\\\\n size: \\\\\\\"\\\\\\\
- ..tostring(size).. \\\\\\\" B \\\\\\\"\\\\\\\
- ..tostring(math.floor(size/1024)).. \\\\\\\" KB\\\\\\\"\\\\\\\
- ..\\\\\\\"\\\\\\\\n Files: \\\\\\\".. tostring(nFile)\\\\\\\
- ..\\\\\\\"\\\\\\\\n Folders: \\\\\\\".. tostring(nDir)\\\\\\\
- )\\\\\\\
- end\\\\\\\
- \\\\\\\
- local outStr = \\\\\\\"Deployment Image Servicing and Management \\\\\\\\n\\\\\\\\n\\\\\\\"\\\\\\\
- \\\\\\\
- if tArgs[2] then\\\\\\\
- tArgs[2]=getPath(tArgs[2])\\\\\\\
- end\\\\\\\
- \\\\\\\
- if #tArgs < 3 then \\\\\\\
- outStr = outStr..[[\\\\\\\
- Usage:\\\\\\\
- dism capture <source directory> <output image>\\\\\\\
- OR\\\\\\\
- apply <source image> <target directory>\\\\\\\
- \\\\\\\
- Original code by 1Ridav.\\\\\\\
- Modified for Orbital by minebuild02.\\\\\\\
- ]]\\\\\\\
- end\\\\\\\
- \\\\\\\
- print(outStr)\\\\\\\
- \\\\\\\
- if tArgs[1] == \\\\\\\"capture\\\\\\\" then\\\\\\\
- if fs.exists(tArgs[2]) and fs.isDir(tArgs[2]) then\\\\\\\
- local zipped = capture(shell.resolve(tArgs[2]))\\\\\\\
- local f = fs.open(tArgs[3]..FFormat, \\\\\\\"w\\\\\\\")\\\\\\\
- f.write(zipped)\\\\\\\
- f.close()\\\\\\\
- zipped = nil\\\\\\\
- size = fs.getSize(tArgs[3]..FFormat)\\\\\\\
- result() \\\\\\\
- end\\\\\\\
- \\\\\\\
- elseif tArgs[1] == \\\\\\\"apply\\\\\\\" then\\\\\\\
- local f = fopen(tArgs[2], \\\\\\\"r\\\\\\\")\\\\\\\
- if not fs.exists(tArgs[3]) then \\\\\\\
- fs.makeDir(tArgs[3]) \\\\\\\
- end\\\\\\\
- apply(f.readAll(), tArgs[3])\\\\\\\
- size = fs.getSize(tArgs[2])\\\\\\\
- result()\\\\\\\
- end\\\"\",\
- \"F:fg\",\
- \"\\\"\\\\\\\
- if not shell.launchProcess then\\\\\\\
- printError( \\\\\\\"Requires multishell\\\\\\\" )\\\\\\\
- return\\\\\\\
- end\\\\\\\
- \\\\\\\
- local tArgs = { ... }\\\\\\\
- if #tArgs > 0 then\\\\\\\
- local nTask = shell.launchProcess( table.unpack( tArgs ) )\\\\\\\
- if nTask then\\\\\\\
- shell.setProcessFocus( nTask )\\\\\\\
- end\\\\\\\
- else\\\\\\\
- local nTask = shell.launchProcess( \\\\\\\"shell\\\\\\\" )\\\\\\\
- if nTask then\\\\\\\
- shell.setProcessFocus( nTask )\\\\\\\
- end\\\\\\\
- end\\\"\",\
- \"F:lc\",\
- \"\\\"-- Lua compiler for the Orbital SDK\\\\\\\
- -- Takes the input file and converts it to Lua bytecode\\\\\\\
- \\\\\\\
- local oex_template = \\\\\\\"!LC!\\\\\\\\\\\\\\\\|/%s\\\\\\\\\\\\\\\\|/%s\\\\\\\"\\\\\\\
- \\\\\\\
- local function compileString(s)\\\\\\\
- local func, err = loadstring(s)\\\\\\\
- if func ~= nil then\\\\\\\
- return string.dump(func)\\\\\\\
- else\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function compileFile(p)\\\\\\\
- local func, err = loadstring(kreadfile(p))\\\\\\\
- if func ~= nil then\\\\\\\
- local h = fs.open(p..\\\\\\\".bin\\\\\\\", fs.AF_WRITE)\\\\\\\
- h.write(string.dump(func))\\\\\\\
- h.close()\\\\\\\
- return true\\\\\\\
- else\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local tArgs = {...}\\\\\\\
- \\\\\\\
- if #tArgs >= 1 then\\\\\\\
- path = shell.resolve(tArgs[1])\\\\\\\
- if not fs.exists(path) or fs.isDir(path) then\\\\\\\
- UI.outputInfo(\\\\\\\"lc\\\\\\\", \\\\\\\"file does not exist\\\\\\\")\\\\\\\
- else\\\\\\\
- UI.outputInfo(\\\\\\\"lc\\\\\\\", \\\\\\\"compiling to bytecode\\\\\\\")\\\\\\\
- compileFile(path)\\\\\\\
- end\\\\\\\
- else\\\\\\\
- UI.outputInfo(\\\\\\\"lc\\\\\\\", \\\\\\\"lc <input file> [format]\\\\\\\")\\\\\\\
- end\\\\\\\
- \\\"\",\
- \"F:msh\",\
- \"\\\"\\\\\\\
- local process = process\\\\\\\
- local parentShell = shell\\\\\\\
- local parentTerm = term.current()\\\\\\\
- \\\\\\\
- if process then\\\\\\\
- process.setTitle( process.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
- end\\\\\\\
- \\\\\\\
- local bExit = false\\\\\\\
- local sDir = (parentShell and parentShell.dir()) or \\\\\\\"\\\\\\\"\\\\\\\
- local sPath = (parentShell and parentShell.path()) or \\\\\\\".:/rom/programs\\\\\\\"\\\\\\\
- local tAliases = (parentShell and parentShell.aliases()) or {}\\\\\\\
- local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}\\\\\\\
- local tProgramStack = {}\\\\\\\
- \\\\\\\
- local shell = {}\\\\\\\
- local function createShellEnv( sDir )\\\\\\\
- local tEnv = {}\\\\\\\
- tEnv[ \\\\\\\"shell\\\\\\\" ] = shell\\\\\\\
- tEnv[ \\\\\\\"process\\\\\\\" ] = process\\\\\\\
- \\\\\\\
- local package = {}\\\\\\\
- package.loaded = {\\\\\\\
- _G = _G,\\\\\\\
- bit32 = bit32,\\\\\\\
- coroutine = coroutine,\\\\\\\
- math = math,\\\\\\\
- package = package,\\\\\\\
- string = string,\\\\\\\
- table = table,\\\\\\\
- }\\\\\\\
- package.path = \\\\\\\"?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua\\\\\\\"\\\\\\\
- if turtle then\\\\\\\
- package.path = package.path..\\\\\\\";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua\\\\\\\"\\\\\\\
- elseif command then\\\\\\\
- package.path = package.path..\\\\\\\";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua\\\\\\\"\\\\\\\
- end\\\\\\\
- package.config = \\\\\\\"/\\\\\\\\n;\\\\\\\\n?\\\\\\\\n!\\\\\\\\n-\\\\\\\"\\\\\\\
- package.preload = {}\\\\\\\
- package.loaders = {\\\\\\\
- function( name )\\\\\\\
- if package.preload[name] then\\\\\\\
- return package.preload[name]\\\\\\\
- else\\\\\\\
- return nil, \\\\\\\"no field package.preload['\\\\\\\" .. name .. \\\\\\\"']\\\\\\\"\\\\\\\
- end\\\\\\\
- end,\\\\\\\
- function( name )\\\\\\\
- local fname = string.gsub(name, \\\\\\\"%.\\\\\\\", \\\\\\\"/\\\\\\\")\\\\\\\
- local sError = \\\\\\\"\\\\\\\"\\\\\\\
- for pattern in string.gmatch(package.path, \\\\\\\"[^;]+\\\\\\\") do\\\\\\\
- local sPath = string.gsub(pattern, \\\\\\\"%?\\\\\\\", fname)\\\\\\\
- if sPath:sub(1,1) ~= \\\\\\\"/\\\\\\\" then\\\\\\\
- sPath = fs.combine(sDir, sPath)\\\\\\\
- end\\\\\\\
- if fs.exists(sPath) and not fs.isDir(sPath) then\\\\\\\
- local fnFile, sError = loadfile( sPath, tEnv )\\\\\\\
- if fnFile then\\\\\\\
- return fnFile, sPath\\\\\\\
- else\\\\\\\
- return nil, sError\\\\\\\
- end\\\\\\\
- else\\\\\\\
- if #sError > 0 then\\\\\\\
- sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\"\\\\\\\
- end\\\\\\\
- sError = sError .. \\\\\\\"no file '\\\\\\\" .. sPath .. \\\\\\\"'\\\\\\\"\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return nil, sError\\\\\\\
- end\\\\\\\
- }\\\\\\\
- \\\\\\\
- local sentinel = {}\\\\\\\
- local function require( name )\\\\\\\
- if type( name ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( name ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if package.loaded[name] == sentinel then\\\\\\\
- error(\\\\\\\"Loop detected requiring '\\\\\\\" .. name .. \\\\\\\"'\\\\\\\", 0)\\\\\\\
- end\\\\\\\
- if package.loaded[name] then\\\\\\\
- return package.loaded[name]\\\\\\\
- end\\\\\\\
- \\\\\\\
- local sError = \\\\\\\"Error loading module '\\\\\\\" .. name .. \\\\\\\"':\\\\\\\"\\\\\\\
- for n,searcher in ipairs(package.loaders) do\\\\\\\
- local loader, err = searcher(name)\\\\\\\
- if loader then\\\\\\\
- package.loaded[name] = sentinel\\\\\\\
- local result = loader( err )\\\\\\\
- if result ~= nil then\\\\\\\
- package.loaded[name] = result\\\\\\\
- return result\\\\\\\
- else\\\\\\\
- package.loaded[name] = true\\\\\\\
- return true\\\\\\\
- end\\\\\\\
- else\\\\\\\
- sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\" .. err\\\\\\\
- end\\\\\\\
- end\\\\\\\
- error(sError, 2)\\\\\\\
- end\\\\\\\
- \\\\\\\
- tEnv[\\\\\\\"package\\\\\\\"] = package\\\\\\\
- tEnv[\\\\\\\"require\\\\\\\"] = require\\\\\\\
- \\\\\\\
- return tEnv\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Colours\\\\\\\
- local promptColour, textColour, bgColour\\\\\\\
- if term.isColour() then\\\\\\\
- promptColour = colours.yellow\\\\\\\
- textColour = colours.white\\\\\\\
- bgColour = colours.black\\\\\\\
- else\\\\\\\
- promptColour = colours.white\\\\\\\
- textColour = colours.white\\\\\\\
- bgColour = colours.black\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function run( _sCommand, ... )\\\\\\\
- local sPath = shell.resolveProgram( _sCommand )\\\\\\\
- if sPath ~= nil then\\\\\\\
- tProgramStack[#tProgramStack + 1] = sPath\\\\\\\
- if process then\\\\\\\
- local sTitle = fs.getName( sPath )\\\\\\\
- if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
- sTitle = sTitle:sub(1,-5)\\\\\\\
- end\\\\\\\
- process.setTitle( process.getCurrent(), sTitle )\\\\\\\
- end\\\\\\\
- local sDir = fs.getDir( sPath )\\\\\\\
- local result = os.run( createShellEnv( sDir ), sPath, ... )\\\\\\\
- tProgramStack[#tProgramStack] = nil\\\\\\\
- if process then\\\\\\\
- if #tProgramStack > 0 then\\\\\\\
- local sTitle = fs.getName( tProgramStack[#tProgramStack] )\\\\\\\
- if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
- sTitle = sTitle:sub(1,-5)\\\\\\\
- end\\\\\\\
- process.setTitle( process.getCurrent(), sTitle )\\\\\\\
- else\\\\\\\
- process.setTitle( process.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return result\\\\\\\
- else\\\\\\\
- printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function tokenise( ... )\\\\\\\
- local sLine = table.concat( { ... }, \\\\\\\" \\\\\\\" )\\\\\\\
- local tWords = {}\\\\\\\
- local bQuoted = false\\\\\\\
- for match in string.gmatch( sLine .. \\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\", \\\\\\\"(.-)\\\\\\\\\\\\\\\"\\\\\\\" ) do\\\\\\\
- if bQuoted then\\\\\\\
- table.insert( tWords, match )\\\\\\\
- else\\\\\\\
- for m in string.gmatch( match, \\\\\\\"[^ \\\\\\\\t]+\\\\\\\" ) do\\\\\\\
- table.insert( tWords, m )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- bQuoted = not bQuoted\\\\\\\
- end\\\\\\\
- return tWords\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Install shell API\\\\\\\
- function shell.run( ... )\\\\\\\
- local tWords = tokenise( ... )\\\\\\\
- local sCommand = tWords[1]\\\\\\\
- if sCommand then\\\\\\\
- return run( sCommand, table.unpack( tWords, 2 ) )\\\\\\\
- end\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.exit()\\\\\\\
- bExit = true\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.dir()\\\\\\\
- return sDir\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setDir( _sDir )\\\\\\\
- if type( _sDir ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sDir ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if not fs.isDir( _sDir ) then\\\\\\\
- error( \\\\\\\"Not a directory\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- sDir = _sDir\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.path()\\\\\\\
- return sPath\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setPath( _sPath )\\\\\\\
- if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- sPath = _sPath\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.resolve( _sPath )\\\\\\\
- if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- local sStartChar = string.sub( _sPath, 1, 1 )\\\\\\\
- if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
- return fs.combine( \\\\\\\"\\\\\\\", _sPath )\\\\\\\
- else\\\\\\\
- return fs.combine( sDir, _sPath )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function pathWithExtension( _sPath, _sExt )\\\\\\\
- local nLen = #sPath\\\\\\\
- local sEndChar = string.sub( _sPath, nLen, nLen )\\\\\\\
- -- Remove any trailing slashes so we can add an extension to the path safely\\\\\\\
- if sEndChar == \\\\\\\"/\\\\\\\" or sEndChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
- _sPath = string.sub( _sPath, 1, nLen - 1 )\\\\\\\
- end\\\\\\\
- return _sPath .. \\\\\\\".\\\\\\\" .. _sExt\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.resolveProgram( _sCommand )\\\\\\\
- if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- -- Substitute aliases firsts\\\\\\\
- if tAliases[ _sCommand ] ~= nil then\\\\\\\
- _sCommand = tAliases[ _sCommand ]\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- If the path is a global path, use it directly\\\\\\\
- local sStartChar = string.sub( _sCommand, 1, 1 )\\\\\\\
- if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
- local sPath = fs.combine( \\\\\\\"\\\\\\\", _sCommand )\\\\\\\
- if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
- return sPath\\\\\\\
- else\\\\\\\
- local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
- if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
- return sPathLua\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Otherwise, look on the path variable\\\\\\\
- for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
- sPath = fs.combine( shell.resolve( sPath ), _sCommand )\\\\\\\
- if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
- return sPath\\\\\\\
- else\\\\\\\
- local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
- if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
- return sPathLua\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Not found\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.programs( _bIncludeHidden )\\\\\\\
- local tItems = {}\\\\\\\
- \\\\\\\
- -- Add programs from the path\\\\\\\
- for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
- sPath = shell.resolve( sPath )\\\\\\\
- if fs.isDir( sPath ) then\\\\\\\
- local tList = fs.list( sPath )\\\\\\\
- for n=1,#tList do\\\\\\\
- local sFile = tList[n]\\\\\\\
- if not fs.isDir( fs.combine( sPath, sFile ) ) and\\\\\\\
- (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= \\\\\\\".\\\\\\\") then\\\\\\\
- if #sFile > 4 and sFile:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
- sFile = sFile:sub(1,-5)\\\\\\\
- end\\\\\\\
- tItems[ sFile ] = true\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end \\\\\\\
- \\\\\\\
- -- Sort and return\\\\\\\
- local tItemList = {}\\\\\\\
- for sItem, b in pairs( tItems ) do\\\\\\\
- table.insert( tItemList, sItem )\\\\\\\
- end\\\\\\\
- table.sort( tItemList )\\\\\\\
- return tItemList\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function completeProgram( sLine )\\\\\\\
- if #sLine > 0 and string.sub( sLine, 1, 1 ) == \\\\\\\"/\\\\\\\" then\\\\\\\
- -- Add programs from the root\\\\\\\
- return fs.complete( sLine, \\\\\\\"\\\\\\\", true, false )\\\\\\\
- \\\\\\\
- else\\\\\\\
- local tResults = {}\\\\\\\
- local tSeen = {}\\\\\\\
- \\\\\\\
- -- Add aliases\\\\\\\
- for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
- if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then\\\\\\\
- local sResult = string.sub( sAlias, #sLine + 1 )\\\\\\\
- if not tSeen[ sResult ] then\\\\\\\
- table.insert( tResults, sResult )\\\\\\\
- tSeen[ sResult ] = true\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Add programs from the path\\\\\\\
- local tPrograms = shell.programs()\\\\\\\
- for n=1,#tPrograms do\\\\\\\
- local sProgram = tPrograms[n]\\\\\\\
- if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then\\\\\\\
- local sResult = string.sub( sProgram, #sLine + 1 )\\\\\\\
- if not tSeen[ sResult ] then\\\\\\\
- table.insert( tResults, sResult )\\\\\\\
- tSeen[ sResult ] = true\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Sort and return\\\\\\\
- table.sort( tResults )\\\\\\\
- return tResults\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )\\\\\\\
- local tInfo = tCompletionInfo[ sProgram ]\\\\\\\
- if tInfo then\\\\\\\
- return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.complete( sLine )\\\\\\\
- if type( sLine ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sLine ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if #sLine > 0 then\\\\\\\
- local tWords = tokenise( sLine )\\\\\\\
- local nIndex = #tWords\\\\\\\
- if string.sub( sLine, #sLine, #sLine ) == \\\\\\\" \\\\\\\" then\\\\\\\
- nIndex = nIndex + 1\\\\\\\
- end\\\\\\\
- if nIndex == 1 then\\\\\\\
- local sBit = tWords[1] or \\\\\\\"\\\\\\\"\\\\\\\
- local sPath = shell.resolveProgram( sBit )\\\\\\\
- if tCompletionInfo[ sPath ] then\\\\\\\
- return { \\\\\\\" \\\\\\\" }\\\\\\\
- else\\\\\\\
- local tResults = completeProgram( sBit )\\\\\\\
- for n=1,#tResults do\\\\\\\
- local sResult = tResults[n]\\\\\\\
- local sPath = shell.resolveProgram( sBit .. sResult )\\\\\\\
- if tCompletionInfo[ sPath ] then\\\\\\\
- tResults[n] = sResult .. \\\\\\\" \\\\\\\"\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return tResults\\\\\\\
- end\\\\\\\
- \\\\\\\
- elseif nIndex > 1 then\\\\\\\
- local sPath = shell.resolveProgram( tWords[1] )\\\\\\\
- local sPart = tWords[nIndex] or \\\\\\\"\\\\\\\"\\\\\\\
- local tPreviousParts = tWords\\\\\\\
- tPreviousParts[nIndex] = nil\\\\\\\
- return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )\\\\\\\
- \\\\\\\
- end\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.completeProgram( sProgram )\\\\\\\
- if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- return completeProgram( sProgram )\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setCompletionFunction( sProgram, fnComplete )\\\\\\\
- if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if type( fnComplete ) ~= \\\\\\\"function\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #2 (expected function, got \\\\\\\" .. type( fnComplete ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- tCompletionInfo[ sProgram ] = {\\\\\\\
- fnComplete = fnComplete\\\\\\\
- }\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.getCompletionInfo()\\\\\\\
- return tCompletionInfo\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.getRunningProgram()\\\\\\\
- if #tProgramStack > 0 then\\\\\\\
- return tProgramStack[#tProgramStack]\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setAlias( _sCommand, _sProgram )\\\\\\\
- if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if type( _sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( _sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- tAliases[ _sCommand ] = _sProgram\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.clearAlias( _sCommand )\\\\\\\
- if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- tAliases[ _sCommand ] = nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.aliases()\\\\\\\
- -- Copy aliases\\\\\\\
- local tCopy = {}\\\\\\\
- for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
- tCopy[sAlias] = sCommand\\\\\\\
- end\\\\\\\
- return tCopy\\\\\\\
- end\\\\\\\
- \\\\\\\
- if process then\\\\\\\
- function shell.launchProcess( ... )\\\\\\\
- local tWords = tokenise( ... )\\\\\\\
- local sCommand = tWords[1]\\\\\\\
- if sCommand then\\\\\\\
- local sPath = shell.resolveProgram( sCommand )\\\\\\\
- if sPath == \\\\\\\"system/bin/sh\\\\\\\" then\\\\\\\
- return process.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), sPath, table.unpack( tWords, 2 ) )\\\\\\\
- elseif sPath ~= nil then\\\\\\\
- return process.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), \\\\\\\"rom/programs/shell.lua\\\\\\\", sCommand, table.unpack( tWords, 2 ) )\\\\\\\
- else\\\\\\\
- printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setProcessFocus( nID )\\\\\\\
- if type( nID ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( nID ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- process.setFocus( nID )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local tArgs = { ... }\\\\\\\
- if #tArgs > 0 then\\\\\\\
- -- \\\\\\\"shell x y z\\\\\\\"\\\\\\\
- -- Run the program specified on the commandline\\\\\\\
- shell.run( ... )\\\\\\\
- \\\\\\\
- else\\\\\\\
- -- \\\\\\\"shell\\\\\\\"\\\\\\\
- -- Print the header\\\\\\\
- term.setBackgroundColor( bgColour )\\\\\\\
- term.setTextColour( promptColour )\\\\\\\
- print( os.version() )\\\\\\\
- term.setTextColour( textColour )\\\\\\\
- \\\\\\\
- -- Run the startup program\\\\\\\
- if parentShell == nil then\\\\\\\
- shell.run( \\\\\\\"/rom/startup.lua\\\\\\\" )\\\\\\\
- end\\\\\\\
- sPath = sPath..\\\\\\\":/bin\\\\\\\"\\\\\\\
- \\\\\\\
- -- Read commands and execute them\\\\\\\
- local tCommandHistory = {}\\\\\\\
- while not bExit do\\\\\\\
- term.redirect( parentTerm )\\\\\\\
- term.setBackgroundColor( bgColour )\\\\\\\
- term.setTextColour( promptColour )\\\\\\\
- write( shell.dir() .. \\\\\\\"> \\\\\\\" )\\\\\\\
- term.setTextColour( textColour )\\\\\\\
- \\\\\\\
- \\\\\\\
- local sLine\\\\\\\
- if settings.get( \\\\\\\"shell.autocomplete\\\\\\\" ) then\\\\\\\
- sLine = read( nil, tCommandHistory, shell.complete )\\\\\\\
- else\\\\\\\
- sLine = read( nil, tCommandHistory )\\\\\\\
- end\\\\\\\
- if sLine:match(\\\\\\\"%S\\\\\\\") and tCommandHistory[#tCommandHistory] ~= sLine then\\\\\\\
- table.insert( tCommandHistory, sLine )\\\\\\\
- end\\\\\\\
- shell.run( sLine )\\\\\\\
- end\\\\\\\
- end\\\"\",\
- \"F:sh\",\
- \"\\\"\\\\\\\
- local multishell = multishell\\\\\\\
- local parentShell = shell\\\\\\\
- local parentTerm = term.current()\\\\\\\
- \\\\\\\
- if multishell then\\\\\\\
- multishell.setTitle( multishell.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
- end\\\\\\\
- \\\\\\\
- local bExit = false\\\\\\\
- local sDir = (parentShell and parentShell.dir()) or \\\\\\\"\\\\\\\"\\\\\\\
- local sPath = (parentShell and parentShell.path()) or \\\\\\\".:/rom/programs\\\\\\\"\\\\\\\
- local tAliases = (parentShell and parentShell.aliases()) or {}\\\\\\\
- local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}\\\\\\\
- local tProgramStack = {}\\\\\\\
- \\\\\\\
- local shell = {}\\\\\\\
- local function createShellEnv( sDir )\\\\\\\
- local tEnv = {}\\\\\\\
- tEnv[ \\\\\\\"shell\\\\\\\" ] = shell\\\\\\\
- tEnv[ \\\\\\\"multishell\\\\\\\" ] = multishell\\\\\\\
- \\\\\\\
- local package = {}\\\\\\\
- package.loaded = {\\\\\\\
- _G = _G,\\\\\\\
- bit32 = bit32,\\\\\\\
- coroutine = coroutine,\\\\\\\
- math = math,\\\\\\\
- package = package,\\\\\\\
- string = string,\\\\\\\
- table = table,\\\\\\\
- }\\\\\\\
- \\\\009package.standard_libraries = {}\\\\\\\
- \\\\009package.standard_libraries.stdlib = \\\\\\\"/lib/libstdlua.2.so\\\\\\\"\\\\\\\
- \\\\009package.standard_libraries.UI = \\\\\\\"/lib/libuser.2.so\\\\\\\"\\\\\\\
- \\\\009package.standard_libraries.debug = \\\\\\\"/lib/libdebug.1.so\\\\\\\"\\\\\\\
- \\\\009package.standard_libraries.cryptlib = \\\\\\\"/lib/libcrypt.1.so\\\\\\\"\\\\\\\
- \\\\009package.standard_libraries.dism = \\\\\\\"/lib/libdism.1.so\\\\\\\"\\\\\\\
- package.path = \\\\\\\"?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua\\\\\\\"\\\\\\\
- if turtle then\\\\\\\
- package.path = package.path..\\\\\\\";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua\\\\\\\"\\\\\\\
- elseif command then\\\\\\\
- package.path = package.path..\\\\\\\";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua\\\\\\\"\\\\\\\
- end\\\\\\\
- package.config = \\\\\\\"/\\\\\\\\n;\\\\\\\\n?\\\\\\\\n!\\\\\\\\n-\\\\\\\"\\\\\\\
- package.preload = {}\\\\\\\
- package.loaders = {\\\\\\\
- function( name )\\\\\\\
- if package.preload[name] then\\\\\\\
- return package.preload[name]\\\\\\\
- else\\\\\\\
- return nil, \\\\\\\"no field package.preload['\\\\\\\" .. name .. \\\\\\\"']\\\\\\\"\\\\\\\
- end\\\\\\\
- end,\\\\\\\
- function( name )\\\\\\\
- local fname = string.gsub(name, \\\\\\\"%.\\\\\\\", \\\\\\\"/\\\\\\\")\\\\\\\
- local sError = \\\\\\\"\\\\\\\"\\\\\\\
- for pattern in string.gmatch(package.path, \\\\\\\"[^;]+\\\\\\\") do\\\\\\\
- local sPath = string.gsub(pattern, \\\\\\\"%?\\\\\\\", fname)\\\\\\\
- if sPath:sub(1,1) ~= \\\\\\\"/\\\\\\\" then\\\\\\\
- sPath = fs.combine(sDir, sPath)\\\\\\\
- end\\\\\\\
- if fs.exists(sPath) and not fs.isDir(sPath) then\\\\\\\
- local fnFile, sError = loadfile( sPath, tEnv )\\\\\\\
- if fnFile then\\\\\\\
- return fnFile, sPath\\\\\\\
- else\\\\\\\
- return nil, sError\\\\\\\
- end\\\\\\\
- else\\\\\\\
- if #sError > 0 then\\\\\\\
- sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\"\\\\\\\
- end\\\\\\\
- sError = sError .. \\\\\\\"no file '\\\\\\\" .. sPath .. \\\\\\\"'\\\\\\\"\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return nil, sError\\\\\\\
- end\\\\\\\
- }\\\\\\\
- \\\\\\\
- local sentinel = {}\\\\\\\
- local function require( name )\\\\\\\
- if type( name ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( name ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if package.loaded[name] == sentinel then\\\\\\\
- error(\\\\\\\"Loop detected requiring '\\\\\\\" .. name .. \\\\\\\"'\\\\\\\", 0)\\\\\\\
- end\\\\\\\
- if package.loaded[name] then\\\\\\\
- return package.loaded[name]\\\\\\\
- end\\\\\\\
- \\\\\\\
- local sError = \\\\\\\"Error loading module '\\\\\\\" .. name .. \\\\\\\"':\\\\\\\"\\\\\\\
- for n,searcher in ipairs(package.loaders) do\\\\\\\
- local loader, err = searcher(name)\\\\\\\
- if loader then\\\\\\\
- package.loaded[name] = sentinel\\\\\\\
- local result = loader( err )\\\\\\\
- if result ~= nil then\\\\\\\
- package.loaded[name] = result\\\\\\\
- return result\\\\\\\
- else\\\\\\\
- package.loaded[name] = true\\\\\\\
- return true\\\\\\\
- end\\\\\\\
- else\\\\\\\
- sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\" .. err\\\\\\\
- end\\\\\\\
- end\\\\\\\
- error(sError, 2)\\\\\\\
- end\\\\\\\
- \\\\\\\
- tEnv[\\\\\\\"package\\\\\\\"] = package\\\\\\\
- tEnv[\\\\\\\"require\\\\\\\"] = require\\\\\\\
- \\\\\\\
- return tEnv\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Colours\\\\\\\
- local promptColour, textColour, bgColour\\\\\\\
- if term.isColour() then\\\\\\\
- promptColour = colours.yellow\\\\\\\
- textColour = colours.white\\\\\\\
- bgColour = colours.black\\\\\\\
- else\\\\\\\
- promptColour = colours.white\\\\\\\
- textColour = colours.white\\\\\\\
- bgColour = colours.black\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function run( _sCommand, ... )\\\\\\\
- local sPath = shell.resolveProgram( _sCommand )\\\\\\\
- if sPath ~= nil then\\\\\\\
- tProgramStack[#tProgramStack + 1] = sPath\\\\\\\
- if multishell then\\\\\\\
- local sTitle = fs.getName( sPath )\\\\\\\
- if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
- sTitle = sTitle:sub(1,-5)\\\\\\\
- end\\\\\\\
- multishell.setTitle( multishell.getCurrent(), sTitle )\\\\\\\
- end\\\\\\\
- local sDir = fs.getDir( sPath )\\\\\\\
- local result = os.run( createShellEnv( sDir ), sPath, ... )\\\\\\\
- tProgramStack[#tProgramStack] = nil\\\\\\\
- if multishell then\\\\\\\
- if #tProgramStack > 0 then\\\\\\\
- local sTitle = fs.getName( tProgramStack[#tProgramStack] )\\\\\\\
- if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
- sTitle = sTitle:sub(1,-5)\\\\\\\
- end\\\\\\\
- multishell.setTitle( multishell.getCurrent(), sTitle )\\\\\\\
- else\\\\\\\
- multishell.setTitle( multishell.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return result\\\\\\\
- else\\\\\\\
- printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function tokenise( ... )\\\\\\\
- local sLine = table.concat( { ... }, \\\\\\\" \\\\\\\" )\\\\\\\
- local tWords = {}\\\\\\\
- local bQuoted = false\\\\\\\
- for match in string.gmatch( sLine .. \\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\", \\\\\\\"(.-)\\\\\\\\\\\\\\\"\\\\\\\" ) do\\\\\\\
- if bQuoted then\\\\\\\
- table.insert( tWords, match )\\\\\\\
- else\\\\\\\
- for m in string.gmatch( match, \\\\\\\"[^ \\\\\\\\t]+\\\\\\\" ) do\\\\\\\
- table.insert( tWords, m )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- bQuoted = not bQuoted\\\\\\\
- end\\\\\\\
- return tWords\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Install shell API\\\\\\\
- function shell.run( ... )\\\\\\\
- local tWords = tokenise( ... )\\\\\\\
- local sCommand = tWords[1]\\\\\\\
- if sCommand then\\\\\\\
- return run( sCommand, table.unpack( tWords, 2 ) )\\\\\\\
- end\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.exit()\\\\\\\
- bExit = true\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.dir()\\\\\\\
- return sDir\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setDir( _sDir )\\\\\\\
- if type( _sDir ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sDir ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if not fs.isDir( _sDir ) then\\\\\\\
- error( \\\\\\\"Not a directory\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- sDir = _sDir\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.path()\\\\\\\
- return sPath\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setPath( _sPath )\\\\\\\
- if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- sPath = _sPath\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.resolve( _sPath )\\\\\\\
- if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- local sStartChar = string.sub( _sPath, 1, 1 )\\\\\\\
- if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
- return fs.combine( \\\\\\\"\\\\\\\", _sPath )\\\\\\\
- else\\\\\\\
- return fs.combine( sDir, _sPath )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function pathWithExtension( _sPath, _sExt )\\\\\\\
- local nLen = #sPath\\\\\\\
- local sEndChar = string.sub( _sPath, nLen, nLen )\\\\\\\
- -- Remove any trailing slashes so we can add an extension to the path safely\\\\\\\
- if sEndChar == \\\\\\\"/\\\\\\\" or sEndChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
- _sPath = string.sub( _sPath, 1, nLen - 1 )\\\\\\\
- end\\\\\\\
- return _sPath .. \\\\\\\".\\\\\\\" .. _sExt\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.resolveProgram( _sCommand )\\\\\\\
- if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- -- Substitute aliases firsts\\\\\\\
- if tAliases[ _sCommand ] ~= nil then\\\\\\\
- _sCommand = tAliases[ _sCommand ]\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- If the path is a global path, use it directly\\\\\\\
- local sStartChar = string.sub( _sCommand, 1, 1 )\\\\\\\
- if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
- local sPath = fs.combine( \\\\\\\"\\\\\\\", _sCommand )\\\\\\\
- if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
- return sPath\\\\\\\
- else\\\\\\\
- local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
- if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
- return sPathLua\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Otherwise, look on the path variable\\\\\\\
- for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
- sPath = fs.combine( shell.resolve( sPath ), _sCommand )\\\\\\\
- if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
- return sPath\\\\\\\
- else\\\\\\\
- local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
- if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
- return sPathLua\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Not found\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.programs( _bIncludeHidden )\\\\\\\
- local tItems = {}\\\\\\\
- \\\\\\\
- -- Add programs from the path\\\\\\\
- for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
- sPath = shell.resolve( sPath )\\\\\\\
- if fs.isDir( sPath ) then\\\\\\\
- local tList = fs.list( sPath )\\\\\\\
- for n=1,#tList do\\\\\\\
- local sFile = tList[n]\\\\\\\
- if not fs.isDir( fs.combine( sPath, sFile ) ) and\\\\\\\
- (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= \\\\\\\".\\\\\\\") then\\\\\\\
- if #sFile > 4 and sFile:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
- sFile = sFile:sub(1,-5)\\\\\\\
- end\\\\\\\
- tItems[ sFile ] = true\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end \\\\\\\
- \\\\\\\
- -- Sort and return\\\\\\\
- local tItemList = {}\\\\\\\
- for sItem, b in pairs( tItems ) do\\\\\\\
- table.insert( tItemList, sItem )\\\\\\\
- end\\\\\\\
- table.sort( tItemList )\\\\\\\
- return tItemList\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function completeProgram( sLine )\\\\\\\
- if #sLine > 0 and string.sub( sLine, 1, 1 ) == \\\\\\\"/\\\\\\\" then\\\\\\\
- -- Add programs from the root\\\\\\\
- return fs.complete( sLine, \\\\\\\"\\\\\\\", true, false )\\\\\\\
- \\\\\\\
- else\\\\\\\
- local tResults = {}\\\\\\\
- local tSeen = {}\\\\\\\
- \\\\\\\
- -- Add aliases\\\\\\\
- for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
- if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then\\\\\\\
- local sResult = string.sub( sAlias, #sLine + 1 )\\\\\\\
- if not tSeen[ sResult ] then\\\\\\\
- table.insert( tResults, sResult )\\\\\\\
- tSeen[ sResult ] = true\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Add programs from the path\\\\\\\
- local tPrograms = shell.programs()\\\\\\\
- for n=1,#tPrograms do\\\\\\\
- local sProgram = tPrograms[n]\\\\\\\
- if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then\\\\\\\
- local sResult = string.sub( sProgram, #sLine + 1 )\\\\\\\
- if not tSeen[ sResult ] then\\\\\\\
- table.insert( tResults, sResult )\\\\\\\
- tSeen[ sResult ] = true\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Sort and return\\\\\\\
- table.sort( tResults )\\\\\\\
- return tResults\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )\\\\\\\
- local tInfo = tCompletionInfo[ sProgram ]\\\\\\\
- if tInfo then\\\\\\\
- return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.complete( sLine )\\\\\\\
- if type( sLine ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sLine ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if #sLine > 0 then\\\\\\\
- local tWords = tokenise( sLine )\\\\\\\
- local nIndex = #tWords\\\\\\\
- if string.sub( sLine, #sLine, #sLine ) == \\\\\\\" \\\\\\\" then\\\\\\\
- nIndex = nIndex + 1\\\\\\\
- end\\\\\\\
- if nIndex == 1 then\\\\\\\
- local sBit = tWords[1] or \\\\\\\"\\\\\\\"\\\\\\\
- local sPath = shell.resolveProgram( sBit )\\\\\\\
- if tCompletionInfo[ sPath ] then\\\\\\\
- return { \\\\\\\" \\\\\\\" }\\\\\\\
- else\\\\\\\
- local tResults = completeProgram( sBit )\\\\\\\
- for n=1,#tResults do\\\\\\\
- local sResult = tResults[n]\\\\\\\
- local sPath = shell.resolveProgram( sBit .. sResult )\\\\\\\
- if tCompletionInfo[ sPath ] then\\\\\\\
- tResults[n] = sResult .. \\\\\\\" \\\\\\\"\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return tResults\\\\\\\
- end\\\\\\\
- \\\\\\\
- elseif nIndex > 1 then\\\\\\\
- local sPath = shell.resolveProgram( tWords[1] )\\\\\\\
- local sPart = tWords[nIndex] or \\\\\\\"\\\\\\\"\\\\\\\
- local tPreviousParts = tWords\\\\\\\
- tPreviousParts[nIndex] = nil\\\\\\\
- return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )\\\\\\\
- \\\\\\\
- end\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.completeProgram( sProgram )\\\\\\\
- if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- return completeProgram( sProgram )\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setCompletionFunction( sProgram, fnComplete )\\\\\\\
- if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if type( fnComplete ) ~= \\\\\\\"function\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #2 (expected function, got \\\\\\\" .. type( fnComplete ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- tCompletionInfo[ sProgram ] = {\\\\\\\
- fnComplete = fnComplete\\\\\\\
- }\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.getCompletionInfo()\\\\\\\
- return tCompletionInfo\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.getRunningProgram()\\\\\\\
- if #tProgramStack > 0 then\\\\\\\
- return tProgramStack[#tProgramStack]\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.setAlias( _sCommand, _sProgram )\\\\\\\
- if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if type( _sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( _sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- tAliases[ _sCommand ] = _sProgram\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.clearAlias( _sCommand )\\\\\\\
- if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- tAliases[ _sCommand ] = nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.aliases()\\\\\\\
- -- Copy aliases\\\\\\\
- local tCopy = {}\\\\\\\
- for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
- tCopy[sAlias] = sCommand\\\\\\\
- end\\\\\\\
- return tCopy\\\\\\\
- end\\\\\\\
- \\\\\\\
- if multishell then\\\\\\\
- function shell.openTab( ... )\\\\\\\
- local tWords = tokenise( ... )\\\\\\\
- local sCommand = tWords[1]\\\\\\\
- if sCommand then\\\\\\\
- local sPath = shell.resolveProgram( sCommand )\\\\\\\
- if sPath == \\\\\\\"rom/programs/shell.lua\\\\\\\" then\\\\\\\
- return multishell.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), sPath, table.unpack( tWords, 2 ) )\\\\\\\
- elseif sPath ~= nil then\\\\\\\
- return multishell.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), \\\\\\\"rom/programs/shell.lua\\\\\\\", sCommand, table.unpack( tWords, 2 ) )\\\\\\\
- else\\\\\\\
- printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.switchTab( nID )\\\\\\\
- if type( nID ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( nID ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- multishell.setFocus( nID )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function shell.executeScript(path)\\\\\\\
- if not fs.exists(path) or fs.isDir(path) then\\\\\\\
- return \\\\\\\"file does not exist\\\\\\\"\\\\\\\
- else\\\\\\\
- local t = kernel.iterateFileLines(path)\\\\\\\
- if t[1] == \\\\\\\"@ #handler /system/bin/sh\\\\\\\" then\\\\\\\
- for _,cmd in pairs(t) do\\\\\\\
- shell.run(cmd)\\\\\\\
- end\\\\\\\
- else\\\\\\\
- return \\\\\\\"script header is missing or corrupt\\\\\\\" \\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local tArgs = { ... }\\\\\\\
- if #tArgs > 0 then\\\\\\\
- -- \\\\\\\"shell x y z\\\\\\\"\\\\\\\
- -- Run the program specified on the commandline\\\\\\\
- shell.run( ... )\\\\\\\
- \\\\\\\
- else\\\\\\\
- -- \\\\\\\"shell\\\\\\\"\\\\\\\
- -- Print the header\\\\\\\
- term.setBackgroundColor( bgColour )\\\\\\\
- term.setTextColour( promptColour )\\\\\\\
- print( os.version() )\\\\\\\
- term.setTextColour( textColour )\\\\\\\
- \\\\\\\
- -- Run the startup program\\\\\\\
- if parentShell == nil then\\\\\\\
- shell.run( \\\\\\\"/rom/startup.lua\\\\\\\" )\\\\\\\
- end\\\\\\\
- sPath = sPath..\\\\\\\":/bin\\\\\\\"\\\\\\\
- \\\\\\\
- -- Read commands and execute them\\\\\\\
- local tCommandHistory = {}\\\\\\\
- while not bExit do\\\\\\\
- term.redirect( parentTerm )\\\\\\\
- term.setBackgroundColor( bgColour )\\\\\\\
- term.setTextColour( promptColour )\\\\\\\
- \\\\009\\\\009if __DEBUG then\\\\\\\
- stdout( \\\\\\\"/\\\\\\\" .. shell.dir() .. \\\\\\\" # \\\\\\\" )\\\\\\\
- \\\\009\\\\009else\\\\\\\
- stdout( \\\\\\\"/\\\\\\\" .. shell.dir() .. \\\\\\\" $ \\\\\\\" )\\\\\\\
- \\\\009\\\\009end\\\\\\\
- term.setTextColour( textColour )\\\\\\\
- \\\\\\\
- \\\\\\\
- local sLine\\\\\\\
- sLine = read( nil, tCommandHistory, shell.complete )\\\\\\\
- if sLine:match(\\\\\\\"%S\\\\\\\") and tCommandHistory[#tCommandHistory] ~= sLine then\\\\\\\
- table.insert( tCommandHistory, sLine )\\\\\\\
- end\\\\\\\
- shell.run( sLine )\\\\\\\
- end\\\\\\\
- end\\\"\",\
- \"F:systeminfo\",\
- \"\\\"print(os.version())\\\\\\\
- print(\\\\\\\"Path:\\\\\\\" shell.path())\\\\\\\
- print(\\\\\\\"ID \\\\\\\"..os.getComputerID() or \\\\\\\"N/A\\\\\\\")\\\\\\\
- print(\\\\\\\"Computer labeled as \\\\\\\"..os.getComputerLabel() or \\\\\\\"N/A\\\\\\\")\\\"\",\
- \"F:tree\",\
- \"\\\"-- Context: http://www.computercraft.info/forums2/index.php?/topic/44-request-windows-tree-command/\\\\\\\
- \\\\\\\
- local tArgs = { ... }\\\\\\\
- local currentPath = shell.resolve(\\\\\\\".\\\\\\\")\\\\\\\
- local lineCounter = 0\\\\\\\
- local pageFlip = false\\\\\\\
- local askingForHelp = false\\\\\\\
- \\\\\\\
- --[[ Process command line arguments ]]\\\\\\\
- if #tArgs > 1 then -- More than one argument.\\\\\\\
- if ( tArgs[1] == string.lower( \\\\\\\"-m\\\\\\\" ) ) or ( tArgs[1] == string.lower( \\\\\\\"-more\\\\\\\" ) ) then\\\\\\\
- pageFlip = true\\\\\\\
- currentPath = shell.resolve( tArgs[2] )\\\\\\\
- elseif ( tArgs[2] == string.lower( \\\\\\\"-m\\\\\\\" ) ) or ( tArgs[2] == string.lower( \\\\\\\"-more\\\\\\\" ) ) then\\\\\\\
- pageFlip = true\\\\\\\
- currentPath = shell.resolve( tArgs[1] )\\\\\\\
- else\\\\\\\
- currentPath = shell.resolve( tArgs[1] )\\\\\\\
- end\\\\\\\
- else -- Only one argument.\\\\\\\
- if ( tArgs[1] == string.lower( \\\\\\\"-h\\\\\\\" ) ) or ( tArgs[1] == string.lower( \\\\\\\"-help\\\\\\\" ) ) then\\\\\\\
- askingForHelp = true\\\\\\\
- elseif tArgs[1] ~= nil then\\\\\\\
- currentPath = shell.resolve( tArgs[1] )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function printUsage()\\\\\\\
- print( \\\\\\\"Usage: tree [-more] [-help] [<DIRECTORY>]\\\\\\\\n\\\\\\\" )\\\\\\\
- \\\\\\\
- print( \\\\\\\"-m or -more Enable page flipping.\\\\\\\" )\\\\\\\
- print( \\\\\\\"-h or -help Show this help.\\\\\\\" )\\\\\\\
- print( \\\\\\\"<DIRECTORY> Name of the directory.\\\\\\\" )\\\\\\\
- print( \\\\\\\" (Default is current directory)\\\\\\\" )\\\\\\\
- \\\\009print( \\\\\\\"Made by Espen.\\\\\\\")\\\\\\\
- end\\\\\\\
- \\\\\\\
- function listDir( path, prefix )\\\\\\\
- if path == \\\\\\\"\\\\\\\" then path = \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" end -- Path of execution.\\\\\\\
- \\\\\\\
- -- Iterate through every element (file or dir) in the path.\\\\\\\
- for k, v in pairs( fs.list( path ) ) do\\\\\\\
- ---[[ PAGE-FLIP\\\\\\\
- if pageFlip then\\\\\\\
- lineCounter = lineCounter + 1\\\\\\\
- if lineCounter >= 17 then\\\\\\\
- write(\\\\\\\"Press any key to continue\\\\\\\")\\\\\\\
- read()\\\\\\\
- term.setCursorPos( 1, 1 )\\\\\\\
- term.clear()\\\\\\\
- lineCounter = 0\\\\\\\
- end\\\\\\\
- end\\\\\\\
- --]]\\\\\\\
- -- Print file/dir name.\\\\\\\
- print( prefix..\\\\\\\"-- \\\\\\\"..v )\\\\\\\
- -- Traverse next directory, if any.\\\\\\\
- local nextDir = path..\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\"..v\\\\\\\
- if fs.isDir( nextDir ) then listDir( nextDir, prefix..\\\\\\\" |\\\\\\\" ) end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- if askingForHelp then\\\\\\\
- printUsage()\\\\\\\
- else\\\\\\\
- print( \\\\\\\"Listing directory: \\\\\\\"..currentPath )\\\\\\\
- listDir( currentPath, \\\\\\\"|\\\\\\\" )\\\\\\\
- end\\\"\",\
- \"F:tty\",\
- \"\\\"local x, y = term.getSize()\\\\\\\
- print(\\\\\\\"terminal object size is \\\\\\\"..tostring(x)..\\\\\\\"x\\\\\\\"..tostring(y))\\\\\\\
- \\\"\",\
- }",
- "D:boot",
- "{\
- \"D:esi\",\
- \"{\\\
- \\\"F:config.dat\\\",\\\
- \\\"\\\\\\\"{\\\\\\\\\\\\\\\
- script = \\\\\\\\\\\\\\\"Orbital\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\
- }\\\\\\\"\\\",\\\
- \\\"D:drivers\\\",\\\
- \\\"{\\\\\\\
- \\\\\\\"F:dmouse.sys\\\\\\\",\\\\\\\
- \\\\\\\"\\\\\\\\\\\\\\\"local function handleRegionMouseInput(xx, yy, x1, x2, y1, y2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- y0 = y2 or y1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if (xx >= x1 and xx <= x2) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if (yy >= y1 and yy <= y0) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- elseif yy == y1 or yy == y0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return false\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __declare_api(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"peripheral\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"handleMouseInput\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", function(...)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local tArgs = {...}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if #tArgs < 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- error(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"usage: handleMouseInput(<table describing the minX, maxX, minY and maxY positions of a button>, [more tables like this]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- sleep(0.01)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a, b, x, y = os.pullEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"mouse_click\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- sleep(0.01)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for k,v in ipairs(tArgs) do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local minX = v[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\009local maxX = v[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\009local minY = v[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\009local maxY = v[4] or v[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if handleRegionMouseInput(x, y, minX, maxX, minY, maxY) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
- \\\\\\\"F:dvirt.sys\\\\\\\",\\\\\\\
- \\\\\\\"\\\\\\\\\\\\\\\"-- Guest Virtualization Driver for Orbital.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Supports CCEmuX.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if ccemux then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ccemux.attach(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"top\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"wireless_modem\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if __DEBUG then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"__DEBUG_REMOTE\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", __kstruct({true}))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return false, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Compatible hypervisor not detected\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
- \\\\\\\"F:ecc.sys\\\\\\\",\\\\\\\
- \\\\\\\"\\\\\\\\\\\\\\\"-- Elliptic Curve Cryptography in Computercraft\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local byteTableMT = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __tostring = function(a) return string.char(unpack(a)) end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __index = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- toHex = function(self, s) return (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"%02x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):rep(#self):format(unpack(self)) end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isEqual = function(self, t)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(t) ~= \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then return false end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if #self ~= #t then return false end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ret = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, #self do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ret = bit32.bor(ret, bit32.bxor(self[i], t[i]))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return ret == 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- SHA-256, HMAC and PBKDF2 functions in ComputerCraft\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- By Anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- For help and details, you can PM me on the CC forums\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- You may use this code in your projects without asking me, as long as credit is given and this header is kept intact\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- http://www.computercraft.info/forums2/index.php?/user/12870-anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- http://pastebin.com/6UV4qfNF\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Last update: October 10, 2017\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local sha256 = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local mod32 = 2^32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local band = bit32 and bit32.band or bit.band\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local bnot = bit32 and bit32.bnot or bit.bnot\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local bxor = bit32 and bit32.bxor or bit.bxor\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local blshift = bit32 and bit32.lshift or bit.blshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local upack = unpack\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function rrotate(n, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local s = n/(2^b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local f = s%1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return (s-f) + f*mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function brshift(int, by) -- Thanks bit32 for bad rshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local s = int / (2^by)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return s - s%1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local H = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local K = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function counter(incr)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local t1, t2 = 0, 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if 0xFFFFFFFF - t1 < incr then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- t2 = t2 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- t1 = incr - (0xFFFFFFFF - t1) - 1 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- else t1 = t1 + incr\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return t2, t1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function BE_toInt(bs, i)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return blshift((bs[i] or 0), 24) + blshift((bs[i+1] or 0), 16) + blshift((bs[i+2] or 0), 8) + (bs[i+3] or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function preprocess(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local len = #data\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local proc = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- data[#data+1] = 0x80\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- while #data%64~=56 do data[#data+1] = 0 end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local blocks = math.ceil(#data/64)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, blocks do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- proc[i] = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for j = 1, 16 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- proc[i][j] = BE_toInt(data, 1+((i-1)*64)+((j-1)*4))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- proc[blocks][15], proc[blocks][16] = counter(len*8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return proc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function digestblock(w, C)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for j = 17, 64 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local v = w[j-15]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local s0 = bxor(bxor(rrotate(w[j-15], 7), rrotate(w[j-15], 18)), brshift(w[j-15], 3))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local s1 = bxor(bxor(rrotate(w[j-2], 17), rrotate(w[j-2], 19)), brshift(w[j-2], 10))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- w[j] = (w[j-16] + s0 + w[j-7] + s1)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a, b, c, d, e, f, g, h = upack(C)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for j = 1, 64 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local S1 = bxor(bxor(rrotate(e, 6), rrotate(e, 11)), rrotate(e, 25))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ch = bxor(band(e, f), band(bnot(e), g))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local temp1 = (h + S1 + ch + K[j] + w[j])%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local S0 = bxor(bxor(rrotate(a, 2), rrotate(a, 13)), rrotate(a, 22))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local maj = bxor(bxor(band(a, b), band(a, c)), band(b, c))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local temp2 = (S0 + maj)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- h, g, f, e, d, c, b, a = g, f, e, (d+temp1)%mod32, c, b, a, (temp1+temp2)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[1] = (C[1] + a)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[2] = (C[2] + b)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[3] = (C[3] + c)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[4] = (C[4] + d)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[5] = (C[5] + e)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[6] = (C[6] + f)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[7] = (C[7] + g)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- C[8] = (C[8] + h)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return C\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function toBytes(t, n)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local b = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, n do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- b[(i-1)*4+1] = band(brshift(t[i], 24), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- b[(i-1)*4+2] = band(brshift(t[i], 16), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- b[(i-1)*4+3] = band(brshift(t[i], 8), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- b[(i-1)*4+4] = band(t[i], 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(b, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function digest(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- data = data or \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- data = type(data) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {upack(data)} or {tostring(data):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- data = preprocess(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local C = {upack(H)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, #data do C = digestblock(data[i], C) end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return toBytes(C, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function hmac(data, key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local data = type(data) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {upack(data)} or {tostring(data):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local key = type(key) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {upack(key)} or {tostring(key):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local blocksize = 64\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- key = #key > blocksize and digest(key) or key\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ipad = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local opad = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local padded_key = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, blocksize do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ipad[i] = bxor(0x36, key[i] or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- opad[i] = bxor(0x5C, key[i] or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, #data do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ipad[blocksize+i] = data[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ipad = digest(ipad)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, blocksize do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- padded_key[i] = opad[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- padded_key[blocksize+i] = ipad[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return digest(padded_key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pbkdf2(pass, salt, iter, dklen)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local salt = type(salt) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and salt or {tostring(salt):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local hashlen = 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local dklen = dklen or 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local block = 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local out = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- while dklen > 0 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ikey = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local isalt = {upack(salt)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local clen = dklen > hashlen and hashlen or dklen\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isalt[#isalt+1] = band(brshift(block, 24), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isalt[#isalt+1] = band(brshift(block, 16), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isalt[#isalt+1] = band(brshift(block, 8), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isalt[#isalt+1] = band(block, 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for j = 1, iter do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isalt = hmac(isalt, pass)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for k = 1, clen do ikey[k] = bxor(isalt[k], ikey[k] or 0) end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if j % 200 == 0 then os.queueEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"PBKDF2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", j) coroutine.yield(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"PBKDF2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\") end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- dklen = dklen - clen\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- block = block+1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for k = 1, clen do out[#out+1] = ikey[k] end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(out, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- digest = digest,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- hmac = hmac,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- pbkdf2 = pbkdf2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Chacha20 cipher in ComputerCraft\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- By Anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- For help and details, you can PM me on the CC forums\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- You may use this code in your projects without asking me, as long as credit is given and this header is kept intact\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- http://www.computercraft.info/forums2/index.php?/user/12870-anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- http://pastebin.com/GPzf9JSa\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Last update: April 17, 2017\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local chacha20 = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local bxor = bit32.bxor\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local band = bit32.band\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local blshift = bit32.lshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local brshift = bit32.arshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local mod = 2^32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local tau = {(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"expand 16-byte k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local sigma = {(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"expand 32-byte k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function rotl(n, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local s = n/(2^(32-b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local f = s%1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return (s-f) + f*mod\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function quarterRound(s, a, b, c, d)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s[a] = (s[a]+s[b])%mod; s[d] = rotl(bxor(s[d], s[a]), 16)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s[c] = (s[c]+s[d])%mod; s[b] = rotl(bxor(s[b], s[c]), 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s[a] = (s[a]+s[b])%mod; s[d] = rotl(bxor(s[d], s[a]), 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s[c] = (s[c]+s[d])%mod; s[b] = rotl(bxor(s[b], s[c]), 7)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return s\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function hashBlock(state, rnd)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local s = {unpack(state)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, rnd do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local r = i%2==1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = r and quarterRound(s, 1, 5, 9, 13) or quarterRound(s, 1, 6, 11, 16)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = r and quarterRound(s, 2, 6, 10, 14) or quarterRound(s, 2, 7, 12, 13)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = r and quarterRound(s, 3, 7, 11, 15) or quarterRound(s, 3, 8, 9, 14)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = r and quarterRound(s, 4, 8, 12, 16) or quarterRound(s, 4, 5, 10, 15)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 16 do s[i] = (s[i]+state[i])%mod end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return s\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function LE_toInt(bs, i)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return (bs[i+1] or 0)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- blshift((bs[i+2] or 0), 8)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- blshift((bs[i+3] or 0), 16)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- blshift((bs[i+4] or 0), 24)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function initState(key, nonce, counter)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local isKey256 = #key == 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local const = isKey256 and sigma or tau\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local state = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 1] = LE_toInt(const, 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 2] = LE_toInt(const, 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 3] = LE_toInt(const, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 4] = LE_toInt(const, 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 5] = LE_toInt(key, 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 6] = LE_toInt(key, 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 7] = LE_toInt(key, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 8] = LE_toInt(key, 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[ 9] = LE_toInt(key, isKey256 and 16 or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[10] = LE_toInt(key, isKey256 and 20 or 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[11] = LE_toInt(key, isKey256 and 24 or 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[12] = LE_toInt(key, isKey256 and 28 or 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[13] = counter\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[14] = LE_toInt(nonce, 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[15] = LE_toInt(nonce, 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[16] = LE_toInt(nonce, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return state\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function serialize(state)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local r = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 16 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- r[#r+1] = band(state[i], 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- r[#r+1] = band(brshift(state[i], 8), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- r[#r+1] = band(brshift(state[i], 16), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- r[#r+1] = band(brshift(state[i], 24), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return r\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- function crypt(data, key, nonce, cntr, round)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(type(key) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid key format (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..type(key)..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(type(nonce) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid nonce format (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..type(nonce)..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(#key == 16 or #key == 32, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid key length (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..#key..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be 16 or 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(#nonce == 12, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid nonce length (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..#nonce..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be 12\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local data = type(data) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {unpack(data)} or {tostring(data):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- cntr = tonumber(cntr) or 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- round = tonumber(round) or 20\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local out = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local state = initState(key, nonce, cntr)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local blockAmt = math.floor(#data/64)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 0, blockAmt do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ks = serialize(hashBlock(state, round))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- state[13] = (state[13]+1) % mod\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local block = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for j = 1, 64 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- block[j] = data[((i)*64)+j]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for j = 1, #block do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- out[#out+1] = bxor(block[j], ks[j])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if i % 1000 == 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- os.queueEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- os.pullEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(out, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- crypt = crypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- random.lua - Random Byte Generator\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local random = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local oldPull = os.pullEvent\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local entropy = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local accumulator = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local entropyPath = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"/.random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local running = false\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function feed(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- accumulator = accumulator .. (data or \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local input = accumulator:sub(1, 87)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- accumulator = accumulator:sub(88)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- entropy = tostring(sha256.digest(entropy .. input))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if fs.exists(entropyPath) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local entropyFile = fs.open(entropyPath, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"rb\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(entropyFile.readAll())\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- entropyFile.close()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring(math.random(1, 2^31 - 1)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring(math.random(1, 2^31 - 1)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 10000 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring({}):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"save\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring({}):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local entropyFile = fs.open(entropyPath, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"wb\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- entropyFile.write(tostring(sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"save\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", entropy)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- entropy = tostring(sha256.digest(entropy))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- entropyFile.close()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function seed(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring({}))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function random()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- feed(tostring({}):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"out\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", entropy)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- entropy = tostring(sha256.digest(entropy))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- seed = seed,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- save = save,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- random = random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Big integer arithmetic for 168-bit (and 336-bit) numbers\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Numbers are represented as little-endian tables of 24-bit integers\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local arith = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function isEqual(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- a[1] == b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- and a[2] == b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- and a[3] == b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- and a[4] == b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- and a[5] == b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- and a[6] == b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- and a[7] == b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- )\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function compare(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 7, 1, -1 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if a[i] > b[i] then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- elseif a[i] < b[i] then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return -1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function add(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- c7 may be greater than 2^24 before reduction\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a[1] + b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a[2] + b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a[3] + b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a[4] + b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a[5] + b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a[6] + b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a[7] + b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c1 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c2 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c3 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c4 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c5 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c6 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function sub(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- c7 may be negative before reduction\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a[1] - b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a[2] - b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a[3] - b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a[4] - b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a[5] - b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a[6] - b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a[7] - b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c1 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c2 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c3 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c4 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c5 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c6 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function rShift(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 - c1 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 + (c2 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 - c2 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + (c3 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 - c3 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + (c4 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 - c4 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + (c5 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 - c5 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + (c6 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 - c6 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + (c7 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 - c7 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function addDouble(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- a and b are 336-bit integers (14 words)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a[1] + b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a[2] + b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a[3] + b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a[4] + b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a[5] + b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a[6] + b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a[7] + b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c8 = a[8] + b[8]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c9 = a[9] + b[9]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c10 = a[10] + b[10]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c11 = a[11] + b[11]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c12 = a[12] + b[12]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c13 = a[13] + b[13]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c14 = a[14] + b[14]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c1 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c2 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c3 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c4 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c5 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c6 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c7 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c8 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c9 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c10 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c11 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c12 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c13 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c14 = c14 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function mult(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a1, a2, a3, a4, a5, a6, a7 = unpack(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local b1, b2, b3, b4, b5, b6, b7 = unpack(b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a1 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a1 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + a2 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a1 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + a2 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + a3 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a1 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + a2 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + a3 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + a4 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a1 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + a2 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + a3 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + a4 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + a5 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a1 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + a2 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + a3 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + a4 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + a5 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + a6 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a1 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a2 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a3 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a4 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a5 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a6 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a7 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c8 = a2 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + a3 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + a4 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + a5 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + a6 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + a7 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c9 = a3 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + a4 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + a5 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + a6 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + a7 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c10 = a4 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + a5 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + a6 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + a7 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c11 = a5 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 + a6 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 + a7 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c12 = a6 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 + a7 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c13 = a7 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c14 = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c1 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c2 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c3 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c4 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c5 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c6 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c7 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c8 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c9 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c10 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c11 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c12 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c13 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c14 = c14 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function square(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- returns a 336-bit integer (14 words)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a1, a2, a3, a4, a5, a6, a7 = unpack(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a1 * a1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a1 * a2 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a1 * a3 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + a2 * a2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a1 * a4 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + a2 * a3 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a1 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + a2 * a4 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + a3 * a3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a1 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + a2 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + a3 * a4 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a1 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a2 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a3 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a4 * a4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c8 = a2 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + a3 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + a4 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c9 = a3 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + a4 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + a5 * a5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c10 = a4 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + a5 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c11 = a5 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 + a6 * a6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c12 = a6 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c13 = a7 * a7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c14 = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c1 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c2 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c3 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c4 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c5 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c6 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c7 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c8 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c9 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c10 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c11 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c12 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c13 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c14 = c14 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Converts a number from base 2^startLength to base 2^resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function reword(start, startLength, resultLength)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local buffer = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local bufferLength = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local startIndex = 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local totalBits = #start * startLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- while totalBits > 0 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- while bufferLength < resultLength do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- buffer = buffer + (start[startIndex] or 0) * 2^bufferLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- startIndex = startIndex + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- bufferLength = bufferLength + startLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result[#result + 1] = buffer % 2^resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- buffer = buffer / 2^resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- buffer = buffer - buffer % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- bufferLength = bufferLength - resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- totalBits = totalBits - resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function mods(d, w)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = d[1] % 2^w\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if result >= 2^(w - 1) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = result - 2^w\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Represents a 168-bit number as the (2^w)-ary Non-Adjacent Form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function NAF(d, w)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local t = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local d = {unpack(d)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if d[1] % 2 == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- t[#t + 1] = mods(d, w)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- d = sub(d, {t[#t], 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- t[#t + 1] = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- d = rShift(d)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return t\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isEqual = isEqual,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- compare = compare,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- add = add,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- sub = sub,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- addDouble = addDouble,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- mult = mult,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- square = square,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- reword = reword,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- NAF = NAF\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Arithmetic on the finite field of integers modulo p\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Where p is the finite field modulus\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local modp = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local add = arith.add\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local sub = arith.sub\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local addDouble = arith.addDouble\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local mult = arith.mult\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local square = arith.square\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local p = {3, 0, 0, 0, 0, 0, 15761408}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- We're using the Montgomery Reduction for fast modular multiplication.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- https://en.wikipedia.org/wiki/Montgomery_modular_multiplication \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- r = 2^168\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- p * pInverse = -1 (mod r)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- r2 = r * r (mod p)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local pInverse = {5592405, 5592405, 5592405, 5592405, 5592405, 5592405, 14800213}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local r2 = {13533400, 837116, 6278376, 13533388, 837116, 6278376, 7504076}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function multByP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a1, a2, a3, a4, a5, a6, a7 = unpack(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a1 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a2 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a3 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a4 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a5 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a6 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a1 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + a7 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c8 = a2 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c9 = a3 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c10 = a4 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c11 = a5 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c12 = a6 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c13 = a7 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c14 = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c1 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c2 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c3 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c4 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c5 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c6 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c7 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c8 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c8 = c8 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c9 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c9 = c9 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c10 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c10 = c10 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c11 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c11 = c11 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c12 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c12 = c12 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- temp = c13 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c14 = c14 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c13 = c13 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Reduces a number from [0, 2p - 1] to [0, p - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function reduceModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- a < p\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if a[7] < 15761408 or a[7] == 15761408 and a[1] < 3 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- a > p\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c1 = a[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c2 = a[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c3 = a[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c4 = a[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c5 = a[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c6 = a[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local c7 = a[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 - 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 - 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c1 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c1 = c1 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c2 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c2 = c2 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c3 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c3 = c3 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c4 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c4 = c4 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c5 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c5 = c5 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if c6 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c7 = c7 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- c6 = c6 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function addModP(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return reduceModP(add(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function subModP(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = sub(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if result[7] < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = add(result, p)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Montgomery REDC algorithn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Reduces a number from [0, p^2 - 1] to [0, p - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function REDC(T)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local m = {unpack(mult({unpack(T, 1, 7)}, pInverse), 1, 7)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local t = {unpack(addDouble(T, multByP(m)), 8, 14)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return reduceModP(t)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function multModP(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Only works with a, b in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return REDC(mult(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function squareModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Only works with a in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return REDC(square(a))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function montgomeryModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return multModP(a, r2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function inverseMontgomeryModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a = {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 8, 14 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- a[i] = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return REDC(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ONE = montgomeryModP({1, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function expModP(base, exponentBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local base = {unpack(base)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if exponentBinary[i] == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = multModP(result, base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- base = squareModP(base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- addModP = addModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- subModP = subModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- multModP = multModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- squareModP = squareModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- montgomeryModP = montgomeryModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- inverseMontgomeryModP = inverseMontgomeryModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- expModP = expModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Arithmetic on the Finite Field of Integers modulo q\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Where q is the generator's subgroup order.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local modq = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local isEqual = arith.isEqual\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local compare = arith.compare\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local add = arith.add\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local sub = arith.sub\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local addDouble = arith.addDouble\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local mult = arith.mult\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local square = arith.square\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local reword = arith.reword\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local modQMT\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local q = {9622359, 6699217, 13940450, 16775734, 16777215, 16777215, 3940351}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local qMinusTwoBinary = {1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- We're using the Montgomery Reduction for fast modular multiplication.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- https://en.wikipedia.org/wiki/Montgomery_modular_multiplication \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- r = 2^168\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- q * qInverse = -1 (mod r)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- r2 = r * r (mod q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local qInverse = {15218585, 5740955, 3271338, 9903997, 9067368, 7173545, 6988392}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local r2 = {1336213, 11071705, 9716828, 11083885, 9188643, 1494868, 3306114}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Reduces a number from [0, 2q - 1] to [0, q - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function reduceModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if compare(result, q) >= 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = sub(result, q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function addModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return reduceModQ(add(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function subModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = sub(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if result[7] < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = add(result, q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Montgomery REDC algorithn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Reduces a number from [0, q^2 - 1] to [0, q - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function REDC(T)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local m = {unpack(mult({unpack(T, 1, 7)}, qInverse), 1, 7)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local t = {unpack(addDouble(T, mult(m, q)), 8, 14)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return reduceModQ(t)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function multModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Only works with a, b in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return REDC(mult(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function squareModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Only works with a in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return REDC(square(a))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function montgomeryModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return multModQ(a, r2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function inverseMontgomeryModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a = {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 8, 14 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- a[i] = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return REDC(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ONE = montgomeryModQ({1, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function expModQ(base, exponentBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local base = {unpack(base)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if exponentBinary[i] == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = multModQ(result, base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- base = squareModQ(base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function intExpModQ(base, exponent)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local base = {unpack(base)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = setmetatable({unpack(ONE)}, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if exponent < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- base = expModQ(base, qMinusTwoBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- exponent = -exponent\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- while exponent > 0 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if exponent % 2 == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = multModQ(result, base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- base = squareModQ(base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- exponent = exponent / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- exponent = exponent - exponent % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function encodeModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = reword(a, 24, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function decodeModQ(s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = type(s) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {unpack(s, 1, 21)} or {tostring(s):byte(1, 21)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = reword(s, 8, 24)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result[8] = nil\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result[7] = result[7] % q[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function hashModQ(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = decodeModQ(sha256.digest(data))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- modQMT = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __index = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- encode = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return encodeModQ(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- },\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __tostring = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return self:encode():toHex()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __add = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(self) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return other + self\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(other) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(other < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- other = montgomeryModQ({other, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return addModQ(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __sub = function(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(a) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(a < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- a = montgomeryModQ({a, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(b) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(b < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- b = montgomeryModQ({b, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return subModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __unm = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return subModQ(q, self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __eq = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return isEqual(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __mul = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(self) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return other * self\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- EC point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Use the point's metatable to handle multiplication\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(other) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and type(other[1]) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return other * self\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(other) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(other < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- other = montgomeryModQ({other, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return multModQ(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __div = function(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(a) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(a < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- a = montgomeryModQ({a, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(b) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(b < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- b = montgomeryModQ({b, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- bInv = expModQ(b, qMinusTwoBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return multModQ(a, bInv)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __pow = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return intExpModQ(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- hashModQ = hashModQ,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- randomModQ = randomModQ,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- decodeModQ = decodeModQ,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- inverseMontgomeryModQ = inverseMontgomeryModQ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Elliptic curve arithmetic\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local curve = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ---- About the Curve Itself\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Field Size: 168 bits\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Field Modulus (p): 481 * 2^159 + 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Equation: x^2 + y^2 = 1 + 122 * x^2 * y^2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Parameters: Edwards Curve with d = 122\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Curve Order (n): 351491143778082151827986174289773107581916088585564\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Cofactor (h): 4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Generator Order (q): 87872785944520537956996543572443276895479022146391\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ---- About the Curve's Security\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Current best attack security: 81.777 bits (Small Subgroup + Rho)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Rho Security: log2(0.884 * sqrt(q)) = 82.777 bits\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Transfer Security? Yes: p ~= q; k > 20\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Field Discriminant Security? Yes:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- t = 27978492958645335688000168\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- s = 10\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- |D| = 6231685068753619775430107799412237267322159383147 > 2^100\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Rigidity? No, not at all.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- XZ/YZ Ladder Security? No: Single coordinate ladders are insecure.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Small Subgroup Security? No.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Invalid Curve Security? Yes: Points are checked before every operation.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Invalid Curve Twist Security? No: Don't use single coordinate ladders.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Completeness? Yes: The curve is complete.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Indistinguishability? Yes (Elligator 2), but not implemented.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local isEqual = arith.isEqual\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local NAF = arith.NAF\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local reword = arith.reword\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local multModP = modp.multModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local squareModP = modp.squareModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local addModP = modp.addModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local subModP = modp.subModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local montgomeryModP = modp.montgomeryModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local inverseMontgomeryModP = modp.inverseMontgomeryModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local expModP = modp.expModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local inverseMontgomeryModQ = modq.inverseMontgomeryModQ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local pointMT\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ZERO = {0, 0, 0, 0, 0, 0, 0}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ONE = montgomeryModP({1, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Curve Parameters\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local d = montgomeryModP({122, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local p = {3, 0, 0, 0, 0, 0, 15761408}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local pMinusTwoBinary = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local pMinusThreeOverFourBinary = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local G = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- {6636044, 10381432, 15741790, 2914241, 5785600, 264923, 4550291},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- {13512827, 8449886, 5647959, 1135556, 5489843, 7177356, 8002203},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local O = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- {unpack(ZERO)},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- {unpack(ONE)},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Projective Coordinates for Edwards curves for point addition/doubling.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Points are represented as: (X:Y:Z) where x = X/Z and y = Y/Z\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- The identity element is represented by (0:1:1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Point operation formulas are available on the EFD:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- https://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointDouble(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- 3M + 4S\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local b = addModP(X1, Y1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local B = squareModP(b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local C = squareModP(X1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local D = squareModP(Y1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local E = addModP(C, D)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local H = squareModP(Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local J = subModP(E, addModP(H, H))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X3 = multModP(subModP(B, E), J)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Y3 = multModP(E, subModP(C, D))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Z3 = multModP(E, J)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointAdd(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- 10M + 1S\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X2, Y2, Z2 = unpack(P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local A = multModP(Z1, Z2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local B = squareModP(A)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local C = multModP(X1, X2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local D = multModP(Y1, Y2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local E = multModP(d, multModP(C, D))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local F = subModP(B, E)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local G = addModP(B, E)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X3 = multModP(A, multModP(F, subModP(multModP(addModP(X1, Y1), addModP(X2, Y2)), addModP(C, D))))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Y3 = multModP(A, multModP(G, subModP(D, C)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Z3 = multModP(F, G)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointNeg(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X3 = subModP(ZERO, X1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Y3 = {unpack(Y1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Z3 = {unpack(Z1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointSub(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return pointAdd(P1, pointNeg(P2))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Converts (X:Y:Z) into (X:Y:1) = (x:y:1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointScale(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local A = expModP(Z1, pMinusTwoBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X3 = multModP(X1, A)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Y3 = multModP(Y1, A)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Z3 = {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointIsEqual(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X2, Y2, Z2 = unpack(P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local A1 = multModP(X1, Z2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local B1 = multModP(Y1, Z2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local A2 = multModP(X2, Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local B2 = multModP(Y2, Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return isEqual(A1, A2) and isEqual(B1, B2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Checks if a projective point satisfies the curve equation\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointIsOnCurve(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local X12 = squareModP(X1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Y12 = squareModP(Y1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Z12 = squareModP(Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Z14 = squareModP(Z12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local a = addModP(X12, Y12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- a = multModP(a, Z12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local b = multModP(d, multModP(X12, Y12))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- b = addModP(Z14, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return isEqual(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointIsInf(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return isEqual(P1[1], ZERO)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- W-ary Non-Adjacent Form (wNAF) method for scalar multiplication:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#w-ary_non-adjacent_form_(wNAF)_method\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function scalarMult(multiplier, P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- w = 5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local naf = NAF(multiplier, 5)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local PTable = {P1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local P2 = pointDouble(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Q = {{unpack(ZERO)}, {unpack(ONE)}, {unpack(ONE)}}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 3, 31, 2 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- PTable[i] = pointAdd(PTable[i - 2], P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = #naf, 1, -1 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Q = pointDouble(Q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\009\\\\\\\\\\\\\\\\009\\\\\\\\\\\\\\\\009local TMP = naf[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if TMP > 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Q = pointAdd(Q, PTable[TMP])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- elseif TMP < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Q = pointSub(Q, PTable[-TMP])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(Q, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Lookup table 4-ary NAF method for scalar multiplication by G.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Precomputations for the regular NAF method are done before the multiplication.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local GTable = {G}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 2, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- GTable[i] = pointDouble(GTable[i - 1])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function scalarMultG(multiplier)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local naf = NAF(multiplier, 2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Q = {{unpack(ZERO)}, {unpack(ONE)}, {unpack(ONE)}}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if naf[i] == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Q = pointAdd(Q, GTable[i])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- elseif naf[i] == -1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Q = pointSub(Q, GTable[i])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(Q, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Point compression and encoding.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Compresses curve points to 22 bytes.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointEncode(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- P1 = pointScale(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local x, y = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Encode y\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result = reword(y, 24, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Encode one bit from x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result[22] = x[1] % 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function pointDecode(enc)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- enc = type(enc) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {unpack(enc, 1, 22)} or {tostring(enc):byte(1, 22)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- --Find x's bit\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local xbit = enc[22]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Decode y\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local y = reword(enc, 8, 24)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- y[8] = nil\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- y[7] = y[7] % p[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Find {x, -x} using curve equation\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local y2 = squareModP(y)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local u = subModP(y2, ONE)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local v = subModP(multModP(d, y2), ONE)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local u2 = squareModP(u)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local u3 = multModP(u, u2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local u5 = multModP(u3, u2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local v3 = multModP(v, squareModP(v))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local w = multModP(u5, v3)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local x = multModP(u3, multModP(v, expModP(w, pMinusThreeOverFourBinary)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -- Use x's bit to find x from {x, -x}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if x[1] % 2 ~= xbit then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- x = subModP(ZERO, x)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local P3 = {x, y, {unpack(ONE)}}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- pointMT = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __index = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isOnCurve = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return pointIsOnCurve(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- isInf = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return self:isOnCurve() and pointIsInf(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- encode = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return pointEncode(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- },\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __tostring = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return self:encode():toHex()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __add = function(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(P1:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(P2:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return pointAdd(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __sub = function(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(P1:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(P2:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return pointSub(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __unm = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(self:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return pointNeg(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __eq = function(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(P1:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(P2:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return pointIsEqual(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __mul = function(P1, s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(P1) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return s * P1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if type(s) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(s < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number multiplier too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = {s, 0, 0, 0, 0, 0, 0}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = inverseMontgomeryModQ(s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- if P1 == G then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return scalarMultG(s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return scalarMult(s, P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- G = setmetatable(G, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- O = setmetatable(O, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- G = G,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- O = O,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- pointDecode = pointDecode\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function getNonceFromEpoch()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local nonce = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local epoch = os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, 12 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- nonce[#nonce + 1] = epoch % 256\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- epoch = epoch / 256\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- epoch = epoch - epoch % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return nonce\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function encrypt(data, key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local encKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"encKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local macKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"macKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local nonce = getNonceFromEpoch()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ciphertext = chacha20.crypt(data, encKey, nonce)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = nonce\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, #ciphertext do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result[#result + 1] = ciphertext[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local mac = sha256.hmac(result, macKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, #mac do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result[#result + 1] = mac[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function decrypt(data, key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local encKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"encKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local macKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"macKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local mac = sha256.hmac({unpack(data, 1, #data - 32)}, macKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local messageMac = {unpack(data, #data - 31)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- assert(mac:isEqual(messageMac), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid mac\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local nonce = {unpack(data, 1, 12)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local ciphertext = {unpack(data, 13, #data - 32)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = chacha20.crypt(ciphertext, encKey, nonce)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function keypair(seed)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- seed = seed or random.random()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local x = modq.hashModQ(seed)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Y = curve.G * x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local privateKey = x:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local publicKey = Y:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return privateKey, publicKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function exchange(privateKey, publicKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local x = modq.decodeModQ(privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Y = curve.pointDecode(publicKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local Z = Y * x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local sharedSecret = sha256.digest(Z:encode())\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return sharedSecret\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function sign(privateKey, message)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local message = type(message) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and string.char(unpack(message)) or tostring(message)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local privateKey = type(privateKey) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and string.char(unpack(privateKey)) or tostring(privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local x = modq.decodeModQ(privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local k = modq.hashModQ(message .. privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local R = curve.G * k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local e = modq.hashModQ(message .. tostring(R))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local s = k - x * e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- e = e:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = s:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local result = e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- for i = 1, #s do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- result[#result + 1] = s[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local function verify(publicKey, message, signature)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local message = type(message) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and string.char(unpack(message)) or tostring(message)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Y = curve.pointDecode(publicKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- e = modq.decodeModQ({unpack(signature, 1, #signature / 2)})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- s = modq.decodeModQ({unpack(signature, #signature / 2 + 1)})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Rv = curve.G * s + Y * e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ev = modq.hashModQ(message .. tostring(Rv))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return ev == e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- local API = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.ChaCha20 = chacha20\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.SHA256 = sha256\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.random = random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.encrypt = encrypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.decrypt = decrypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.keypair = keypair\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.exchange = exchange\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.sign = sign\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- API.verify = verify\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"crypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", API)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- return 1\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
- }\\\",\\\
- \\\"F:esiboot.b\\\",\\\
- \\\"\\\\\\\"local sr = shell.run\\\\\\\\\\\\\\\
- local args = {...}\\\\\\\\\\\\\\\
- local bootConfigDefaults = {}\\\\\\\\\\\\\\\
- bootConfigDefaults.script = \\\\\\\\\\\\\\\"Orbital\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local function boot_handleBootElement(str)\\\\\\\\\\\\\\\
- local s1 = \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
- local n1 = s1:len()\\\\\\\\\\\\\\\
- local n2 = str:len()\\\\\\\\\\\\\\\
- local s2 = string.sub(s1, 1, n1-n2)\\\\\\\\\\\\\\\
- return \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..str..s2..\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local function boot_mprint(array, this, x, y, h, g)\\\\\\\\\\\\\\\
- local c1 = term.getBackgroundColor()\\\\\\\\\\\\\\\
- local c2 = term.getTextColor()\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- for i = 1, #array do\\\\\\\\\\\\\\\
- term.setCursorPos(x, y)\\\\\\\\\\\\\\\
- --Check if option selected\\\\\\\\\\\\\\\
- if i == this then \\\\\\\\\\\\\\\
- --Option selected \\\\\\\\\\\\\\\
- term.setBackgroundColor(h)\\\\\\\\\\\\\\\
- term.setTextColor(g)\\\\\\\\\\\\\\\
- else \\\\\\\\\\\\\\\
- --Option NOT selected \\\\\\\\\\\\\\\
- term.setBackgroundColor(g)\\\\\\\\\\\\\\\
- term.setTextColor(h)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- --Print the string\\\\\\\\\\\\\\\
- term.write(boot_handleBootElement(array[i]))\\\\\\\\\\\\\\\
- y = y + 1 \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- term.setBackgroundColor(c1)\\\\\\\\\\\\\\\
- term.setTextColor(c2)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local function boot_drawBootMenu(array, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
- local select = 1\\\\\\\\\\\\\\\
- local x, y = term.getCursorPos()\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- term.setCursorPos(x, y)\\\\\\\\\\\\\\\
- boot_mprint(array, select, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
- event, key = os.pullEvent(\\\\\\\\\\\\\\\"key\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- --Enter\\\\\\\\\\\\\\\
- if key == 28 then \\\\\\\\\\\\\\\
- return select \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- if #array > 1 then\\\\\\\\\\\\\\\
- --Arrow UP or W key\\\\\\\\\\\\\\\
- if key == 200 or key == 17 then \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009 select = select - 1 \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009\\\\\\\\009\\\\\\\\\\\\\\\
- if select < 1 then \\\\\\\\\\\\\\\
- select = #array \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- --Arrow Down or S key\\\\\\\\\\\\\\\
- elseif key == 208 or key == 31 then \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009 select = select + 1 \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009\\\\\\\\009 if select > #array then select = 1 end\\\\\\\\\\\\\\\
- \\\\\\\\009 end\\\\\\\\\\\\\\\
- end \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local function boot_printColoredTextLine(y, txt, bg, fg)\\\\\\\\\\\\\\\
- term.setCursorPos(1, y)\\\\\\\\\\\\\\\
- term.setBackgroundColor(bg or colors.lightGray)\\\\\\\\\\\\\\\
- term.write(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setCursorPos(1, y)\\\\\\\\\\\\\\\
- term.setTextColor(fg or colors.black)\\\\\\\\\\\\\\\
- print(txt)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"drawBootManager\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local function drawBootManager(opt)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.clear()\\\\\\\\\\\\\\\
- term.setCursorPos(1,1)\\\\\\\\\\\\\\\
- \\\\\\\\009if not opt then\\\\\\\\\\\\\\\
- boot_printColoredTextLine(2, \\\\\\\\\\\\\\\" Orbital Boot Manager v3.1 \\\\\\\\\\\\\\\", colors.lightGray, colors.black)\\\\\\\\\\\\\\\
- boot_printColoredTextLine(18, \\\\\\\\\\\\\\\" F2=ESI Setup F10=Boot Menu \\\\\\\\\\\\\\\", colors.lightGray, colors.black)\\\\\\\\\\\\\\\
- \\\\\\\\009else\\\\\\\\\\\\\\\
- boot_printColoredTextLine(2, \\\\\\\\\\\\\\\" Orbital Boot Manager v3.1 \\\\\\\\\\\\\\\", colors.red, colors.black)\\\\\\\\\\\\\\\
- boot_printColoredTextLine(18, \\\\\\\\\\\\\\\" CTRL+R=Reboot \\\\\\\\\\\\\\\", colors.red, colors.black)\\\\\\\\\\\\\\\
- \\\\\\\\009end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local esiTable = {}\\\\\\\\\\\\\\\
- esiTable.UIBootMenu = boot_drawBootMenu\\\\\\\\\\\\\\\
- esiTable.UIHandleElement = boot_handleBootElement\\\\\\\\\\\\\\\
- esiTable.UIColoredLine = boot_printColoredTextLine\\\\\\\\\\\\\\\
- esiTable.UIInit = drawBootManager\\\\\\\\\\\\\\\
- esiTable.LoadBootConfig = function()\\\\\\\\\\\\\\\
- if not fs.exists(\\\\\\\\\\\\\\\"/boot/esi/config.dat\\\\\\\\\\\\\\\") then\\\\\\\\\\\\\\\
- return nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- local lf = fs.open(\\\\\\\\\\\\\\\"/boot/esi/config.dat\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- local contents = lf.readAll()\\\\\\\\\\\\\\\
- lf.close()\\\\\\\\\\\\\\\
- return textutils.unserialize(contents) \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- esiTable.SaveBootConfig = function(cTable)\\\\\\\\\\\\\\\
- local sf = fs.open(\\\\\\\\\\\\\\\"/boot/esi/config.dat\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- sf.write(textutils.serialize(cTable))\\\\\\\\\\\\\\\
- sf.close()\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- esiTable.Finalize = function()\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"RunInternal\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"RunMap\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"UserMode\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"Boot\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"RunExternal\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- __declare_api(\\\\\\\\\\\\\\\"ESI\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"Finalize\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- __declare_api(\\\\\\\\\\\\\\\"ESI\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"RunScript\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- esiTable.RunScript = function(s)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"RunInternal\\\\\\\\\\\\\\\", function(m)\\\\\\\\\\\\\\\
- dofile(\\\\\\\\\\\\\\\"/boot/esi/\\\\\\\\\\\\\\\"..m..\\\\\\\\\\\\\\\".b\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"RunMap\\\\\\\\\\\\\\\", function(m)\\\\\\\\\\\\\\\
- sr(\\\\\\\\\\\\\\\"/boot/\\\\\\\\\\\\\\\"..m..\\\\\\\\\\\\\\\".map\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"UserMode\\\\\\\\\\\\\\\", function(null)\\\\\\\\\\\\\\\
- sr(\\\\\\\\\\\\\\\"/bin/sh\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"Boot\\\\\\\\\\\\\\\", function(k)\\\\\\\\\\\\\\\
- dofile(\\\\\\\\\\\\\\\"/boot/kernel/\\\\\\\\\\\\\\\"..k)\\\\\\\\\\\\\\\
- end)\\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"RunExternal\\\\\\\\\\\\\\\", function(f)\\\\\\\\\\\\\\\
- dofile(\\\\\\\\\\\\\\\"/boot/\\\\\\\\\\\\\\\"..f)\\\\\\\\\\\\\\\
- end)\\\\\\\\\\\\\\\
- sr(\\\\\\\\\\\\\\\"/boot/esi/scripts/\\\\\\\\\\\\\\\"..s..\\\\\\\\\\\\\\\".script\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"ESI\\\\\\\\\\\\\\\", esiTable)\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local conf = ESI.LoadBootConfig()\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- if not conf then\\\\\\\\\\\\\\\
- ESI.SaveBootConfig(bootConfigDefaults)\\\\\\\\\\\\\\\
- drawBootManager(true)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.red)\\\\\\\\009\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,4)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"The Orbital Boot Manager was unable to continue\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,5)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"the booting process.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,7)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"Status:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,8)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"ESI_CONFIGURATION_MISSING (0x00000001)\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,10)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"Information:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,11)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"The /boot/esi/config.dat file is missing.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,12)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"A default file will be generated after rebooting.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- \\\\\\\\009 sleep(1)\\\\\\\\\\\\\\\
- \\\\\\\\009end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local secondsPast = 0\\\\\\\\\\\\\\\
- local timerID = os.startTimer( 1 )\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- ESI.UIInit(false)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\009\\\\\\\\\\\\\\\
- term.setCursorPos(2,4)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"Extensible System Interface (ESI)\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setCursorPos(2,6)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"Computer ID: \\\\\\\\\\\\\\\"..tostring(os.getComputerID()))\\\\\\\\\\\\\\\
- term.setCursorPos(2,7)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"Hostname: \\\\\\\\\\\\\\\"..tostring(os.getComputerLabel() or \\\\\\\\\\\\\\\"N/A\\\\\\\\\\\\\\\"))\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- sleep(0.25)\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- for k, file in pairs(fs.list(\\\\\\\\\\\\\\\"/boot/esi/drivers\\\\\\\\\\\\\\\")) do\\\\\\\\\\\\\\\
- if not dofile(\\\\\\\\\\\\\\\"/boot/esi/drivers/\\\\\\\\\\\\\\\"..file) then\\\\\\\\\\\\\\\
- drawBootManager(true)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.red)\\\\\\\\009\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,4)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"The Orbital Boot Manager was unable to continue\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,5)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"the booting process.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,7)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"Status:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,8)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"DRIVER_LOAD_FAILURE (0x00000003)\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,10)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"Information:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,11)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"The following driver failed to load:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\009term.setCursorPos(2,12)\\\\\\\\\\\\\\\
- \\\\\\\\009print(\\\\\\\\\\\\\\\"/boot/esi/drivers/\\\\\\\\\\\\\\\"..file)\\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- \\\\\\\\009 sleep(1)\\\\\\\\\\\\\\\
- \\\\\\\\009end\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- term.setCursorPos(2,8+k) \\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"Loaded driver: \\\\\\\\\\\\\\\"..file)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- sleep(0.25)\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- term.setCursorPos(2,16)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"Booting active kernel...\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- local event, value = os.pullEvent()\\\\\\\\\\\\\\\
- --sleep(0.1)\\\\\\\\\\\\\\\
- if event == \\\\\\\\\\\\\\\"timer\\\\\\\\\\\\\\\" and value == timerID then\\\\\\\\\\\\\\\
- secondsPast = secondsPast + 1 -- Increment secondsPast by one, a second has passed\\\\\\\\\\\\\\\
- if secondsPast == 3 then\\\\\\\\\\\\\\\
- --sleep(0.1)\\\\\\\\\\\\\\\
- ESI.UIColoredLine(18, \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\", colors.lightGray, colors.black)\\\\\\\\\\\\\\\
- break\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- timerID = os.startTimer( 1 )\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- elseif event == \\\\\\\\\\\\\\\"key\\\\\\\\\\\\\\\" and value == 60 then\\\\\\\\\\\\\\\
- break\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- if secondsPast == 3 then\\\\\\\\\\\\\\\
- ESI.RunScript(conf.script)\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- --sr(\\\\\\\\\\\\\\\"esiconfig\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end\\\\\\\"\\\",\\\
- \\\"F:esiconfig.b\\\",\\\
- \\\"\\\\\\\"local function boot_handleBootElement(str)\\\\\\\\\\\\\\\
- local s1 = \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
- local n1 = s1:len()\\\\\\\\\\\\\\\
- local n2 = str:len()\\\\\\\\\\\\\\\
- local s2 = string.sub(s1, 1, n1-n2)\\\\\\\\\\\\\\\
- return \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..str..s2..\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local function boot_mprint(array, this, x, y, h, g)\\\\\\\\\\\\\\\
- local c1 = term.getBackgroundColor()\\\\\\\\\\\\\\\
- local c2 = term.getTextColor()\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- for i = 1, #array do\\\\\\\\\\\\\\\
- term.setCursorPos(x, y)\\\\\\\\\\\\\\\
- --Check if option selected\\\\\\\\\\\\\\\
- if i == this then \\\\\\\\\\\\\\\
- --Option selected \\\\\\\\\\\\\\\
- term.setBackgroundColor(h)\\\\\\\\\\\\\\\
- term.setTextColor(g)\\\\\\\\\\\\\\\
- else \\\\\\\\\\\\\\\
- --Option NOT selected \\\\\\\\\\\\\\\
- term.setBackgroundColor(g)\\\\\\\\\\\\\\\
- term.setTextColor(h)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- --Print the string\\\\\\\\\\\\\\\
- term.write(boot_handleBootElement(array[i]))\\\\\\\\\\\\\\\
- y = y + 1 \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- term.setBackgroundColor(c1)\\\\\\\\\\\\\\\
- term.setTextColor(c2)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local function boot_drawBootMenu(array, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
- local select = 1\\\\\\\\\\\\\\\
- local x, y = term.getCursorPos()\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- term.setCursorPos(x, y)\\\\\\\\\\\\\\\
- boot_mprint(array, select, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
- event, key = os.pullEvent(\\\\\\\\\\\\\\\"key\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- --Enter\\\\\\\\\\\\\\\
- if key == 28 then \\\\\\\\\\\\\\\
- return select \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- if #array > 1 then\\\\\\\\\\\\\\\
- --Arrow UP or W key\\\\\\\\\\\\\\\
- if key == 200 or key == 17 then \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009 select = select - 1 \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009\\\\\\\\009\\\\\\\\\\\\\\\
- if select < 1 then \\\\\\\\\\\\\\\
- select = #array \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- --Arrow Down or S key\\\\\\\\\\\\\\\
- elseif key == 208 or key == 31 then \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009 select = select + 1 \\\\\\\\\\\\\\\
- \\\\\\\\009\\\\\\\\009\\\\\\\\009 if select > #array then select = 1 end\\\\\\\\\\\\\\\
- \\\\\\\\009 end\\\\\\\\\\\\\\\
- end \\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- term.clear()\\\\\\\\\\\\\\\
- boot_drawBootMenu({boot_handleBootElement(\\\\\\\\\\\\\\\"Darwin Developer Preview 0.1.0.7\\\\\\\\\\\\\\\"), boot_handleBootElement(\\\\\\\\\\\\\\\"Tesseract Bootstrap 1.0.0.0\\\\\\\\\\\\\\\"), boot_handleBootElement(\\\\\\\\\\\\\\\"aaaaaaaaaa\\\\\\\\\\\\\\\")}, 2, 2, colors.lightGray, colors.black)\\\\\\\"\\\",\\\
- \\\"D:scripts\\\",\\\
- \\\"{\\\\\\\
- \\\\\\\"F:Orbital.script\\\\\\\",\\\\\\\
- \\\\\\\"\\\\\\\\\\\\\\\"-- Example ESI boot script.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- RunMap \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"kernel\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- run kernel.map\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- RunMap \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"security\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- run security.map\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- Boot \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"darwin-rolling-0.1.0.7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- boot the kernel\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- UserMode \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Default\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- go user mode\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
- }\\\",\\\
- }\",\
- \"D:kernel\",\
- \"{\\\
- \\\"F:darwin-rolling-0.1.0.7\\\",\\\
- \\\"\\\\\\\"-- @PRODUCTNAME Darwin\\\\\\\\\\\\\\\
- -- @VERSION 0.0.4.6\\\\\\\\\\\\\\\
- -- @RELEASETYPE rolling\\\\\\\\\\\\\\\
- -- @SKU Developer Preview\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- --term.clear()\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- os.version = function()\\\\\\\\\\\\\\\
- return \\\\\\\\\\\\\\\"Orbital 0.1.0.7 Developer Preview\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- if not dofile(\\\\\\\\\\\\\\\"/boot/kernel.map\\\\\\\\\\\\\\\") then\\\\\\\\\\\\\\\
- printError(\\\\\\\\\\\\\\\"[ X ] Failed to initialize kernel library\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- coroutine.yield()\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- __declare(\\\\\\\\\\\\\\\"__DEBUG\\\\\\\\\\\\\\\", __kstruct({true}))\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- n = 1\\\\\\\\\\\\\\\
- for k, file in pairs(fs.list(\\\\\\\\\\\\\\\"/lib\\\\\\\\\\\\\\\")) do\\\\\\\\\\\\\\\
- if string.sub(file, -3) == \\\\\\\\\\\\\\\".so\\\\\\\\\\\\\\\" and file ~= \\\\\\\\\\\\\\\"libstdlua.2.so\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\
- term.setCursorPos(2,3 + n)\\\\\\\\\\\\\\\
- __kload(\\\\\\\\\\\\\\\"/lib/\\\\\\\\\\\\\\\"..file) -- attempting to hook the file\\\\\\\\\\\\\\\
- n = k\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- n = k - 1\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- finalize kernel-mode init\\\\\\\\\\\\\\\
- __kfinalize()\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- sleep(0.5)\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- output\\\\\\\\\\\\\\\
- --term.setCursorPos(2,8)\\\\\\\\\\\\\\\
- --printk(1, \\\\\\\\\\\\\\\"Darwin kernel loaded\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- sleep(2)\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- term.clear()\\\\\\\\\\\\\\\
- term.setCursorPos(1,1)\\\\\\\"\\\",\\\
- \\\"F:tesseract-bootstrap-1.0\\\",\\\
- \\\"\\\\\\\"-- @PRODUCTNAME Tesseract\\\\\\\\\\\\\\\
- -- @VERSION 1.0.0.0\\\\\\\\\\\\\\\
- -- @RELEASETYPE release\\\\\\\\\\\\\\\
- -- @SKU Bootstrap\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local temp_kernel = [[\\\\\\\\\\\\\\\
- -- Halt the system completely, yield all coroutines\\\\\\\\\\\\\\\
- local function halt()\\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- coroutine.create(function() while true do coroutine.yield() end end)\\\\\\\\\\\\\\\
- coroutine.yield()\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- Low-level routines\\\\\\\\\\\\\\\
- function traverseKey(array, text)\\\\\\\\\\\\\\\
- for k,v in pairs(array) do\\\\\\\\\\\\\\\
- if v == text then\\\\\\\\\\\\\\\
- return true, k\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false, nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function traverseValue(array, text)\\\\\\\\\\\\\\\
- for k,v in pairs(array) do\\\\\\\\\\\\\\\
- if k == text then\\\\\\\\\\\\\\\
- return true, v\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false, nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function findKey(array, text)\\\\\\\\\\\\\\\
- for k,v in pairs(array) do\\\\\\\\\\\\\\\
- if k == text then\\\\\\\\\\\\\\\
- return true, k\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false, nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function findValue(array, text)\\\\\\\\\\\\\\\
- for k,v in pairs(array) do\\\\\\\\\\\\\\\
- if v == text then\\\\\\\\\\\\\\\
- return true, v\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false, nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function queryForKey(array, text)\\\\\\\\\\\\\\\
- for k,v in pairs(array) do\\\\\\\\\\\\\\\
- if string.find(k, text) then\\\\\\\\\\\\\\\
- return true, k\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false, nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function queryForValue(array, text)\\\\\\\\\\\\\\\
- for k,v in pairs(array) do\\\\\\\\\\\\\\\
- if string.find(v, text) then\\\\\\\\\\\\\\\
- return true, v\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false, nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function stringToBytes(str)\\\\\\\\\\\\\\\
- return string.byte(str, 1, str:len())\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function bytesToString(...)\\\\\\\\\\\\\\\
- return string.char(...)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function iterateFileLines(path)\\\\\\\\\\\\\\\
- local handle = fs.open(path, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- local commands = {}\\\\\\\\\\\\\\\
- local line = handle.readLine()\\\\\\\\\\\\\\\
- while line do\\\\\\\\\\\\\\\
- commands[#commands + 1] = line\\\\\\\\\\\\\\\
- line = handle.readLine()\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- handle.close()\\\\\\\\\\\\\\\
- return commands\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- Clear the screen\\\\\\\\\\\\\\\
- function clear()\\\\\\\\\\\\\\\
- term.clear()\\\\\\\\\\\\\\\
- term.setCursorPos(1,1)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- Shut the system down safely.\\\\\\\\\\\\\\\
- function shutdown()\\\\\\\\\\\\\\\
- gui.printBootSuccess(\\\\\\\\\\\\\\\"System is ready for shutdown\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- sleep(1.5)\\\\\\\\\\\\\\\
- os.shutdown()\\\\\\\\\\\\\\\
- halt()\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function reboot()\\\\\\\\\\\\\\\
- gui.printBootSuccess(\\\\\\\\\\\\\\\"System is rebooting\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- sleep(1.5)\\\\\\\\\\\\\\\
- os.reboot()\\\\\\\\\\\\\\\
- halt()\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- Crash the system\\\\\\\\\\\\\\\
- function crashReport(text)\\\\\\\\\\\\\\\
- printError(\\\\\\\\\\\\\\\"[ ! ] Fatal error (\\\\\\\\\\\\\\\"..text..\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- printError(\\\\\\\\\\\\\\\"[ ! ] HALTING EXECUTION!\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- halt()\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- Import a file\\\\\\\\\\\\\\\
- function import(file)\\\\\\\\\\\\\\\
- if fs.exists(file) and not fs.isDir(file) then\\\\\\\\\\\\\\\
- return os.loadAPI(file)\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- log.write(\\\\\\\\\\\\\\\"Failed to load \\\\\\\\\\\\\\\"..file..\\\\\\\\\\\\\\\" as an API\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- return false\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- Require a file as a Lua module\\\\\\\\\\\\\\\
- function require(file) -- A primitive require\\\\\\\\\\\\\\\
- if fs.exists(file) and not fs.isDir(file) then\\\\\\\\\\\\\\\
- return dofile(file)\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- log.write(\\\\\\\\\\\\\\\"Failed to load \\\\\\\\\\\\\\\"..file..\\\\\\\\\\\\\\\" as an module\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- return nil\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- API hook\\\\\\\\\\\\\\\
- function APIHook(t)\\\\\\\\\\\\\\\
- if t then\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- -- Not loaded\\\\\\\\\\\\\\\
- if import(\\\\\\\\\\\\\\\"/system/api/\\\\\\\\\\\\\\\"..t) then\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- -- Load system libraries\\\\\\\\\\\\\\\
- function loadAssemblies(dir)\\\\\\\\\\\\\\\
- local flist = fs.list(dir)\\\\\\\\\\\\\\\
- for _, file in ipairs(flist) do\\\\\\\\\\\\\\\
- sleep(0.25)\\\\\\\\\\\\\\\
- kernel.import(dir..\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\"..file) -- attempting to hook the file\\\\\\\\\\\\\\\
- gui.printBootSuccess(\\\\\\\\\\\\\\\"Assembly \\\\\\\\\\\\\\\"..file..\\\\\\\\\\\\\\\" hooked into RAM!\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printFile(file)\\\\\\\\\\\\\\\
- if fs.exists(file) and not fs.isDir(file) then\\\\\\\\\\\\\\\
- local handle = fs.open(file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- local contents = handle.readAll()\\\\\\\\\\\\\\\
- handle.close()\\\\\\\\\\\\\\\
- return contents\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function getURLContents(url)\\\\\\\\\\\\\\\
- local handlex = http.get(url)\\\\\\\\\\\\\\\
- local contents = handlex.readAll()\\\\\\\\\\\\\\\
- handlex.close()\\\\\\\\\\\\\\\
- return contents\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function getFile(file, url, overwrite)\\\\\\\\\\\\\\\
- if not fs.exists(file) then\\\\\\\\\\\\\\\
- local handle = fs.open(file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- handle.writeLine(getURLContents(url))\\\\\\\\\\\\\\\
- handle.close()\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- elseif overwrite and not fs.isDir(file) then\\\\\\\\\\\\\\\
- local handle = fs.open(file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- handle.writeLine(getURLContents(url))\\\\\\\\\\\\\\\
- handle.close()\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- return false\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function secureInput(invite, definition)\\\\\\\\\\\\\\\
- write(invite..\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- local input = read(\\\\\\\\\\\\\\\"*\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- if input == definition then\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- return false\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- ]]\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local temp_gui = [[\\\\\\\\\\\\\\\
- function clearScreen(color)\\\\\\\\\\\\\\\
- term.setBackgroundColor(color or colors.black)\\\\\\\\\\\\\\\
- kernel.clear()\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function button(text, x1, x2, y)\\\\\\\\\\\\\\\
- term.setCursorPos(x1, y)\\\\\\\\\\\\\\\
- print(text)\\\\\\\\\\\\\\\
- local a, b, xx, yy = os.pullEvent(\\\\\\\\\\\\\\\"mouse_click\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- if (xx >= x1 and xx <= x2 and yy == y) then\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- return false\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function counter(text, y)\\\\\\\\\\\\\\\
- for i=1,100 do\\\\\\\\\\\\\\\
- sleep(0.1)\\\\\\\\\\\\\\\
- term.setCursorPos(1, y)\\\\\\\\\\\\\\\
- print(text..\\\\\\\\\\\\\\\" [\\\\\\\\\\\\\\\"..tostring(i)..\\\\\\\\\\\\\\\"%]\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function drawProgress(txt, y)\\\\\\\\\\\\\\\
- term.setCursorPos(4, 4)\\\\\\\\\\\\\\\
- print(txt)\\\\\\\\\\\\\\\
- term.setCursorPos(1, y)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"[ ]\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setCursorPos(2, y)\\\\\\\\\\\\\\\
- textutils.slowPrint(\\\\\\\\\\\\\\\"==============================]\\\\\\\\\\\\\\\", 10)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function drawProgressAlt(color)\\\\\\\\\\\\\\\
- term.setCursorPos(4, 10)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"#-------------------------------------------#\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setCursorPos(4, 11)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"| |\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setCursorPos(4, 12)\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\"#-------------------------------------------#\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setBackgroundColor(color or colors.yellow)\\\\\\\\\\\\\\\
- term.setCursorPos(5, 11)\\\\\\\\\\\\\\\
- textutils.slowWrite(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\", 10)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printColoredTextLine(y, txt, bg, fg)\\\\\\\\\\\\\\\
- term.setCursorPos(1, y)\\\\\\\\\\\\\\\
- term.setBackgroundColor(bg or colors.lightGray)\\\\\\\\\\\\\\\
- term.write(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setCursorPos(1, y)\\\\\\\\\\\\\\\
- term.setTextColor(fg or colors.black)\\\\\\\\\\\\\\\
- print(txt)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printBootInfo(i)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"[ \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.cyan)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"* \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"] \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..i)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printBootWarning(w)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"[ \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.orange)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"! \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"] \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..w)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printBootSuccess(wa)\\\\\\\\\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"[ \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lime)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"v \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"] \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- print(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..wa)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printAppInfo(header, msg)\\\\\\\\\\\\\\\
- term.setTextColor(colors.cyan)\\\\\\\\\\\\\\\
- write(header..\\\\\\\\\\\\\\\": \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- print(msg)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printAppWarning(header, msg)\\\\\\\\\\\\\\\
- term.setTextColor(colors.red)\\\\\\\\\\\\\\\
- write(header..\\\\\\\\\\\\\\\": \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.orange)\\\\\\\\\\\\\\\
- print(msg)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printAppSuccess(header, msg)\\\\\\\\\\\\\\\
- term.setTextColor(colors.lime)\\\\\\\\\\\\\\\
- write(header..\\\\\\\\\\\\\\\": \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.green)\\\\\\\\\\\\\\\
- print(msg)\\\\\\\\\\\\\\\
- term.setTextColor(colors.white)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function request(req)\\\\\\\\\\\\\\\
- while true do\\\\\\\\\\\\\\\
- term.setTextColor(colors.cyan)\\\\\\\\\\\\\\\
- write(req .. \\\\\\\\\\\\\\\"? \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"(\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lime)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"Y\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.red)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\"N\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
- write(\\\\\\\\\\\\\\\") \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- local presel=read()\\\\\\\\\\\\\\\
- if presel==\\\\\\\\\\\\\\\"Y\\\\\\\\\\\\\\\" or presel==\\\\\\\\\\\\\\\"y\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\
- return true\\\\\\\\\\\\\\\
- elseif presel==\\\\\\\\\\\\\\\"N\\\\\\\\\\\\\\\" or presel==\\\\\\\\\\\\\\\"n\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\
- return false\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function drawImg(path, x, y)\\\\\\\\\\\\\\\
- if fs.exists(path) and not fs.isDir(path) then\\\\\\\\\\\\\\\
- local img = paintutils.loadImage(path)\\\\\\\\\\\\\\\
- paintutils.drawImage(img, x, y)\\\\\\\\\\\\\\\
- else\\\\\\\\\\\\\\\
- gui.printAppWarning(\\\\\\\\\\\\\\\"gui\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"image not found\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- function printColored(text, color)\\\\\\\\\\\\\\\
- local tmp = term.getTextColor()\\\\\\\\\\\\\\\
- term.setTextColor(color)\\\\\\\\\\\\\\\
- print(text)\\\\\\\\\\\\\\\
- term.setTextColor(tmp)\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- ]]\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- if not fs.exists(\\\\\\\\\\\\\\\"/.tmp\\\\\\\\\\\\\\\") then\\\\\\\\\\\\\\\
- fs.makeDir(\\\\\\\\\\\\\\\"/.tmp\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- local h_kernel = fs.open(\\\\\\\\\\\\\\\"/.tmp/kernel\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- local h_gui = fs.open(\\\\\\\\\\\\\\\"/.tmp/gui\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- h_kernel.writeLine(temp_kernel)\\\\\\\\\\\\\\\
- h_kernel.close()\\\\\\\\\\\\\\\
- h_gui.writeLine(temp_gui)\\\\\\\\\\\\\\\
- h_gui.close()\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- os.version = function()\\\\\\\\\\\\\\\
- return \\\\\\\\\\\\\\\"Tesseract Bootstrap 1.0\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
- end\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- os.loadAPI(\\\\\\\\\\\\\\\"/.tmp/kernel\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- os.loadAPI(\\\\\\\\\\\\\\\"/.tmp/gui\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- fs.delete(\\\\\\\\\\\\\\\"/.tmp/kernel\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- fs.delete(\\\\\\\\\\\\\\\"/.tmp/gui\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- gui.printAppSuccess(\\\\\\\\\\\\\\\"tesseract\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"bootstrap kernel loaded\\\\\\\\\\\\\\\")\\\\\\\"\\\",\\\
- }\",\
- \"F:kernel.map\",\
- \"\\\"-- Darwin native API\\\\\\\
- \\\\\\\
- -- LOCALS\\\\\\\
- \\\\\\\
- -- declare bug check codes\\\\\\\
- local tmp_kc = {}\\\\\\\
- tmp_kc[0x0000] = \\\\\\\"UNDEFINED_EXCEPTION\\\\\\\"\\\\\\\
- tmp_kc[0x0001] = \\\\\\\"KERNEL_INTEGRITY_VIOLATION\\\\\\\"\\\\\\\
- tmp_kc[0x0002] = \\\\\\\"KERNEL_ASSEMBLY_NOT_ACCESSIBLE\\\\\\\"\\\\\\\
- tmp_kc[0x0003] = \\\\\\\"FIRMWARE_VERSION_INCOMPATIBLE\\\\\\\"\\\\\\\
- tmp_kc[0x0004] = \\\\\\\"ATTEMPTED_KERNEL_ENVIRONMENT_BYPASS\\\\\\\"\\\\\\\
- tmp_kc[0x0005] = \\\\\\\"ATTEMPTED_KERNEL_STRUCT_MODIFICATION\\\\\\\"\\\\\\\
- tmp_kc[0xFFFE] = \\\\\\\"DELIBERATELY_THROWN_EXCEPTION\\\\\\\"\\\\\\\
- tmp_kc[0xFFFF] = \\\\\\\"UNHANDLED_USER_MODE_EXCEPTION\\\\\\\"\\\\\\\
- \\\\\\\
- -- handle the bug check codes\\\\\\\
- local function handleBugCheckCode(code)\\\\\\\
- if code > 0xFFFFFFFF then\\\\\\\
- return \\\\\\\"0xFFFFFFFF\\\\\\\"\\\\\\\
- end\\\\\\\
- local h = \\\\\\\"0x00000000\\\\\\\"\\\\\\\
- local code_s = string.format(\\\\\\\"%X\\\\\\\", code)\\\\\\\
- return string.format(\\\\\\\"%s%s\\\\\\\", string.sub(h, 1, h:len() - code_s:len()), code_s)\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function getCodeID(c)\\\\\\\
- if code > 0xFFFFFFFF then\\\\\\\
- return tmp_kc[0x00000000]\\\\\\\
- end\\\\\\\
- return tmp_kc[c] or tmp_kc[0x00000000]\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function handleBootMessage(str)\\\\\\\
- local s1 = \\\\\\\" \\\\\\\"\\\\\\\
- local n1 = s1:len()\\\\\\\
- local n2 = str:len()\\\\\\\
- local s2 = string.sub(s1, 1, n1-n2)\\\\\\\
- return \\\\\\\" \\\\\\\"..str..s2..\\\\\\\" \\\\\\\"\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- GLOBALS\\\\\\\
- \\\\\\\
- -- declare log function\\\\\\\
- __declare(\\\\\\\"log\\\\\\\", function(l)\\\\\\\
- if not fs.exists(\\\\\\\"/etc/darwin.log\\\\\\\") then\\\\\\\
- x = fs.open(\\\\\\\"/etc/darwin.log\\\\\\\", \\\\\\\"w\\\\\\\")\\\\\\\
- else\\\\\\\
- x = fs.open(\\\\\\\"/etc/darwin.log\\\\\\\", \\\\\\\"a\\\\\\\")\\\\\\\
- end\\\\\\\
- x.writeLine(tostring(os.day())..\\\\\\\"d:\\\\\\\"..textutils.formatTime(os.time(), true)..\\\\\\\" | \\\\\\\"..l)\\\\\\\
- x.close()\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- declare bug check stub\\\\\\\
- __declare(\\\\\\\"__kstop\\\\\\\", function(code, p1, p2, p3, p4)\\\\\\\
- os.pullEvent = os.pullEventRaw\\\\\\\
- local code_a = 0x00000000\\\\\\\
- if tmp_kc[code] ~= nil then\\\\\\\
- code_a = code\\\\\\\
- end\\\\\\\
- \\\\\\\
- t = string.format(\\\\\\\"KSTOP CALLED! %s %s %s %s %s %s\\\\\\\", handleBugCheckCode(code_a), tmp_kc[code_a], tostring(p1), tostring(p2), tostring(p3), tostring(p4))\\\\\\\
- log(t)\\\\\\\
- \\\\\\\
- if not __DEBUG then\\\\\\\
- os.reboot()\\\\\\\
- end\\\\\\\
- \\\\\\\
- term.setBackgroundColor(colors.blue)\\\\\\\
- term.setTextColor(colors.white)\\\\\\\
- term.clear()\\\\\\\
- term.setCursorPos(1,1)\\\\\\\
- \\\\\\\
- x = string.format([[\\\\\\\
- The system has encountered an unrecoverable error.\\\\\\\
- Your computer needs to be restarted.\\\\\\\
- \\\\\\\
- Please write down the following parameters\\\\\\\
- and send them to the Darwin development team:\\\\\\\
- \\\\\\\
- [%s] %s\\\\\\\
- \\\\\\\
- [1] %s\\\\\\\
- [2] %s\\\\\\\
- [3] %s\\\\\\\
- [4] %s\\\\\\\
- \\\\\\\
- 15 seconds until reboot.\\\\\\\
- ]], handleBugCheckCode(code_a), tmp_kc[code_a], tostring(p1), tostring(p2), tostring(p3), tostring(p4))\\\\\\\
- stdout(x..\\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
- sleep(15)\\\\\\\
- os.reboot()\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- declare executive\\\\\\\
- __declare(\\\\\\\"run\\\\\\\", function(ap)\\\\\\\
- return os.run(getfenv(1), ap)\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- declare device IDs\\\\\\\
- local d = {}\\\\\\\
- d.MONITOR = \\\\\\\"monitor\\\\\\\"\\\\\\\
- d.FLOPPY = \\\\\\\"drive\\\\\\\"\\\\\\\
- d.MODEM = \\\\\\\"modem\\\\\\\"\\\\\\\
- d.PRINTER = \\\\\\\"printer\\\\\\\"\\\\\\\
- __declare(\\\\\\\"DEVICE_ID\\\\\\\", __kstruct(d))\\\\\\\
- \\\\\\\
- -- declare FS access flags\\\\\\\
- __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_READ\\\\\\\", \\\\\\\"r\\\\\\\")\\\\\\\
- __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_WRITE\\\\\\\", \\\\\\\"w\\\\\\\")\\\\\\\
- __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_APPEND\\\\\\\", \\\\\\\"a\\\\\\\")\\\\\\\
- __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_READBINARY\\\\\\\", \\\\\\\"rb\\\\\\\")\\\\\\\
- __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_WRITEBINARY\\\\\\\", \\\\\\\"wb\\\\\\\")\\\\\\\
- __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_APPENDBINARY\\\\\\\", \\\\\\\"ab\\\\\\\")\\\\\\\
- \\\\\\\
- -- declare stream descriptors\\\\\\\
- __declare(\\\\\\\"stdin\\\\\\\", read)\\\\\\\
- __declare(\\\\\\\"stdout\\\\\\\", write)\\\\\\\
- __declare(\\\\\\\"stderr\\\\\\\", printError)\\\\\\\
- \\\\\\\
- -- declare format descriptor\\\\\\\
- __declare(\\\\\\\"printf\\\\\\\", function(...)\\\\\\\
- stdout(string.format(...))\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- declare kernel descriptor\\\\\\\
- __declare(\\\\\\\"printk\\\\\\\", function(n, i)\\\\\\\
- local LOG_TYPES = {}\\\\\\\
- LOG_TYPES[0] = {colors.lightGray, \\\\\\\" i \\\\\\\"}\\\\\\\
- LOG_TYPES[1] = {colors.lime, \\\\\\\" v \\\\\\\"}\\\\\\\
- LOG_TYPES[2] = {colors.cyan, \\\\\\\" * \\\\\\\"}\\\\\\\
- LOG_TYPES[3] = {colors.orange, \\\\\\\" ! \\\\\\\"}\\\\\\\
- LOG_TYPES[4] = {colors.red, \\\\\\\"!!!\\\\\\\"}\\\\\\\
- if n > 4 then\\\\\\\
- n = 4\\\\\\\
- end\\\\\\\
- if __DEBUG then\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\
- term.setTextColor(colors.gray)\\\\\\\
- stdout(\\\\\\\"[\\\\\\\")\\\\\\\
- term.setTextColor(LOG_TYPES[n][1])\\\\\\\
- stdout(LOG_TYPES[n][2])\\\\\\\
- term.setTextColor(colors.gray)\\\\\\\
- stdout(\\\\\\\"]\\\\\\\")\\\\\\\
- if n == 4 then\\\\\\\
- term.setTextColor(colors.red)\\\\\\\
- else\\\\\\\
- term.setTextColor(colors.lightGray) \\\\\\\
- end\\\\\\\
- stdout(\\\\\\\" \\\\\\\"..i..\\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
- term.setTextColor(colors.white)\\\\\\\
- end\\\\\\\
- log(i)\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- declare kernel reader\\\\\\\
- __declare(\\\\\\\"kreadfile\\\\\\\", function(path)\\\\\\\
- local handle = fs.open(path, \\\\\\\"r\\\\\\\")\\\\\\\
- local content = handle.readAll()\\\\\\\
- handle.close()\\\\\\\
- return content\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- declare temporary kernel-mode loader\\\\\\\
- local function loadAssembly(path)\\\\\\\
- sleep(0.2)\\\\\\\
- if not fs.exists(path) or fs.isDir(path) then\\\\\\\
- printk(4, \\\\\\\"LOAD FAILED: \\\\\\\"..path)\\\\\\\
- return false\\\\\\\
- else\\\\\\\
- if dofile(path) then\\\\\\\
- ESI.UIColoredLine(18, handleBootMessage(\\\\\\\"Loaded: \\\\\\\"..path), colors.lightGray, colors.black)\\\\\\\
- return true\\\\\\\
- else\\\\\\\
- printk(4, \\\\\\\"LOAD FAILED: \\\\\\\"..path)\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- __declare(\\\\\\\"__kload\\\\\\\", function(path)\\\\\\\
- if not loadAssembly(path) then\\\\\\\
- return false, __kstop(0x00000002, path)\\\\\\\
- else\\\\\\\
- return true, nil\\\\\\\
- end\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- declare finalizer\\\\\\\
- __declare(\\\\\\\"__kfinalize\\\\\\\", function()\\\\\\\
- __declare(\\\\\\\"__kload\\\\\\\", nil)\\\\\\\
- __declare(\\\\\\\"__kread\\\\\\\", nil)\\\\\\\
- __declare(\\\\\\\"__kfinalize\\\\\\\", nil)\\\\\\\
- if __DEBUG then\\\\\\\
- __declare(\\\\\\\"__khandlecode\\\\\\\", handleBugCheckCode)\\\\\\\
- return\\\\\\\
- end\\\\\\\
- ESI.Finalize()\\\\\\\
- __declare(\\\\\\\"__declare\\\\\\\", nil)\\\\\\\
- __declare(\\\\\\\"__declare_api\\\\\\\", nil)\\\\\\\
- end)\\\\\\\
- \\\\\\\
- -- return\\\\\\\
- return 1\\\"\",\
- \"F:security.map\",\
- \"\\\"local oldReadOnly = _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"isReadOnly\\\\\\\"]\\\\\\\
- local oldMove = _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"move\\\\\\\"]\\\\\\\
- local oldDelete = _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"delete\\\\\\\"]\\\\\\\
- local oldHttpGet = _G[\\\\\\\"http\\\\\\\"][\\\\\\\"get\\\\\\\"]\\\\\\\
- local oldError = _G[\\\\\\\"error\\\\\\\"]\\\\\\\
- _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"isReadOnly\\\\\\\"] = function(path)\\\\\\\
- local find1 = shell.resolve(path) or path\\\\\\\
- if string.find(find1, \\\\\\\"boot\\\\\\\") or string.find(find1, \\\\\\\"bin\\\\\\\") or string.find(find1, \\\\\\\"lib\\\\\\\") then\\\\\\\
- log(\\\\\\\"Attempt to access system files!\\\\\\\")\\\\\\\
- if __DEBUG then\\\\\\\
- log(\\\\\\\"Superuser access verified.\\\\\\\")\\\\\\\
- return false\\\\\\\
- else\\\\\\\
- log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
- return true\\\\\\\
- end\\\\\\\
- elseif find1 == \\\\\\\"startup\\\\\\\" or find1 == \\\\\\\"/startup\\\\\\\" then\\\\\\\
- log(\\\\\\\"Attempt to access bootloader!\\\\\\\")\\\\\\\
- log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
- return true\\\\\\\
- end \\\\\\\
- return oldReadOnly(path)\\\\\\\
- end\\\\\\\
- _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"move\\\\\\\"] = function(path1, path2)\\\\\\\
- local find2 = shell.resolve(path1)\\\\\\\
- if string.find(find2, \\\\\\\"boot\\\\\\\") or string.find(find2, \\\\\\\"bin\\\\\\\") or string.find(find2, \\\\\\\"lib\\\\\\\") then\\\\\\\
- log(\\\\\\\"Attempt to access system files!\\\\\\\")\\\\\\\
- if __DEBUG then\\\\\\\
- log(\\\\\\\"Superuser access verified.\\\\\\\")\\\\\\\
- else\\\\\\\
- log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- elseif find2 == \\\\\\\"startup\\\\\\\" or find2 == \\\\\\\"/startup\\\\\\\" then\\\\\\\
- log(\\\\\\\"Attempt to access boot loader!\\\\\\\")\\\\\\\
- log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
- return nil\\\\\\\
- end \\\\\\\
- return oldMove(path1, path2)\\\\\\\
- end\\\\\\\
- _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"delete\\\\\\\"] = function(path)\\\\\\\
- local find3 = shell.resolve(path) or path\\\\\\\
- if string.find(find3, \\\\\\\"boot\\\\\\\") or string.find(find3, \\\\\\\"bin\\\\\\\") or string.find(find3, \\\\\\\"lib\\\\\\\") then\\\\\\\
- log(\\\\\\\"Attempt to access system files!\\\\\\\")\\\\\\\
- if __DEBUG then\\\\\\\
- log(\\\\\\\"Superuser access verified.\\\\\\\")\\\\\\\
- else\\\\\\\
- log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- elseif find3 == \\\\\\\"startup\\\\\\\" or find3 == \\\\\\\"/startup\\\\\\\" then\\\\\\\
- log(\\\\\\\"Attempt to access bootloader!\\\\\\\")\\\\\\\
- log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
- return nil\\\\\\\
- end \\\\\\\
- return oldDelete(path)\\\\\\\
- end\\\\\\\
- _G[\\\\\\\"http\\\\\\\"][\\\\\\\"get\\\\\\\"] = function(url, headers)\\\\\\\
- log(\\\\\\\"Downloaded contents of \\\\\\\"..url)\\\\\\\
- return oldHttpGet(url, headers)\\\\\\\
- end\\\"\",\
- }",
- "D:etc",
- "{\
- \"F:darwin.log\",\
- \"\\\"3d:3:06 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 3d:3:07 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:3:07 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 3d:3:07 | Darwin kernel loaded\\\\\\\
- 3d:3:45 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 3d:3:45 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:3:45 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 3d:3:45 | Darwin kernel loaded\\\\\\\
- 3d:4:45 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 3d:4:45 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:4:46 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 3d:4:46 | Darwin kernel loaded\\\\\\\
- 3d:5:10 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 3d:5:10 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:5:11 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 3d:5:11 | Darwin kernel loaded\\\\\\\
- 3d:5:46 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 3d:5:47 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:5:47 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 3d:5:48 | Darwin kernel loaded\\\\\\\
- 3d:9:37 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 3d:9:37 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:9:37 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 3d:9:38 | Darwin kernel loaded\\\\\\\
- 3d:10:21 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 3d:10:21 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:10:21 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 3d:10:22 | Darwin kernel loaded\\\\\\\
- 3d:11:06 | Downloaded contents of https://pastebin.com/raw/wFgCiYkY\\\\\\\
- 5d:12:33 | Attempt to access system files!\\\\\\\
- 5d:12:33 | Superuser access verified.\\\\\\\
- 5d:12:33 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 5d:12:33 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 5d:12:34 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 5d:12:34 | Darwin kernel loaded\\\\\\\
- 5d:15:25 | Attempt to access system files!\\\\\\\
- 5d:15:25 | Superuser access verified.\\\\\\\
- 5d:15:25 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 5d:15:25 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 5d:15:26 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 5d:15:26 | Darwin kernel loaded\\\\\\\
- 1d:6:04 | Attempt to access system files!\\\\\\\
- 1d:6:04 | Superuser access verified.\\\\\\\
- 1d:6:04 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 1d:6:05 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 1d:6:05 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 1d:6:06 | Darwin kernel loaded\\\\\\\
- 2d:3:52 | Attempt to access system files!\\\\\\\
- 2d:3:52 | Superuser access verified.\\\\\\\
- 2d:3:52 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 2d:3:52 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 2d:3:53 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 2d:3:53 | Darwin kernel loaded\\\\\\\
- 2d:4:27 | Attempt to access system files!\\\\\\\
- 2d:4:27 | Superuser access verified.\\\\\\\
- 2d:4:27 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
- 2d:4:27 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 2d:4:27 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 2d:4:28 | Darwin kernel loaded\\\\\\\
- 2d:12:34 | Darwin kernel loaded\\\\\\\
- 2d:13:01 | Darwin kernel loaded\\\\\\\
- 2d:13:25 | Darwin kernel loaded\\\\\\\
- 2d:14:01 | Darwin kernel loaded\\\\\\\
- 2d:15:32 | Darwin kernel loaded\\\\\\\
- 2d:16:36 | Darwin kernel loaded\\\\\\\
- 2d:19:15 | Attempt to access system files!\\\\\\\
- 2d:19:15 | Superuser access verified.\\\\\\\
- 2d:21:52 | Loaded system file: /lib/libdaemon.1.so\\\\\\\
- 2d:21:53 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 2d:21:53 | Loaded system file: /lib/libsha256_anavrins.1.so\\\\\\\
- 2d:21:53 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 2d:21:54 | Darwin kernel loaded\\\\\\\
- 2d:23:04 | Loaded system file: /lib/libdaemon.1.so\\\\\\\
- 2d:23:04 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
- 2d:23:05 | Loaded system file: /lib/libsha256_anavrins.1.so\\\\\\\
- 2d:23:05 | Loaded system file: /lib/libuser.2.so\\\\\\\
- 3d:0:06 | Assembly loaded: /lib/libdaemon.1.so\\\\\\\
- 3d:0:07 | Assembly loaded: /lib/libgui_txui.1.so\\\\\\\
- 3d:0:07 | Assembly loaded: /lib/libsha256_anavrins.1.so\\\\\\\
- 3d:0:07 | Assembly loaded: /lib/libuser.2.so\\\\\\\
- 3d:0:48 | Loaded: /lib/libdaemon.1.so\\\\\\\
- 3d:0:48 | Loaded: /lib/libgui_txui.1.so\\\\\\\
- 3d:0:49 | Loaded: /lib/libsha256_anavrins.1.so\\\\\\\
- 3d:0:49 | Loaded: /lib/libuser.2.so\\\\\\\
- 3d:5:39 | Loaded: /lib/libdaemon.1.so\\\\\\\
- 3d:5:39 | Loaded: /lib/libgui_txui.1.so\\\\\\\
- 3d:5:40 | Loaded: /lib/libsha256_anavrins.1.so\\\\\\\
- 3d:5:40 | Loaded: /lib/libuser.2.so\\\\\\\
- 3d:6:01 | Loaded: /lib/libdaemon.1.so\\\\\\\
- 3d:6:02 | Loaded: /lib/libgui_txui.1.so\\\\\\\
- 3d:6:02 | Loaded: /lib/libsha256_anavrins.1.so\\\\\\\
- 3d:6:02 | Loaded: /lib/libuser.2.so\\\\\\\
- 4d:18:12 | Downloaded contents of https://pastebin.com/raw/bggiSgmc\\\\\\\
- 5d:3:14 | Downloaded contents of https://pastebin.com/raw/ZGJGBJdg\\\\\\\
- 5d:20:19 | Attempt to access system files!\\\\\\\
- 5d:20:19 | Superuser access verified.\\\\\\\
- 6d:11:06 | Attempt to access system files!\\\\\\\
- 6d:11:06 | Superuser access verified.\\\\\\\
- 6d:11:11 | Attempt to access system files!\\\\\\\
- 6d:11:11 | Superuser access verified.\\\\\\\
- 6d:11:27 | Attempt to access system files!\\\\\\\
- 6d:11:27 | Superuser access verified.\\\\\\\
- 6d:11:46 | Attempt to access system files!\\\\\\\
- 6d:11:46 | Superuser access verified.\\\\\\\
- 6d:12:21 | Attempt to access system files!\\\\\\\
- 6d:12:21 | Superuser access verified.\\\\\\\
- 6d:19:51 | Attempt to access system files!\\\\\\\
- 6d:19:51 | Superuser access verified.\\\\\\\
- 6d:19:56 | Attempt to access system files!\\\\\\\
- 6d:19:56 | Superuser access verified.\\\"\",\
- \"F:process\",\
- \"\\\"\\\\\\\
- -- Setup process switching\\\\\\\
- local parentTerm = term.current()\\\\\\\
- local w,h = parentTerm.getSize()\\\\\\\
- \\\\\\\
- local tProcesses = {}\\\\\\\
- local nCurrentProcess = nil\\\\\\\
- local nRunningProcess = nil\\\\\\\
- local bShowMenu = false\\\\\\\
- local bWindowsResized = false\\\\\\\
- \\\\\\\
- local function selectProcess( n )\\\\\\\
- if nCurrentProcess ~= n then\\\\\\\
- if nCurrentProcess then\\\\\\\
- local tOldProcess = tProcesses[ nCurrentProcess ]\\\\\\\
- tOldProcess.window.setVisible( false )\\\\\\\
- end\\\\\\\
- nCurrentProcess = n\\\\\\\
- if nCurrentProcess then\\\\\\\
- local tNewProcess = tProcesses[ nCurrentProcess ]\\\\\\\
- tNewProcess.window.setVisible( true )\\\\\\\
- tNewProcess.bInteracted = true\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function setProcessTitle( n, sTitle )\\\\\\\
- tProcesses[ n ].sTitle = sTitle\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function resumeProcess( nProcess, sEvent, ... )\\\\\\\
- local tProcess = tProcesses[ nProcess ]\\\\\\\
- local sFilter = tProcess.sFilter\\\\\\\
- if sFilter == nil or sFilter == sEvent or sEvent == \\\\\\\"terminate\\\\\\\" then\\\\\\\
- local nPreviousProcess = nRunningProcess\\\\\\\
- nRunningProcess = nProcess\\\\\\\
- term.redirect( tProcess.terminal )\\\\\\\
- local ok, result = coroutine.resume( tProcess.co, sEvent, ... )\\\\\\\
- tProcess.terminal = term.current()\\\\\\\
- if ok then\\\\\\\
- tProcess.sFilter = result\\\\\\\
- else\\\\\\\
- printError( result )\\\\\\\
- end\\\\\\\
- nRunningProcess = nPreviousProcess\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function launchProcess( tProgramEnv, sProgramPath, ... )\\\\\\\
- local tProgramArgs = table.pack( ... )\\\\\\\
- local nProcess = #tProcesses + 1\\\\\\\
- local tProcess = {}\\\\\\\
- tProcess.sTitle = fs.getName( sProgramPath )\\\\\\\
- if bShowMenu then\\\\\\\
- tProcess.window = window.create( parentTerm, 1, 2, w, h-1, false )\\\\\\\
- else\\\\\\\
- tProcess.window = window.create( parentTerm, 1, 1, w, h, false )\\\\\\\
- end\\\\\\\
- tProcess.co = coroutine.create( function()\\\\\\\
- os.run( tProgramEnv, sProgramPath, table.unpack( tProgramArgs, 1, tProgramArgs.n ) )\\\\\\\
- if not tProcess.bInteracted then\\\\\\\
- term.setCursorBlink( false )\\\\\\\
- print( \\\\\\\"Press any key to continue\\\\\\\" )\\\\\\\
- os.pullEvent( \\\\\\\"char\\\\\\\" )\\\\\\\
- end\\\\\\\
- end )\\\\\\\
- tProcess.sFilter = nil\\\\\\\
- tProcess.terminal = tProcess.window\\\\\\\
- tProcess.bInteracted = false\\\\\\\
- tProcesses[ nProcess ] = tProcess\\\\\\\
- resumeProcess( nProcess )\\\\\\\
- return nProcess\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function cullProcess( nProcess )\\\\\\\
- local tProcess = tProcesses[ nProcess ]\\\\\\\
- if coroutine.status( tProcess.co ) == \\\\\\\"dead\\\\\\\" then\\\\\\\
- if nCurrentProcess == nProcess then\\\\\\\
- selectProcess( nil )\\\\\\\
- end\\\\\\\
- table.remove( tProcesses, nProcess )\\\\\\\
- if nCurrentProcess == nil then\\\\\\\
- if nProcess > 1 then\\\\\\\
- selectProcess( nProcess - 1 )\\\\\\\
- elseif #tProcesses > 0 then\\\\\\\
- selectProcess( 1 )\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return true\\\\\\\
- end\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function cullProcesses()\\\\\\\
- local culled = false\\\\\\\
- for n=#tProcesses,1,-1 do\\\\\\\
- culled = culled or cullProcess( n )\\\\\\\
- end\\\\\\\
- return culled\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Setup the main menu\\\\\\\
- local menuMainTextColor, menuMainBgColor, menuOtherTextColor, menuOtherBgColor\\\\\\\
- if parentTerm.isColor() then\\\\\\\
- menuMainTextColor, menuMainBgColor = colors.yellow, colors.black\\\\\\\
- menuOtherTextColor, menuOtherBgColor = colors.black, colors.gray\\\\\\\
- else\\\\\\\
- menuMainTextColor, menuMainBgColor = colors.white, colors.black\\\\\\\
- menuOtherTextColor, menuOtherBgColor = colors.black, colors.gray\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function redrawMenu()\\\\\\\
- if bShowMenu then\\\\\\\
- -- Draw menu\\\\\\\
- parentTerm.setCursorPos( 1, 1 )\\\\\\\
- parentTerm.setBackgroundColor( menuOtherBgColor )\\\\\\\
- parentTerm.clearLine()\\\\\\\
- for n=1,#tProcesses do\\\\\\\
- if n == nCurrentProcess then\\\\\\\
- parentTerm.setTextColor( menuMainTextColor )\\\\\\\
- parentTerm.setBackgroundColor( menuMainBgColor )\\\\\\\
- else\\\\\\\
- parentTerm.setTextColor( menuOtherTextColor )\\\\\\\
- parentTerm.setBackgroundColor( menuOtherBgColor )\\\\\\\
- end\\\\\\\
- parentTerm.write( \\\\\\\" \\\\\\\" .. tProcesses[n].sTitle .. \\\\\\\" \\\\\\\" )\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Put the cursor back where it should be\\\\\\\
- local tProcess = tProcesses[ nCurrentProcess ]\\\\\\\
- if tProcess then\\\\\\\
- tProcess.window.restoreCursor()\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function resizeWindows()\\\\\\\
- local windowY, windowHeight\\\\\\\
- if bShowMenu then\\\\\\\
- windowY = 2\\\\\\\
- windowHeight = h-1\\\\\\\
- else\\\\\\\
- windowY = 1\\\\\\\
- windowHeight = h\\\\\\\
- end\\\\\\\
- for n=1,#tProcesses do\\\\\\\
- local tProcess = tProcesses[n]\\\\\\\
- local window = tProcess.window\\\\\\\
- local x,y = tProcess.window.getCursorPos()\\\\\\\
- if y > windowHeight then\\\\\\\
- tProcess.window.scroll( y - windowHeight )\\\\\\\
- tProcess.window.setCursorPos( x, windowHeight )\\\\\\\
- end\\\\\\\
- tProcess.window.reposition( 1, windowY, w, windowHeight )\\\\\\\
- end\\\\\\\
- bWindowsResized = true\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function setMenuVisible( bVis )\\\\\\\
- if bShowMenu ~= bVis then\\\\\\\
- bShowMenu = bVis\\\\\\\
- resizeWindows()\\\\\\\
- redrawMenu()\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local process = {}\\\\\\\
- \\\\\\\
- function process.getFocus()\\\\\\\
- return nCurrentProcess\\\\\\\
- end\\\\\\\
- \\\\\\\
- function process.setFocus( n )\\\\\\\
- if type( n ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( n ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if n >= 1 and n <= #tProcesses then\\\\\\\
- selectProcess( n )\\\\\\\
- redrawMenu()\\\\\\\
- return true\\\\\\\
- end\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- \\\\\\\
- function process.getTitle( n )\\\\\\\
- if type( n ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( n ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if n >= 1 and n <= #tProcesses then\\\\\\\
- return tProcesses[n].sTitle\\\\\\\
- end\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function process.setTitle( n, sTitle )\\\\\\\
- if type( n ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( n ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if type( sTitle ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( sTitle ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if n >= 1 and n <= #tProcesses then\\\\\\\
- setProcessTitle( n, sTitle )\\\\\\\
- redrawMenu()\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function process.getCurrent()\\\\\\\
- return nRunningProcess\\\\\\\
- end\\\\\\\
- \\\\\\\
- function process.launch( tProgramEnv, sProgramPath, ... )\\\\\\\
- if type( tProgramEnv ) ~= \\\\\\\"table\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #1 (expected table, got \\\\\\\" .. type( tProgramEnv ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- if type( sProgramPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
- error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( sProgramPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
- end\\\\\\\
- local previousTerm = term.current()\\\\\\\
- setMenuVisible( (#tProcesses + 1) >= 2 )\\\\\\\
- local nResult = launchProcess( tProgramEnv, sProgramPath, ... )\\\\\\\
- redrawMenu()\\\\\\\
- term.redirect( previousTerm )\\\\\\\
- return nResult\\\\\\\
- end\\\\\\\
- \\\\\\\
- function process.getCount()\\\\\\\
- return #tProcesses\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Begin\\\\\\\
- parentTerm.clear()\\\\\\\
- setMenuVisible( false )\\\\\\\
- selectProcess( launchProcess( {\\\\\\\
- [\\\\\\\"shell\\\\\\\"] = shell,\\\\\\\
- [\\\\\\\"process\\\\\\\"] = process,\\\\\\\
- }, \\\\\\\"/bin/msh\\\\\\\" ) )\\\\\\\
- redrawMenu()\\\\\\\
- \\\\\\\
- -- Run processes\\\\\\\
- while #tProcesses > 0 do\\\\\\\
- -- Get the event\\\\\\\
- local tEventData = table.pack( os.pullEventRaw() )\\\\\\\
- local sEvent = tEventData[1]\\\\\\\
- if sEvent == \\\\\\\"term_resize\\\\\\\" then\\\\\\\
- -- Resize event\\\\\\\
- w,h = parentTerm.getSize()\\\\\\\
- resizeWindows()\\\\\\\
- redrawMenu()\\\\\\\
- \\\\\\\
- elseif sEvent == \\\\\\\"char\\\\\\\" or sEvent == \\\\\\\"key\\\\\\\" or sEvent == \\\\\\\"key_up\\\\\\\" or sEvent == \\\\\\\"paste\\\\\\\" or sEvent == \\\\\\\"terminate\\\\\\\" then\\\\\\\
- -- Keyboard event\\\\\\\
- -- Passthrough to current process\\\\\\\
- resumeProcess( nCurrentProcess, table.unpack( tEventData, 1, tEventData.n ) )\\\\\\\
- if cullProcess( nCurrentProcess ) then\\\\\\\
- setMenuVisible( #tProcesses >= 2 )\\\\\\\
- redrawMenu()\\\\\\\
- end\\\\\\\
- \\\\\\\
- elseif sEvent == \\\\\\\"mouse_click\\\\\\\" then\\\\\\\
- -- Click event\\\\\\\
- local button, x, y = tEventData[2], tEventData[3], tEventData[4]\\\\\\\
- if bShowMenu and y == 1 then\\\\\\\
- -- Switch process\\\\\\\
- local tabStart = 1\\\\\\\
- for n=1,#tProcesses do\\\\\\\
- local tabEnd = tabStart + string.len( tProcesses[n].sTitle ) + 1\\\\\\\
- if x >= tabStart and x <= tabEnd then\\\\\\\
- selectProcess( n )\\\\\\\
- redrawMenu()\\\\\\\
- break\\\\\\\
- end\\\\\\\
- tabStart = tabEnd + 1\\\\\\\
- end\\\\\\\
- else\\\\\\\
- -- Passthrough to current process\\\\\\\
- resumeProcess( nCurrentProcess, sEvent, button, x, (bShowMenu and y-1) or y )\\\\\\\
- if cullProcess( nCurrentProcess ) then\\\\\\\
- setMenuVisible( #tProcesses >= 2 )\\\\\\\
- redrawMenu()\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- elseif sEvent == \\\\\\\"mouse_drag\\\\\\\" or sEvent == \\\\\\\"mouse_up\\\\\\\" or sEvent == \\\\\\\"mouse_scroll\\\\\\\" then\\\\\\\
- -- Other mouse event\\\\\\\
- local p1, x, y = tEventData[2], tEventData[3], tEventData[4]\\\\\\\
- if not (bShowMenu and y == 1) then\\\\\\\
- -- Passthrough to current process\\\\\\\
- resumeProcess( nCurrentProcess, sEvent, p1, x, (bShowMenu and y-1) or y )\\\\\\\
- if cullProcess( nCurrentProcess ) then\\\\\\\
- setMenuVisible( #tProcesses >= 2 )\\\\\\\
- redrawMenu()\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- else\\\\\\\
- -- Other event\\\\\\\
- -- Passthrough to all processes\\\\\\\
- local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event\\\\\\\
- for n=1,nLimit do\\\\\\\
- resumeProcess( n, table.unpack( tEventData, 1, tEventData.n ) )\\\\\\\
- end\\\\\\\
- if cullProcesses() then\\\\\\\
- setMenuVisible( #tProcesses >= 2 )\\\\\\\
- redrawMenu()\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- if bWindowsResized then\\\\\\\
- -- Pass term_resize to all processes\\\\\\\
- local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event\\\\\\\
- for n=1,nLimit do\\\\\\\
- resumeProcess( n, \\\\\\\"term_resize\\\\\\\" )\\\\\\\
- end\\\\\\\
- bWindowsResized = false\\\\\\\
- if cullProcesses() then\\\\\\\
- setMenuVisible( #tProcesses >= 2 )\\\\\\\
- redrawMenu()\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- Shutdown\\\\\\\
- term.redirect( parentTerm )\\\"\",\
- \"D:resources\",\
- \"{\\\
- \\\"F:dialog_box.img\\\",\\\
- \\\"\\\\\\\"\\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- \\\\\\\\\\\\\\\
- 000000000000000000000000000000000000000000000\\\\\\\\\\\\\\\
- 0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
- 0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
- 0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
- 0777777777777777777777777777777777777777777707\\\\\\\\\\\\\\\
- 0777777777777777777777777777777777777777777707\\\\\\\\\\\\\\\
- 0777777777777777777777777777777777777777777707\\\\\\\\\\\\\\\
- 0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
- 777777777777777777777777777777777777777777777\\\\\\\"\\\",\\\
- }\",\
- }",
- "D:lib",
- "{\
- \"F:libdaemon.1.so\",\
- \"\\\"local libcode = [[\\\\\\\
- --a stateless iterator for use in for loops.\\\\\\\
- local function fIter (t, i)\\\\\\\
- i = not i and #t or (i - 1)\\\\\\\
- if i>0 then\\\\\\\
- return i, t[i]\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- --a table that stores all running daemons when we add a new value we first create a coroutine using the fFunc passed\\\\\\\
- local tBackground = setmetatable({},{\\\\\\\
- __newindex = function(t, k, v)\\\\\\\
- v.cRoutine=coroutine.create(v[1])\\\\\\\
- rawset(t, k, v)\\\\\\\
- end;\\\\\\\
- })\\\\\\\
- \\\\\\\
- --starts a new daemon\\\\\\\
- \\\\\\\
- --fFunc = function that runs in background\\\\\\\
- --fError = function ran if fFunc ever ends for any reason\\\\\\\
- \\\\\\\
- --returns identifier for new daemon\\\\\\\
- \\\\\\\
- function add(fFunc, fError)\\\\\\\
- tBackground[#tBackground + 1] = {fFunc, fError=fError}\\\\\\\
- return tBackground[#tBackground]\\\\\\\
- end\\\\\\\
- \\\\\\\
- --removes a running daemon\\\\\\\
- --internally this sets a flag telling the system to remove this daemon next time it loops through\\\\\\\
- --cRoutine = daemon to remove\\\\\\\
- \\\\\\\
- function rem(cRoutine)\\\\\\\
- cRoutine.sFilter=\\\\\\\"Daemon_internal_remove\\\\\\\"\\\\\\\
- end\\\\\\\
- \\\\\\\
- --returns identifiers for all running daemons\\\\\\\
- function getBackground()\\\\\\\
- return tBackground\\\\\\\
- end\\\\\\\
- \\\\\\\
- --internal variable, determines what level of depth we are in the daemon\\\\\\\
- local bPullMeta = false\\\\\\\
- \\\\\\\
- \\\\\\\
- --replacing the native os.pullEventRaw to function\\\\\\\
- __declare_api(\\\\\\\"os\\\\\\\", \\\\\\\"pullEventRaw\\\\\\\", function(sEvent)\\\\\\\
- local tData\\\\\\\
- \\\\\\\
- if bPullMeta then\\\\\\\
- return coroutine.yield(sEvent)\\\\\\\
- else\\\\\\\
- repeat\\\\\\\
- bPullMeta = true\\\\\\\
- tData = {coroutine.yield()}\\\\\\\
- \\\\\\\
- for iIndex, cRoutine in fIter, tBackground do --\\\\\\\
- if cRoutine.sFilter==tData[1] or not cRoutine.sFilter then\\\\\\\
- local bOk, sInnerEvent = coroutine.resume(cRoutine.cRoutine, unpack(tData))\\\\\\\
- if bOk then\\\\\\\
- cRoutine.sFilter = sInnerEvent\\\\\\\
- else\\\\\\\
- table.remove(tBackground, iIndex)\\\\\\\
- if cRoutine.fError then\\\\\\\
- cRoutine.fError(sInnerEvent, cRoutine)\\\\\\\
- end\\\\\\\
- end\\\\\\\
- elseif cRoutine.sFilter==\\\\\\\"Daemon_internal_remove\\\\\\\" then\\\\\\\
- table.remove(tBackground, iIndex)\\\\\\\
- end\\\\\\\
- end\\\\\\\
- bPullMeta = false\\\\\\\
- until tData[1] == sEvent or not sEvent\\\\\\\
- return unpack(tData)\\\\\\\
- end\\\\\\\
- end)\\\\\\\
- ]]\\\\\\\
- \\\\\\\
- persist(\\\\\\\"daemon\\\\\\\", libcode)\\\\\\\
- \\\\\\\
- return 1\\\"\",\
- \"F:libgui_txui.1.so\",\
- \"\\\"local libcode = [[\\\\\\\
- -- --\\\\\\\
- -- txUI - ComputerCraft User Interface Library\\\\\\\
- -- rel\\\\\\\
- -- tuogex\\\\\\\
- -- --\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Controller @static\\\\\\\
- -- Holds the windows of the program and handles events\\\\\\\
- -- --\\\\\\\
- Controller = {}\\\\\\\
- Controller.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009components = {};\\\\\\\
- \\\\009windows = {};\\\\\\\
- \\\\009termSize = {};\\\\\\\
- \\\\009spaceColor = colors.white;\\\\\\\
- \\\\009style = {};\\\\\\\
- \\\\009useNative = true;\\\\\\\
- \\\\009multiWindow = false;\\\\\\\
- \\\\009oldTerm = {};\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009drawAll = function(self)\\\\\\\
- \\\\009\\\\009local w, h = term.getSize()\\\\\\\
- \\\\009\\\\009Utils:drawRect(1, 1, w, h, self.spaceColor)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:draw()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009local drawQueue = {}\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009table.insert(drawQueue, 1, val)\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009for key, val in pairs(drawQueue) do\\\\\\\
- \\\\009\\\\009\\\\009val:draw()\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009appUpdate = function(self, eventTbl) end;\\\\\\\
- \\\\009startUpdateCycle = function(self)\\\\\\\
- \\\\009\\\\009Controller.termSize = term.getSize()\\\\\\\
- \\\\009\\\\009if (self.useNative) then\\\\\\\
- \\\\009\\\\009\\\\009Controller.oldTerm = term.current()\\\\\\\
- \\\\009\\\\009\\\\009term.redirect(term.native())\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009local handleEvent = function()\\\\\\\
- \\\\009\\\\009\\\\009local event\\\\\\\
- \\\\009\\\\009\\\\009repeat\\\\\\\
- \\\\009\\\\009\\\\009\\\\009event = {os.pullEventRaw()}\\\\\\\
- \\\\009\\\\009\\\\009until(event[1] ~= \\\\\\\"timer\\\\\\\")\\\\\\\
- \\\\009\\\\009\\\\009if (event[1] == \\\\\\\"terminate\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self:terminate()\\\\\\\
- \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"mouse_click\\\\\\\" or event[1] == \\\\\\\"monitor_touch\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:click(event[3], event[4], event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and Utils:inBounds(val.x, val.y, val.w, val.h, event[3], event[4]) and tostring(self.windows[1]) ~= tostring(val)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009table.remove(self.windows, key)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009table.insert(self.windows, 1, val)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009elseif (val.visible and Utils:inBounds(val.x, val.y, val.w, val.h, event[3], event[4]) and tostring(self.windows[1]) == tostring(val)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and Utils:inBounds(val.x, val.y, val.w, val.h, event[3], event[4]) and tostring(self.windows[1]) == tostring(val) and val:click(event[3], event[4], event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"mouse_scroll\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:scroll(event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:scroll(event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"mouse_drag\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:drag(event[3], event[4], event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:drag(event[3], event[4], event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"char\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:char(event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:char(event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"key\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:key(event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:key(event[2])) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:event(event)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:event(event)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009return event\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009while (true) do\\\\\\\
- \\\\009\\\\009\\\\009if (#self.windows == 0 and #self.components == 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self:exit()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009self:drawAll()\\\\\\\
- \\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009local eventTbl = handleEvent()\\\\\\\
- \\\\009\\\\009\\\\009self:appUpdate(eventTbl);\\\\\\\
- \\\\009\\\\009\\\\009--remove components marked for removal\\\\\\\
- \\\\009\\\\009\\\\009local removed = {}\\\\\\\
- \\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (val.removed) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009table.insert(removed, key)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009for key, val in pairs(removed) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self.components[val] = nil\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009--close windows marked for close\\\\\\\
- \\\\009\\\\009\\\\009local closed = {}\\\\\\\
- \\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (val.closed) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009table.insert(closed, key)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009for key, val in pairs(closed) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self.windows[val] = nil\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009setVisibleWindow = function(self, windowTbl)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009local wasVisible = val.visible\\\\\\\
- \\\\009\\\\009\\\\009val.visible = (tostring(val) == tostring(windowTbl) or self.multiWindow)\\\\\\\
- \\\\009\\\\009\\\\009if (not wasVisible and val.visible) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:onView()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009if (wasVisible and not val.visible) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:onHide()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009addWindow = function(self, windowTbl)\\\\\\\
- \\\\009\\\\009windowTbl.closed = false\\\\\\\
- \\\\009\\\\009windowTbl.visible = self.multiWindow\\\\\\\
- \\\\009\\\\009table.insert(self.windows, windowTbl)\\\\\\\
- \\\\009\\\\009if (#self.windows == 1) then\\\\\\\
- \\\\009\\\\009\\\\009self:setVisibleWindow(windowTbl)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009closeWindow = function(self, windowTbl)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
- \\\\009\\\\009\\\\009if (val == windowTbl) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val.closed = true\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009addComponent = function(self, componentTbl)\\\\\\\
- \\\\009\\\\009componentTbl.parent = self\\\\\\\
- \\\\009\\\\009componentTbl.parent.x = 1\\\\\\\
- \\\\009\\\\009componentTbl.parent.y = 1\\\\\\\
- \\\\009\\\\009componentTbl.parent.w = self.termSize[1]\\\\\\\
- \\\\009\\\\009componentTbl.parent.h = self.termSize[2]\\\\\\\
- \\\\009\\\\009componentTbl.removed = false\\\\\\\
- \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009removeComponent = function(self, componentTbl)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if (val == componentTbl) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val.removed = true\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009terminate = function(self)\\\\\\\
- \\\\009\\\\009self:exit()\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009exit = function(self)\\\\\\\
- \\\\009\\\\009if (self.useNative) then\\\\\\\
- \\\\009\\\\009\\\\009term.redirect(self.oldTerm)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009term.setBackgroundColor(colors.black)\\\\\\\
- \\\\009\\\\009term.clear()\\\\\\\
- \\\\009\\\\009term.setCursorPos(1, 1)\\\\\\\
- \\\\009\\\\009error()\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009cloneComponent = function(self, obj, copied)\\\\\\\
- \\\\009\\\\009if type(obj) ~= 'table' then\\\\\\\
- \\\\009\\\\009\\\\009return obj\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009if copied and copied[obj] then\\\\\\\
- \\\\009\\\\009\\\\009return copied[obj]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009local c = copied or {}\\\\\\\
- \\\\009\\\\009local res = setmetatable({}, getmetatable(obj))\\\\\\\
- \\\\009\\\\009c[obj] = res\\\\\\\
- \\\\009\\\\009for k, v in pairs(obj) do\\\\\\\
- \\\\009\\\\009\\\\009res[self:cloneComponent(k, c)] = self:cloneComponent(v, c)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009return res\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009inheritComponent = function(self, obj, newTbl)\\\\\\\
- \\\\009\\\\009local oldComponent = self:cloneComponent(obj)\\\\\\\
- \\\\009\\\\009for k, v in pairs(newTbl) do\\\\\\\
- \\\\009\\\\009\\\\009oldComponent[k] = v\\\\\\\
- \\\\009\\\\009end \\\\\\\
- \\\\009\\\\009return oldComponent\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009setDefaultStyle = function(self, styleTbl)\\\\\\\
- \\\\009\\\\009self.style = styleTbl\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- Controller.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009return Controller.prototype[key]\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- setmetatable(Controller, Controller.mt)\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Utils @static\\\\\\\
- -- Utilities to aid in UI design\\\\\\\
- -- --\\\\\\\
- Utils = {}\\\\\\\
- Utils.prototype = {\\\\\\\
- \\\\009drawRect = function(self, x, y, w, h, color)\\\\\\\
- \\\\009\\\\009term.setBackgroundColor(color)\\\\\\\
- \\\\009\\\\009for pY = y, h - 1 + y, 1 do\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(x, pY)\\\\\\\
- \\\\009\\\\009\\\\009for pX = x, w - 1 + x, 1 do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009term.write(\\\\\\\" \\\\\\\")\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009alignText = function(self, alignment, textLength, x, w)\\\\\\\
- \\\\009\\\\009if (alignment == \\\\\\\"left\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009return x\\\\\\\
- \\\\009\\\\009elseif (alignment == \\\\\\\"center\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009return x + ((w - textLength) / 2)\\\\\\\
- \\\\009\\\\009elseif (alignment == \\\\\\\"right\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009return x + (w - textLength)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009limitText = function(self, text, limit, tail)\\\\\\\
- \\\\009\\\\009if (string.len(text) > limit) then\\\\\\\
- \\\\009\\\\009\\\\009return string.sub(text, 0, limit - string.len(tail)) .. tail\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return text\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009wrapText = function(self, text, limit)\\\\\\\
- \\\\009\\\\009local index = 0\\\\\\\
- \\\\009\\\\009return text:gsub(\\\\\\\"(%C?)\\\\\\\", function (w)\\\\\\\
- \\\\009\\\\009\\\\009index = index + 1\\\\\\\
- \\\\009\\\\009\\\\009return w .. (index % limit == 0 and \\\\\\\"\\\\\\\\n\\\\\\\" or \\\\\\\"\\\\\\\")\\\\\\\
- \\\\009\\\\009end)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009splitText = function(self, str, pat)\\\\\\\
- \\\\009\\\\009local t = {}\\\\\\\
- \\\\009\\\\009local fpat = \\\\\\\"(.-)\\\\\\\" .. pat\\\\\\\
- \\\\009\\\\009local last_end = 1\\\\\\\
- \\\\009\\\\009local s, e, cap = str:find(fpat, 1)\\\\\\\
- \\\\009\\\\009while s do\\\\\\\
- \\\\009\\\\009\\\\009if (s ~= 1 or cap ~= \\\\\\\"\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009table.insert(t,cap)\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009last_end = e + 1\\\\\\\
- \\\\009\\\\009\\\\009s, e, cap = str:find(fpat, last_end)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009if (last_end <= #str) then\\\\\\\
- \\\\009\\\\009\\\\009cap = str:sub(last_end)\\\\\\\
- \\\\009\\\\009\\\\009table.insert(t, cap)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009return t\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009inBounds = function(self, boundX, boundY, boundW, boundH, checkX, checkY)\\\\\\\
- \\\\009\\\\009local xInBound = (checkX >= boundX) and (checkX <= boundX + boundW - 1)\\\\\\\
- \\\\009\\\\009local yInBound = (checkY >= boundY) and (checkY <= boundY + boundH - 1)\\\\\\\
- \\\\009\\\\009return xInBound and yInBound\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- Utils.mt = {\\\\\\\
- \\\\009__index = function(table, key)\\\\\\\
- \\\\009\\\\009return Utils.prototype[key]\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- setmetatable(Utils, Utils.mt)\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Style\\\\\\\
- -- Contains default styles for components and windows\\\\\\\
- -- --\\\\\\\
- Style = {}\\\\\\\
- Style.prototype = {\\\\\\\
- \\\\009Window = {};\\\\\\\
- \\\\009Component = {};\\\\\\\
- \\\\009Panel = {};\\\\\\\
- \\\\009Button = {};\\\\\\\
- \\\\009Label = {};\\\\\\\
- \\\\009TextField = {};\\\\\\\
- \\\\009List = {};\\\\\\\
- \\\\009CheckBox = {};\\\\\\\
- \\\\009ProgressBar = {};\\\\\\\
- }\\\\\\\
- Style.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009return Style.prototype[key]\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function Style:new(styleTbl)\\\\\\\
- \\\\009setmetatable(styleTbl, Style.mt)\\\\\\\
- \\\\009return styleTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Window\\\\\\\
- -- Pretty self explainatory\\\\\\\
- -- --\\\\\\\
- Window = {}\\\\\\\
- Window.prototype = {\\\\\\\
- \\\\009-- vars\\\\\\\
- \\\\009bgColor = colors.lightGray;\\\\\\\
- \\\\009tlColor = colors.gray;\\\\\\\
- \\\\009activeTlColor = colors.blue;\\\\\\\
- \\\\009components = {};\\\\\\\
- \\\\009titleLabel = {};\\\\\\\
- \\\\009z = 0;\\\\\\\
- \\\\009x = 1;\\\\\\\
- \\\\009y = 1;\\\\\\\
- \\\\009h = 1;\\\\\\\
- \\\\009w = 1;\\\\\\\
- \\\\009draggable = false;\\\\\\\
- \\\\009lastClick = {};\\\\\\\
- \\\\009hasShadow = false;\\\\\\\
- \\\\009shadowColor = colors.black;\\\\\\\
- \\\\009visible = false;\\\\\\\
- \\\\009closed = false;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009--draw shadow\\\\\\\
- \\\\009\\\\009if (self.hasShadow) then\\\\\\\
- \\\\009\\\\009\\\\009Utils:drawRect(self.x + 1, self.y + 1, self.w, self.h, self.shadowColor)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009--drawPane\\\\\\\
- \\\\009\\\\009Utils:drawRect(self.x, self.y, self.w, self.h, self.bgColor)\\\\\\\
- \\\\009\\\\009--drawTitle\\\\\\\
- \\\\009\\\\009term.setBackgroundColor((self:isActive() and Controller.multiWindow) and self.activeTlColor or self.tlColor)\\\\\\\
- \\\\009\\\\009term.setCursorPos(self.x, self.y)\\\\\\\
- \\\\009\\\\009for pX = self.x, self.w + self.x - 1, 1 do\\\\\\\
- \\\\009\\\\009\\\\009term.write(\\\\\\\" \\\\\\\")\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009if (self.titleLabel.draw ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009self.titleLabel:draw()\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009--draw components\\\\\\\
- \\\\009\\\\009self:drawComponents()\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009drawComponents = function(self)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:draw()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009setTitleLabel = function(self, newLabel)\\\\\\\
- \\\\009\\\\009newLabel.parent = self\\\\\\\
- \\\\009\\\\009setmetatable(newLabel, Label.tlmt)\\\\\\\
- \\\\009\\\\009self.titleLabel = newLabel\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009addComponent = function(self, componentTbl)\\\\\\\
- \\\\009\\\\009componentTbl.parent = self\\\\\\\
- \\\\009\\\\009componentTbl.removed = false\\\\\\\
- \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009removeComponent = function(self, componentTbl)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if (val == componentTbl) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val.removed = true\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009close = function(self)\\\\\\\
- \\\\009\\\\009Controller:closeWindow(self)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009click = function(self, x, y)\\\\\\\
- \\\\009\\\\009if (self.draggable and ((x >= self.x) and (x <= (self.x + self.w - 1)) and (y >= self.y) and (y <= self.y))) then\\\\\\\
- \\\\009\\\\009\\\\009self.lastClick.x = x\\\\\\\
- \\\\009\\\\009\\\\009self.lastClick.y = y\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009self.lastClick.x = nil\\\\\\\
- \\\\009\\\\009\\\\009self.lastClick.y = nil\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:click(x, y)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009return (self.draggable and ((x >= self.x) and (x <= (self.x + self.w - 1)) and (y >= self.y) and (y <= self.y)))\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009key = function(self, keyCode)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:key(keyCode)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009char = function(self, char)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:char(char)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009scroll = function(self, direction)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:scroll(direction)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009drag = function(self, x, y)\\\\\\\
- \\\\009\\\\009if (self.draggable and self.lastClick.x ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009self.x = self.x + x - self.lastClick.x\\\\\\\
- \\\\009\\\\009\\\\009self.y = self.y + y - self.lastClick.y\\\\\\\
- \\\\009\\\\009\\\\009self.lastClick.x = x\\\\\\\
- \\\\009\\\\009\\\\009self.lastClick.y = y\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:drag(x, y)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009event = function(self, eventTbl)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:event(eventTbl)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009onView = function(self)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009onHide = function(self)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self)\\\\\\\
- \\\\009\\\\009local removed = {}\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if (val.removed) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009table.insert(removed, key)\\\\\\\
- \\\\009\\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009for key, val in pairs(removed) do\\\\\\\
- \\\\009\\\\009\\\\009self.components[val] = nil\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009isActive = function(self)\\\\\\\
- \\\\009\\\\009return Controller.windows[1] == self\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- Window.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (Controller.style.Window[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Controller.style.Window[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Window.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function Window:new(windowTbl)\\\\\\\
- \\\\009setmetatable(windowTbl, Window.mt)\\\\\\\
- \\\\009windowTbl.components = {}\\\\\\\
- \\\\009return windowTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Component @abstract\\\\\\\
- -- Abstract class used to represent components in a window\\\\\\\
- -- --\\\\\\\
- Component = {}\\\\\\\
- Component.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009x = 1;\\\\\\\
- \\\\009y = 1;\\\\\\\
- \\\\009h = 1;\\\\\\\
- \\\\009w = 1;\\\\\\\
- \\\\009z = 0;\\\\\\\
- \\\\009parent = {};\\\\\\\
- \\\\009removed = false;\\\\\\\
- \\\\009visible = true;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self) end;\\\\\\\
- \\\\009click = function(self, x, y, button) return false end;\\\\\\\
- \\\\009key = function(self, keyCode) return false end;\\\\\\\
- \\\\009char = function(self, char) return false end;\\\\\\\
- \\\\009scroll = function(self, direction) return false end;\\\\\\\
- \\\\009drag = function(self, x, y, button) return false end;\\\\\\\
- \\\\009event = function(self, eventTbl) return false end;\\\\\\\
- \\\\009update = function(self) return false end;\\\\\\\
- \\\\009termX = function(self) return self.x + self.parent.x - 1 end;\\\\\\\
- \\\\009termY = function(self) return self.y + self.parent.y - 1 end;\\\\\\\
- \\\\009setPos = function(self, x, y)\\\\\\\
- \\\\009\\\\009self.x = x;\\\\\\\
- \\\\009\\\\009self.y = y;\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009setSize = function(self, w, h)\\\\\\\
- \\\\009\\\\009self.w = w;\\\\\\\
- \\\\009\\\\009self.h = h;\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Panel\\\\\\\
- -- Pretty self explainatory\\\\\\\
- -- --\\\\\\\
- Panel = {}\\\\\\\
- Panel.prototype = {\\\\\\\
- \\\\009-- vars\\\\\\\
- \\\\009bgColor = colors.lightGray;\\\\\\\
- \\\\009components = {};\\\\\\\
- \\\\009z = 0;\\\\\\\
- \\\\009x = 1;\\\\\\\
- \\\\009y = 1;\\\\\\\
- \\\\009h = 1;\\\\\\\
- \\\\009w = 1;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009--drawPane\\\\\\\
- \\\\009\\\\009Utils:drawRect(self.x, self.y, self.w, self.h, self.bgColor)\\\\\\\
- \\\\009\\\\009--draw components\\\\\\\
- \\\\009\\\\009self:drawComponents()\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009drawComponents = function(self)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:draw()\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009addComponent = function(self, componentTbl)\\\\\\\
- \\\\009\\\\009componentTbl.parent = self\\\\\\\
- \\\\009\\\\009componentTbl.removed = false\\\\\\\
- \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009removeComponent = function(self, componentTbl)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if (val == componentTbl) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val.removed = true\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009close = function(self)\\\\\\\
- \\\\009\\\\009Controller:closeWindow(self)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009click = function(self, x, y)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:click(x, y)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009key = function(self, keyCode)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:key(keyCode)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009char = function(self, char)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:char(char)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009scroll = function(self, direction)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:scroll(direction)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009drag = function(self, x, y)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:drag(x, y)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009event = function(self, eventTbl)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val:event(eventTbl)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self)\\\\\\\
- \\\\009\\\\009local removed = {}\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if (val.removed) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009table.insert(removed, key)\\\\\\\
- \\\\009\\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009for key, val in pairs(removed) do\\\\\\\
- \\\\009\\\\009\\\\009self.components[val] = nil\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- Panel.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (Controller.style.Panel[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Controller.style.Panel[key]\\\\\\\
- \\\\009\\\\009elseif (Panel.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Panel.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function Panel:new(panelTbl)\\\\\\\
- \\\\009setmetatable(panelTbl, Panel.mt)\\\\\\\
- \\\\009panelTbl.components = {}\\\\\\\
- \\\\009return panelTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Button extends Component\\\\\\\
- -- A component that you can click\\\\\\\
- -- --\\\\\\\
- Button = {}\\\\\\\
- Button.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009h = 3;\\\\\\\
- \\\\009w = 16;\\\\\\\
- \\\\009bgColor = colors.lightBlue;\\\\\\\
- \\\\009textColor = colors.white;\\\\\\\
- \\\\009activeColor = colors.blue;\\\\\\\
- \\\\009activeTextColor = colors.white;\\\\\\\
- \\\\009active = false;\\\\\\\
- \\\\009text = \\\\\\\"txUI Button\\\\\\\";\\\\\\\
- \\\\009textAlign = \\\\\\\"center\\\\\\\";\\\\\\\
- \\\\009vertCenter = true;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009action = function(self) end;\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, (function(self) if (self.active) then return self.activeColor else return self.bgColor end end)(self))\\\\\\\
- \\\\009\\\\009term.setTextColor((function(self) if (self.active) then return self.activeTextColor else return self.textColor end end)(self))\\\\\\\
- \\\\009\\\\009local lines = #Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
- \\\\009\\\\009for k, v in ipairs(Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")) do\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))\\\\\\\
- \\\\009\\\\009\\\\009term.write(v)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009click = function (self, x, y)\\\\\\\
- \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
- \\\\009\\\\009\\\\009self.active = true\\\\\\\
- \\\\009\\\\009\\\\009self:action()\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009self.active = false\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self) return false end;\\\\\\\
- }\\\\\\\
- Button.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (Controller.style.Button[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Controller.style.Button[key]\\\\\\\
- \\\\009\\\\009elseif (Button.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Button.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function Button:new(buttonTbl)\\\\\\\
- \\\\009if (buttonTbl == nil) then\\\\\\\
- \\\\009\\\\009buttonTbl = self\\\\\\\
- \\\\009end\\\\\\\
- \\\\009setmetatable(buttonTbl, Button.mt)\\\\\\\
- \\\\009return buttonTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Label extends Component\\\\\\\
- -- A component that displays text\\\\\\\
- -- --\\\\\\\
- Label = {}\\\\\\\
- Label.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009h = 1;\\\\\\\
- \\\\009w = 16;\\\\\\\
- \\\\009bgColor = colors.white;\\\\\\\
- \\\\009textColor = colors.black;\\\\\\\
- \\\\009text = \\\\\\\"txUI Label\\\\\\\";\\\\\\\
- \\\\009textAlign = \\\\\\\"center\\\\\\\";\\\\\\\
- \\\\009vertCenter = true;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
- \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
- \\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
- \\\\009\\\\009local lines = #Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
- \\\\009\\\\009for k, v in ipairs(Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")) do\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))\\\\\\\
- \\\\009\\\\009\\\\009term.write(v)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self) return false end;\\\\\\\
- }\\\\\\\
- Label.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (Label.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Label.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- Label.tlmt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (key == \\\\\\\"w\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009return table.parent.w\\\\\\\
- \\\\009\\\\009elseif (key == \\\\\\\"bgColor\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009return table.parent.tlColor\\\\\\\
- \\\\009\\\\009elseif (Label.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Label.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function Label:new(labelTbl)\\\\\\\
- \\\\009if (labelTbl == nil) then\\\\\\\
- \\\\009\\\\009labelTbl = self\\\\\\\
- \\\\009end\\\\\\\
- \\\\009setmetatable(labelTbl, Label.mt)\\\\\\\
- \\\\009return labelTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- TextField extends Component\\\\\\\
- -- A component that allows for text input\\\\\\\
- -- --\\\\\\\
- TextField = {}\\\\\\\
- TextField.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009h = 1;\\\\\\\
- \\\\009w = 16;\\\\\\\
- \\\\009bgColor = colors.white;\\\\\\\
- \\\\009textColor = colors.black;\\\\\\\
- \\\\009placeholderColor = colors.lightGray;\\\\\\\
- \\\\009placeholder = \\\\\\\"txUI TextField\\\\\\\";\\\\\\\
- \\\\009text = \\\\\\\"\\\\\\\";\\\\\\\
- \\\\009textAlign = \\\\\\\"left\\\\\\\";\\\\\\\
- \\\\009textMask = \\\\\\\"\\\\\\\";\\\\\\\
- \\\\009active = false;\\\\\\\
- \\\\009cursorPos = 0;\\\\\\\
- \\\\009displayOffset = 0;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
- \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
- \\\\009\\\\009if (self.active or string.len(self.text) ~= 0) then\\\\\\\
- \\\\009\\\\009\\\\009local toWrite = string.sub(self.text, self.displayOffset + 1, self.displayOffset + self.w)\\\\\\\
- \\\\009\\\\009\\\\009if (string.len(self.textMask) ~= 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009toWrite = string.gsub(toWrite, \\\\\\\"%C\\\\\\\", self.textMask)\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(toWrite), self:termX(), self.w), self:termY() + (self.h / 2))\\\\\\\
- \\\\009\\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
- \\\\009\\\\009\\\\009term.write(toWrite)\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009local toWrite = string.sub(self.placeholder, self.displayOffset + 1)\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(toWrite), self:termX(), self.w), self:termY() + (self.h / 2))\\\\\\\
- \\\\009\\\\009\\\\009term.setTextColor(self.placeholderColor)\\\\\\\
- \\\\009\\\\009\\\\009term.write(toWrite)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009term.setCursorBlink(self.active)\\\\\\\
- \\\\009\\\\009if (self.active) then\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.cursorPos - self.displayOffset, self:termY() + (self.h / 2))\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009click = function (self, x, y)\\\\\\\
- \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
- \\\\009\\\\009\\\\009self.active = true\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009self.active = false\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009action = function(self)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009key = function(self, keyCode)\\\\\\\
- \\\\009\\\\009if (self.active == false) then\\\\\\\
- \\\\009\\\\009\\\\009return\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009if (keyCode == keys.backspace) then\\\\\\\
- \\\\009\\\\009\\\\009if (self.cursorPos > 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self.text = string.sub(self.text, 1, self.cursorPos - 1) .. string.sub(self.text, self.cursorPos + 1)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self.cursorPos = self.cursorPos - 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (self.cursorPos - self.displayOffset < 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self:draw()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009elseif (keyCode == keys.left) then\\\\\\\
- \\\\009\\\\009\\\\009if (self.cursorPos > 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self.cursorPos = self.cursorPos - 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (self.cursorPos - self.displayOffset < 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self:draw()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009elseif (keyCode == keys.right) then\\\\\\\
- \\\\009\\\\009\\\\009if (self.cursorPos < string.len(self.text)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self.cursorPos = self.cursorPos + 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (self.cursorPos - self.displayOffset > self.w - 1) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009self:draw()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009elseif (keyCode == keys.enter) then\\\\\\\
- \\\\009\\\\009\\\\009self:action()\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009char = function(self, char)\\\\\\\
- \\\\009\\\\009if (self.active == false) then\\\\\\\
- \\\\009\\\\009\\\\009return\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009self.text = string.sub(self.text, 1, self.cursorPos) .. char .. string.sub(self.text, self.cursorPos + 1)\\\\\\\
- \\\\009\\\\009if (self.cursorPos - self.displayOffset > self.w - 2) then\\\\\\\
- \\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009self.cursorPos = self.cursorPos + 1\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self)\\\\\\\
- \\\\009\\\\009if (self.active) then\\\\\\\
- \\\\009\\\\009\\\\009self:draw()\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- TextField.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (TextField.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return TextField.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function TextField:new(textFieldTbl)\\\\\\\
- \\\\009if (textFieldTbl == nil) then\\\\\\\
- \\\\009\\\\009textFieldTbl = self\\\\\\\
- \\\\009end\\\\\\\
- \\\\009setmetatable(textFieldTbl, TextField.mt)\\\\\\\
- \\\\009return textFieldTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- List extends Component\\\\\\\
- -- A component that lets you hold lists of other components\\\\\\\
- -- --\\\\\\\
- List = {}\\\\\\\
- List.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009h = 5;\\\\\\\
- \\\\009w = 16;\\\\\\\
- \\\\009bgColor = colors.white;\\\\\\\
- \\\\009bgColorStripe = colors.lightGray;\\\\\\\
- \\\\009textColor = colors.black;\\\\\\\
- \\\\009textColorStripe = colors.black;\\\\\\\
- \\\\009activeColor = colors.gray;\\\\\\\
- \\\\009activeTextColor = colors.white;\\\\\\\
- \\\\009textAlign = \\\\\\\"left\\\\\\\";\\\\\\\
- \\\\009scrollBarColor = colors.gray;\\\\\\\
- \\\\009scrollBarTextColor = colors.white;\\\\\\\
- \\\\009scrollBar = true;\\\\\\\
- \\\\009wrapText = false;\\\\\\\
- \\\\009displayOffset = 0;\\\\\\\
- \\\\009components = {};\\\\\\\
- \\\\009active = false;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
- \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
- \\\\009\\\\009-- draw the components\\\\\\\
- \\\\009\\\\009local index = 1\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009val.w = self.w - (self.scrollBar and 1 or 0)\\\\\\\
- \\\\009\\\\009\\\\009val.y = self.displayOffset + index\\\\\\\
- \\\\009\\\\009\\\\009index = index + val.h\\\\\\\
- \\\\009\\\\009\\\\009if ((val.y > 0) and (val.y <= self.h)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:draw()\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009self.components[key] = val\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009-- draw the scroll bar\\\\\\\
- \\\\009\\\\009if (self.scrollBar) then\\\\\\\
- \\\\009\\\\009\\\\009Utils:drawRect(self:termX() + self.w - 1, self:termY(), 1, self.h, self.scrollBarColor)\\\\\\\
- \\\\009\\\\009\\\\009term.setBackgroundColor(self.scrollBarColor)\\\\\\\
- \\\\009\\\\009\\\\009term.setTextColor(self.scrollBarTextColor)\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - 1, self:termY())\\\\\\\
- \\\\009\\\\009\\\\009term.write(\\\\\\\"^\\\\\\\")\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - 1, self:termY() + self.h - 1)\\\\\\\
- \\\\009\\\\009\\\\009term.write(\\\\\\\"v\\\\\\\")\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009click = function (self, x, y)\\\\\\\
- \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
- \\\\009\\\\009\\\\009if ((val.y > 0) and (val.y <= self.h)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009val:click(x, y)\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
- \\\\009\\\\009\\\\009self.active = true\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009self.active = false\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009if (self.scrollBar) then\\\\\\\
- \\\\009\\\\009\\\\009if ((x == self:termX() + self.w - 1) and (y == self:termY())) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (self.displayOffset < 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009if ((x == self:termX() + self.w - 1) and (y == self:termY() + self.h - 1)) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (self.displayOffset > -#self.components + 1) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009scroll = function (self, direction)\\\\\\\
- \\\\009\\\\009if (self.active) then\\\\\\\
- \\\\009\\\\009\\\\009if (direction == -1) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (self.displayOffset < 0) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009if (direction == 1) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (self.displayOffset > -#self.components + 1) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009addComponent = function(self, componentTbl)\\\\\\\
- \\\\009\\\\009componentTbl.h = 1\\\\\\\
- \\\\009\\\\009componentTbl.w = self.w - (self.scrollBar and 1 or 0)\\\\\\\
- \\\\009\\\\009if (not self.wrapText) then\\\\\\\
- \\\\009\\\\009\\\\009componentTbl.text = Utils:limitText(componentTbl.text, componentTbl.w, \\\\\\\"...\\\\\\\")\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009if (string.len(componentTbl.text) > componentTbl.w) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009componentTbl.h = math.ceil(string.len(componentTbl.text) / componentTbl.w)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009componentTbl.text = Utils:wrapText(componentTbl.text, componentTbl.w)\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009componentTbl.bgColor = (#self.components % 2 == 0 and self.bgColor or self.bgColorStripe)\\\\\\\
- \\\\009\\\\009componentTbl.textColor = (#self.components % 2 == 0 and self.textColor or self.textColorStripe)\\\\\\\
- \\\\009\\\\009componentTbl.textAlign = self.textAlign\\\\\\\
- \\\\009\\\\009componentTbl.activeColor = self.activeColor\\\\\\\
- \\\\009\\\\009componentTbl.activeTextColor = self.activeTextColor\\\\\\\
- \\\\009\\\\009componentTbl.parent = self\\\\\\\
- \\\\009\\\\009componentTbl.removed = false\\\\\\\
- \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self) return false end;\\\\\\\
- }\\\\\\\
- List.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (List.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return List.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function List:new(listTbl)\\\\\\\
- \\\\009if (listTbl == nil) then\\\\\\\
- \\\\009\\\\009listTbl = self\\\\\\\
- \\\\009end\\\\\\\
- \\\\009setmetatable(listTbl, List.mt)\\\\\\\
- \\\\009listTbl.components = {}\\\\\\\
- \\\\009return listTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- Checkbox extends Component\\\\\\\
- -- A component that lets users make a boolean choice\\\\\\\
- -- --\\\\\\\
- Checkbox = {}\\\\\\\
- Checkbox.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009h = 1;\\\\\\\
- \\\\009w = 16;\\\\\\\
- \\\\009bgColor = colors.lightGray;\\\\\\\
- \\\\009boxColor = colors.white;\\\\\\\
- \\\\009textColor = colors.black;\\\\\\\
- \\\\009checkedChar = \\\\\\\"X\\\\\\\";\\\\\\\
- \\\\009checked = false;\\\\\\\
- \\\\009text = \\\\\\\"txUI Checkbox\\\\\\\";\\\\\\\
- \\\\009textPosition = \\\\\\\"right\\\\\\\";\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
- \\\\009\\\\009-- draw box and set label position\\\\\\\
- \\\\009\\\\009term.setBackgroundColor(self.boxColor)\\\\\\\
- \\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
- \\\\009\\\\009if (self.textPosition == \\\\\\\"right\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), 1, 1, self.boxColor)\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(self:termX(), self:termY())\\\\\\\
- \\\\009\\\\009\\\\009term.write(self.checked and self.checkedChar or \\\\\\\" \\\\\\\")\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + 2, self:termY())\\\\\\\
- \\\\009\\\\009elseif (self.textPosition == \\\\\\\"left\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009Utils:drawRect(self:termX() + self.w - 1, self:termY(), 1, 1, self.boxColor)\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - 1, self:termY())\\\\\\\
- \\\\009\\\\009\\\\009term.write(self.checked and self.checkedChar or \\\\\\\" \\\\\\\")\\\\\\\
- \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - string.len(self.text) - 2, self:termY())\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009-- draw label\\\\\\\
- \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
- \\\\009\\\\009term.write(self.text)\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009click = function (self, x, y)\\\\\\\
- \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
- \\\\009\\\\009\\\\009self.checked = not self.checked\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self) return false end;\\\\\\\
- }\\\\\\\
- Checkbox.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (Checkbox.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return Checkbox.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function Checkbox:new(checkboxTbl)\\\\\\\
- \\\\009if (checkboxTbl == nil) then\\\\\\\
- \\\\009\\\\009checkboxTbl = self\\\\\\\
- \\\\009end\\\\\\\
- \\\\009setmetatable(checkboxTbl, Checkbox.mt)\\\\\\\
- \\\\009return checkboxTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- -- --\\\\\\\
- -- ProgressBar extends Component\\\\\\\
- -- A component that shows progress\\\\\\\
- -- --\\\\\\\
- ProgressBar = {}\\\\\\\
- ProgressBar.prototype = {\\\\\\\
- \\\\009--vars\\\\\\\
- \\\\009h = 1;\\\\\\\
- \\\\009w = 16;\\\\\\\
- \\\\009val = 0;\\\\\\\
- \\\\009bgColor = colors.white;\\\\\\\
- \\\\009barColor = colors.lime;\\\\\\\
- \\\\009textColor = colors.black;\\\\\\\
- \\\\009barTextColor = colors.white;\\\\\\\
- \\\\009textAlign = \\\\\\\"center\\\\\\\";\\\\\\\
- \\\\009textMask = \\\\\\\"{val}%\\\\\\\";\\\\\\\
- \\\\009showText = true;\\\\\\\
- \\\\009vertCenter = true;\\\\\\\
- \\\\009--functions\\\\\\\
- \\\\009draw = function(self)\\\\\\\
- \\\\009\\\\009if (self.val > 100) then\\\\\\\
- \\\\009\\\\009\\\\009self.val = 100\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009local barWidth = self.w * (self.val / 100)\\\\\\\
- \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
- \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), barWidth, self.h, self.barColor)\\\\\\\
- \\\\009\\\\009if (self.showText) then\\\\\\\
- \\\\009\\\\009\\\\009local text = string.gsub(self.textMask, \\\\\\\"{val}\\\\\\\", tostring(self.val))\\\\\\\
- \\\\009\\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
- \\\\009\\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
- \\\\009\\\\009\\\\009local lines = #Utils:splitText(text, \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
- \\\\009\\\\009\\\\009for k, v in ipairs(Utils:splitText(text, \\\\\\\"\\\\\\\\n\\\\\\\")) do\\\\\\\
- \\\\009\\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))\\\\\\\
- \\\\009\\\\009\\\\009\\\\009local x, y = term.getCursorPos()\\\\\\\
- \\\\009\\\\009\\\\009\\\\009if (x - self:termX() < barWidth) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009term.setBackgroundColor(self.barColor)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009term.setTextColor(self.barTextColor)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009term.write(v)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009if (x - self:termX() + string.len(v) > barWidth) then\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009local overflow = x - self:termX() + string.len(v) - barWidth\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009local ax, ay = term.getCursorPos()\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.setCursorPos(ax - overflow, ay)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.write(string.sub(v, math.abs(string.len(v) - overflow) + 1))\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009\\\\009\\\\009term.write(v)\\\\\\\
- \\\\009\\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009\\\\009end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- \\\\009update = function(self) return false end;\\\\\\\
- }\\\\\\\
- ProgressBar.mt = {\\\\\\\
- \\\\009__index = function (table, key)\\\\\\\
- \\\\009\\\\009if (ProgressBar.prototype[key] ~= nil) then\\\\\\\
- \\\\009\\\\009\\\\009return ProgressBar.prototype[key]\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end;\\\\\\\
- }\\\\\\\
- function ProgressBar:new(progressBarTbl)\\\\\\\
- \\\\009if (progressBarTbl == nil) then\\\\\\\
- \\\\009\\\\009progressBarTbl = self\\\\\\\
- \\\\009end\\\\\\\
- \\\\009setmetatable(progressBarTbl, ProgressBar.mt)\\\\\\\
- \\\\009return progressBarTbl\\\\\\\
- end\\\\\\\
- \\\\\\\
- Controller:setDefaultStyle(Style:new({}))\\\\\\\
- ]]\\\\\\\
- \\\\\\\
- persist(\\\\\\\"GUI\\\\\\\", libcode)\\\\\\\
- \\\\\\\
- return 1\\\"\",\
- \"F:libstdlua.2.so\",\
- \"\\\"local libcode = [[\\\\\\\
- --\\\\\\\
- --Copyright (C) 2012 Thomas Farr a.k.a tomass1996 [[email protected]]\\\\\\\
- --Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\\\\\\\
- --associated documentation files (the \\\\\\\"Software\\\\\\\"), to deal in the Software without restriction,\\\\\\\
- --including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\\\\\\\
- --copies of the Software, and to permit persons to whom the Software is furnished to do so,\\\\\\\
- --subject to the following conditions:\\\\\\\
- ---The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\\\\\\\
- ---Visible credit is given to the original author.\\\\\\\
- ---The software is distributed in a non-profit way.\\\\\\\
- --THE SOFTWARE IS PROVIDED \\\\\\\"AS IS\\\\\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\\\\\\\
- --WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\\\\\\\
- --COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\\\\\\\
- --ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\\\\\\
- --\\\\\\\
- \\\\\\\
- local floor,modf, insert = math.floor,math.modf, table.insert\\\\\\\
- local char,format,rep = string.char,string.format,string.rep\\\\\\\
- \\\\\\\
- local function basen(n,b)\\\\\\\
- \\\\009if n < 0 then\\\\\\\
- \\\\009\\\\009n = -n\\\\\\\
- \\\\009end\\\\\\\
- local t = \\\\\\\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\\\\]^_abcdefghijklmnopqrstuvwxyz{|}~\\\\\\\"\\\\\\\
- if n < b then\\\\\\\
- \\\\009local ret = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009ret = ret..string.sub(t, (n%b)+1,(n%b)+1)\\\\\\\
- \\\\009return ret\\\\\\\
- else\\\\\\\
- \\\\009local tob = tostring(basen(math.floor(n/b), b))\\\\\\\
- \\\\009local ret = tob..t:sub((n%b)+1,(n%b)+1)\\\\\\\
- \\\\009return ret\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local Base64 = {}\\\\\\\
- Base64[\\\\\\\"lsh\\\\\\\"] = function(value,shift)\\\\\\\
- return (value*(2^shift)) % 256\\\\\\\
- end\\\\\\\
- Base64[\\\\\\\"rsh\\\\\\\"] = function(value,shift)\\\\\\\
- return math.floor(value/2^shift) % 256\\\\\\\
- end\\\\\\\
- Base64[\\\\\\\"bit\\\\\\\"] = function(x,b)\\\\\\\
- return (x % 2^b - x % 2^(b-1) > 0)\\\\\\\
- end\\\\\\\
- Base64[\\\\\\\"lor\\\\\\\"] = function(x,y)\\\\\\\
- local result = 0\\\\\\\
- for p=1,8 do result = result + (((Base64.bit(x,p) or Base64.bit(y,p)) == true) and 2^(p-1) or 0) end\\\\\\\
- return result\\\\\\\
- end\\\\\\\
- Base64[\\\\\\\"base64chars\\\\\\\"] = {\\\\\\\
- [0]='A',[1]='B',[2]='C',[3]='D',[4]='E',[5]='F',[6]='G',[7]='H',[8]='I',[9]='J',[10]='K',\\\\\\\
- [11]='L',[12]='M',[13]='N',[14]='O',[15]='P',[16]='Q',[17]='R',[18]='S',[19]='T',[20]='U',\\\\\\\
- [21]='V',[22]='W',[23]='X',[24]='Y',[25]='Z',[26]='a',[27]='b',[28]='c',[29]='d',[30]='e',\\\\\\\
- [31]='f',[32]='g',[33]='h',[34]='i',[35]='j',[36]='k',[37]='l',[38]='m',[39]='n',[40]='o',\\\\\\\
- [41]='p',[42]='q',[43]='r',[44]='s',[45]='t',[46]='u',[47]='v',[48]='w',[49]='x',[50]='y',\\\\\\\
- [51]='z',[52]='0',[53]='1',[54]='2',[55]='3',[56]='4',[57]='5',[58]='6',[59]='7',[60]='8',\\\\\\\
- [61]='9',[62]='-',[63]='_'}\\\\\\\
- Base64[\\\\\\\"base64bytes\\\\\\\"] = {\\\\\\\
- ['A']=0,['B']=1,['C']=2,['D']=3,['E']=4,['F']=5,['G']=6,['H']=7,['I']=8,['J']=9,['K']=10,\\\\\\\
- ['L']=11,['M']=12,['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,\\\\\\\
- ['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,\\\\\\\
- ['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,['n']=39,['o']=40,\\\\\\\
- ['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,\\\\\\\
- ['z']=51,['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,\\\\\\\
- ['9']=61,['-']=62,['_']=63,['=']=nil}\\\\\\\
- \\\\\\\
- local base32 = \\\\\\\"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\\\\\\\"\\\\\\\
- \\\\\\\
- local tSHA1 = {}\\\\\\\
- tSHA1[\\\\\\\"bytes_to_w32\\\\\\\"] = function(a,b,c,d) return a*0x1000000+b*0x10000+c*0x100+d end\\\\\\\
- tSHA1[\\\\\\\"w32_to_bytes\\\\\\\"] = function(i) return floor(i/0x1000000)%0x100,floor(i/0x10000)%0x100,floor(i/0x100)%0x100,i%0x100 end\\\\\\\
- tSHA1[\\\\\\\"w32_rot\\\\\\\"] = function(bits,a)\\\\\\\
- local b2 = 2^(32-bits)\\\\\\\
- local a,b = modf(a/b2)\\\\\\\
- return a+b*b2*(2^(bits))\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"byte_to_bits\\\\\\\"] = function(b)\\\\\\\
- local b = function (n)\\\\\\\
- local b = floor(b/n)\\\\\\\
- return b%2==1\\\\\\\
- end\\\\\\\
- return b(1),b(2),b(4),b(8),b(16),b(32),b(64),b(128)\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"bits_to_byte\\\\\\\"] = function(a,b,c,d,e,f,g,h)\\\\\\\
- local function n(b,x) return b and x or 0 end\\\\\\\
- return n(a,1)+n(b,2)+n(c,4)+n(d,8)+n(e,16)+n(f,32)+n(g,64)+n(h,128)\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"bits_to_string\\\\\\\"] = function(a,b,c,d,e,f,g,h)\\\\\\\
- local function x(b) return b and \\\\\\\"1\\\\\\\" or \\\\\\\"0\\\\\\\" end\\\\\\\
- return (\\\\\\\"%s%s%s%s %s%s%s%s\\\\\\\"):format(x(a),x(b),x(c),x(d),x(e),x(f),x(g),x(h))\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"byte_to_bit_string\\\\\\\"] = function(b) return tSHA1.bits_to_string(byte_to_bits(b)) end\\\\\\\
- tSHA1[\\\\\\\"w32_to_bit_string\\\\\\\"] = function(a)\\\\\\\
- if type(a) == \\\\\\\"string\\\\\\\" then return a end\\\\\\\
- local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
- local s = tSHA1.byte_to_bit_string\\\\\\\
- return (\\\\\\\"%s %s %s %s\\\\\\\"):format(s(aa):reverse(),s(ab):reverse(),s(ac):reverse(),s(ad):reverse()):reverse()\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"band\\\\\\\"] = function(a,b)\\\\\\\
- local A,B,C,D,E,F,G,H = tSHA1.byte_to_bits(b)\\\\\\\
- local a,b,c,d,e,f,g,h = tSHA1.byte_to_bits(a)\\\\\\\
- return tSHA1.bits_to_byte(\\\\\\\
- A and a, B and b, C and c, D and d,\\\\\\\
- E and e, F and f, G and g, H and h)\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"bor\\\\\\\"] = function(a,b)\\\\\\\
- local A,B,C,D,E,F,G,H = tSHA1.byte_to_bits(b)\\\\\\\
- local a,b,c,d,e,f,g,h = tSHA1.byte_to_bits(a)\\\\\\\
- return tSHA1.bits_to_byte(\\\\\\\
- A or a, B or b, C or c, D or d,\\\\\\\
- E or e, F or f, G or g, H or h)\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"bxor\\\\\\\"] = function(a,b)\\\\\\\
- local A,B,C,D,E,F,G,H = tSHA1.byte_to_bits(b)\\\\\\\
- local a,b,c,d,e,f,g,h = tSHA1.byte_to_bits(a)\\\\\\\
- return tSHA1.bits_to_byte(\\\\\\\
- A ~= a, B ~= b, C ~= c, D ~= d,\\\\\\\
- E ~= e, F ~= f, G ~= g, H ~= h)\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"bnot\\\\\\\"] = function(x) return 255-(x % 256) end\\\\\\\
- tSHA1[\\\\\\\"w32_comb\\\\\\\"] = function(fn)\\\\\\\
- return function (a,b)\\\\\\\
- local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
- local ba,bb,bc,bd = tSHA1.w32_to_bytes(b)\\\\\\\
- return tSHA1.bytes_to_w32(fn(aa,ba),fn(ab,bb),fn(ac,bc),fn(ad,bd))\\\\\\\
- end\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"w32_xor_n\\\\\\\"] = function(a,...)\\\\\\\
- local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
- for i=1,select('#',...) do\\\\\\\
- local ba,bb,bc,bd = tSHA1.w32_to_bytes(select(i,...))\\\\\\\
- aa,ab,ac,ad = tSHA1.bxor(aa,ba),tSHA1.bxor(ab,bb),tSHA1.bxor(ac,bc),tSHA1.bxor(ad,bd)\\\\\\\
- end\\\\\\\
- return tSHA1.bytes_to_w32(aa,ab,ac,ad)\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"w32_or3\\\\\\\"] = function(a,b,c)\\\\\\\
- local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
- local ba,bb,bc,bd = tSHA1.w32_to_bytes(b)\\\\\\\
- local ca,cb,cc,cd = tSHA1.w32_to_bytes(c)\\\\\\\
- return tSHA1.bytes_to_w32(\\\\\\\
- tSHA1.bor(aa,tSHA1.bor(ba,ca)), tSHA1.bor(ab,tSHA1.bor(bb,cb)), tSHA1.bor(ac,tSHA1.bor(bc,cc)), tSHA1.bor(ad,tSHA1.bor(bd,cd))\\\\\\\
- )\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"w32_not\\\\\\\"] = function(a) return 4294967295-(a % 4294967296) end\\\\\\\
- tSHA1[\\\\\\\"w32_add\\\\\\\"] = function(a,b) return (a+b) % 4294967296 end\\\\\\\
- tSHA1[\\\\\\\"w32_add_n\\\\\\\"] = function(a,...)\\\\\\\
- for i=1,select('#',...) do\\\\\\\
- a = (a+select(i,...)) % 4294967296\\\\\\\
- end\\\\\\\
- return a\\\\\\\
- end\\\\\\\
- tSHA1[\\\\\\\"w32_to_hexstring\\\\\\\"] = function(w) return format(\\\\\\\"%08x\\\\\\\",w) end\\\\\\\
- tSHA1[\\\\\\\"w32_and\\\\\\\"] = tSHA1.w32_comb(tSHA1.band)\\\\\\\
- tSHA1[\\\\\\\"w32_xor\\\\\\\"] = tSHA1.w32_comb(tSHA1.bxor)\\\\\\\
- tSHA1[\\\\\\\"w32_or\\\\\\\"] = tSHA1.w32_comb(tSHA1.bor)\\\\\\\
- \\\\\\\
- local CRC = {}\\\\\\\
- CRC.crc32 = {\\\\\\\
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,\\\\\\\
- 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,\\\\\\\
- 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,\\\\\\\
- 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,\\\\\\\
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,\\\\\\\
- 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,\\\\\\\
- 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,\\\\\\\
- 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,\\\\\\\
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,\\\\\\\
- 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,\\\\\\\
- 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,\\\\\\\
- 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,\\\\\\\
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,\\\\\\\
- 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,\\\\\\\
- 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,\\\\\\\
- 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,\\\\\\\
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,\\\\\\\
- 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,\\\\\\\
- 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,\\\\\\\
- 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,\\\\\\\
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,\\\\\\\
- 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,\\\\\\\
- 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,\\\\\\\
- 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,\\\\\\\
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,\\\\\\\
- 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,\\\\\\\
- 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,\\\\\\\
- 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,\\\\\\\
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,\\\\\\\
- 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,\\\\\\\
- 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,\\\\\\\
- 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,\\\\\\\
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,\\\\\\\
- 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,\\\\\\\
- 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,\\\\\\\
- 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,\\\\\\\
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,\\\\\\\
- 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,\\\\\\\
- 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,\\\\\\\
- 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,\\\\\\\
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,\\\\\\\
- 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,\\\\\\\
- 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }\\\\\\\
- \\\\\\\
- local bit = {}\\\\\\\
- bit[\\\\\\\"bnot\\\\\\\"] = function(n)\\\\\\\
- local tbl = bit.tobits(n)\\\\\\\
- local size = math.max(table.getn(tbl), 32)\\\\\\\
- for i = 1, size do\\\\\\\
- if(tbl[i] == 1) then\\\\\\\
- tbl[i] = 0\\\\\\\
- else\\\\\\\
- tbl[i] = 1\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return bit.tonumb(tbl)\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"band\\\\\\\"] = function(m, n)\\\\\\\
- local tbl_m = bit.tobits(m)\\\\\\\
- local tbl_n = bit.tobits(n)\\\\\\\
- bit.expand(tbl_m, tbl_n)\\\\\\\
- local tbl = {}\\\\\\\
- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))\\\\\\\
- for i = 1, rslt do\\\\\\\
- if(tbl_m[i]== 0 or tbl_n[i] == 0) then\\\\\\\
- tbl[i] = 0\\\\\\\
- else\\\\\\\
- tbl[i] = 1\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return bit.tonumb(tbl)\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"bor\\\\\\\"] = function(m, n)\\\\\\\
- local tbl_m = bit.tobits(m)\\\\\\\
- local tbl_n = bit.tobits(n)\\\\\\\
- bit.expand(tbl_m, tbl_n)\\\\\\\
- local tbl = {}\\\\\\\
- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))\\\\\\\
- for i = 1, rslt do\\\\\\\
- if(tbl_m[i]== 0 and tbl_n[i] == 0) then\\\\\\\
- tbl[i] = 0\\\\\\\
- else\\\\\\\
- tbl[i] = 1\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return bit.tonumb(tbl)\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"bxor\\\\\\\"] = function(m, n)\\\\\\\
- local tbl_m = bit.tobits(m)\\\\\\\
- local tbl_n = bit.tobits(n)\\\\\\\
- bit.expand(tbl_m, tbl_n)\\\\\\\
- local tbl = {}\\\\\\\
- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))\\\\\\\
- for i = 1, rslt do\\\\\\\
- if(tbl_m[i] ~= tbl_n[i]) then\\\\\\\
- tbl[i] = 1\\\\\\\
- else\\\\\\\
- tbl[i] = 0\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return bit.tonumb(tbl)\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"brshift\\\\\\\"] = function(n, bits)\\\\\\\
- bit.checkint(n)\\\\\\\
- local high_bit = 0\\\\\\\
- if(n < 0) then\\\\\\\
- n = bit.bnot(math.abs(n)) + 1\\\\\\\
- high_bit = 2147483648\\\\\\\
- end\\\\\\\
- for i=1, bits do\\\\\\\
- n = n/2\\\\\\\
- n = bit.bor(math.floor(n), high_bit)\\\\\\\
- end\\\\\\\
- return math.floor(n)\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"blshift\\\\\\\"] = function(n, bits)\\\\\\\
- bit.checkint(n)\\\\\\\
- if(n < 0) then\\\\\\\
- n = bit.bnot(math.abs(n)) + 1\\\\\\\
- end\\\\\\\
- for i=1, bits do\\\\\\\
- n = n*2\\\\\\\
- end\\\\\\\
- return bit.band(n, 4294967295)\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"bxor2\\\\\\\"] = function(m, n)\\\\\\\
- local rhs = bit.bor(bit.bnot(m), bit.bnot(n))\\\\\\\
- local lhs = bit.bor(m, n)\\\\\\\
- local rslt = bit.band(lhs, rhs)\\\\\\\
- return rslt\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"blogic_rshift\\\\\\\"] = function(n, bits)\\\\\\\
- bit.checkint(n)\\\\\\\
- if(n < 0) then\\\\\\\
- n = bit.bnot(math.abs(n)) + 1\\\\\\\
- end\\\\\\\
- for i=1, bits do\\\\\\\
- n = n/2\\\\\\\
- end\\\\\\\
- return math.floor(n)\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"tobits\\\\\\\"] = function(n)\\\\\\\
- bit.checkint(n)\\\\\\\
- if(n < 0) then\\\\\\\
- return bit.tobits(bit.bnot(math.abs(n)) + 1)\\\\\\\
- end\\\\\\\
- local tbl = {}\\\\\\\
- local cnt = 1\\\\\\\
- while (n > 0) do\\\\\\\
- local last = math.fmod(n,2)\\\\\\\
- if(last == 1) then\\\\\\\
- tbl[cnt] = 1\\\\\\\
- else\\\\\\\
- tbl[cnt] = 0\\\\\\\
- end\\\\\\\
- n = (n-last)/2\\\\\\\
- cnt = cnt + 1\\\\\\\
- end\\\\\\\
- return tbl\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"tonumb\\\\\\\"] = function(tbl)\\\\\\\
- local n = table.getn(tbl)\\\\\\\
- local rslt = 0\\\\\\\
- local power = 1\\\\\\\
- for i = 1, n do\\\\\\\
- rslt = rslt + tbl[i]*power\\\\\\\
- power = power*2\\\\\\\
- end\\\\\\\
- return rslt\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"checkint\\\\\\\"] = function(n)\\\\\\\
- if(n - math.floor(n) > 0) then\\\\\\\
- error(\\\\\\\"trying to use bitwise operation on non-integer!\\\\\\\")\\\\\\\
- end\\\\\\\
- end\\\\\\\
- bit[\\\\\\\"expand\\\\\\\"] = function(tbl_m, tbl_n)\\\\\\\
- local big = {}\\\\\\\
- local small = {}\\\\\\\
- if(table.getn(tbl_m) > table.getn(tbl_n)) then\\\\\\\
- big = tbl_m\\\\\\\
- small = tbl_n\\\\\\\
- else\\\\\\\
- big = tbl_n\\\\\\\
- small = tbl_m\\\\\\\
- end\\\\\\\
- for i = table.getn(small) + 1, table.getn(big) do\\\\\\\
- small[i] = 0\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local FCS = {}\\\\\\\
- FCS[\\\\\\\"16\\\\\\\"] = {\\\\\\\
- [0]=0, 4489, 8978, 12955, 17956, 22445, 25910, 29887,\\\\\\\
- 35912, 40385, 44890, 48851, 51820, 56293, 59774, 63735,\\\\\\\
- 4225, 264, 13203, 8730, 22181, 18220, 30135, 25662,\\\\\\\
- 40137, 36160, 49115, 44626, 56045, 52068, 63999, 59510,\\\\\\\
- 8450, 12427, 528, 5017, 26406, 30383, 17460, 21949,\\\\\\\
- 44362, 48323, 36440, 40913, 60270, 64231, 51324, 55797,\\\\\\\
- 12675, 8202, 4753, 792, 30631, 26158, 21685, 17724,\\\\\\\
- 48587, 44098, 40665, 36688, 64495, 60006, 55549, 51572,\\\\\\\
- 16900, 21389, 24854, 28831, 1056, 5545, 10034, 14011,\\\\\\\
- 52812, 57285, 60766, 64727, 34920, 39393, 43898, 47859,\\\\\\\
- 21125, 17164, 29079, 24606, 5281, 1320, 14259, 9786,\\\\\\\
- 57037, 53060, 64991, 60502, 39145, 35168, 48123, 43634,\\\\\\\
- 25350, 29327, 16404, 20893, 9506, 13483, 1584, 6073,\\\\\\\
- 61262, 65223, 52316, 56789, 43370, 47331, 35448, 39921,\\\\\\\
- 29575, 25102, 20629, 16668, 13731, 9258, 5809, 1848,\\\\\\\
- 65487, 60998, 56541, 52564, 47595, 43106, 39673, 35696,\\\\\\\
- 33800, 38273, 42778, 46739, 49708, 54181, 57662, 61623,\\\\\\\
- 2112, 6601, 11090, 15067, 20068, 24557, 28022, 31999,\\\\\\\
- 38025, 34048, 47003, 42514, 53933, 49956, 61887, 57398,\\\\\\\
- 6337, 2376, 15315, 10842, 24293, 20332, 32247, 27774,\\\\\\\
- 42250, 46211, 34328, 38801, 58158, 62119, 49212, 53685,\\\\\\\
- 10562, 14539, 2640, 7129, 28518, 32495, 19572, 24061,\\\\\\\
- 46475, 41986, 38553, 34576, 62383, 57894, 53437, 49460,\\\\\\\
- 14787, 10314, 6865, 2904, 32743, 28270, 23797, 19836,\\\\\\\
- 50700, 55173, 58654, 62615, 32808, 37281, 41786, 45747,\\\\\\\
- 19012, 23501, 26966, 30943, 3168, 7657, 12146, 16123,\\\\\\\
- 54925, 50948, 62879, 58390, 37033, 33056, 46011, 41522,\\\\\\\
- 23237, 19276, 31191, 26718, 7393, 3432, 16371, 11898,\\\\\\\
- 59150, 63111, 50204, 54677, 41258, 45219, 33336, 37809,\\\\\\\
- 27462, 31439, 18516, 23005, 11618, 15595, 3696, 8185,\\\\\\\
- 63375, 58886, 54429, 50452, 45483, 40994, 37561, 33584,\\\\\\\
- 31687, 27214, 22741, 18780, 15843, 11370, 7921, 3960 }\\\\\\\
- FCS[\\\\\\\"32\\\\\\\"] = {\\\\\\\
- [0]=0, 1996959894, -301047508, -1727442502, 124634137, 1886057615, -379345611, -1637575261,\\\\\\\
- 249268274, 2044508324, -522852066, -1747789432, 162941995, 2125561021, -407360249, -1866523247,\\\\\\\
- 498536548, 1789927666, -205950648, -2067906082, 450548861, 1843258603, -187386543, -2083289657,\\\\\\\
- 325883990, 1684777152, -43845254, -1973040660, 335633487, 1661365465, -99664541, -1928851979,\\\\\\\
- 997073096, 1281953886, -715111964, -1570279054, 1006888145, 1258607687, -770865667, -1526024853,\\\\\\\
- 901097722, 1119000684, -608450090, -1396901568, 853044451, 1172266101, -589951537, -1412350631,\\\\\\\
- 651767980, 1373503546, -925412992, -1076862698, 565507253, 1454621731, -809855591, -1195530993,\\\\\\\
- 671266974, 1594198024, -972236366, -1324619484, 795835527, 1483230225, -1050600021, -1234817731,\\\\\\\
- 1994146192, 31158534, -1731059524, -271249366, 1907459465, 112637215, -1614814043, -390540237,\\\\\\\
- 2013776290, 251722036, -1777751922, -519137256, 2137656763, 141376813, -1855689577, -429695999,\\\\\\\
- 1802195444, 476864866, -2056965928, -228458418, 1812370925, 453092731, -2113342271, -183516073,\\\\\\\
- 1706088902, 314042704, -1950435094, -54949764, 1658658271, 366619977, -1932296973, -69972891,\\\\\\\
- 1303535960, 984961486, -1547960204, -725929758, 1256170817, 1037604311, -1529756563, -740887301,\\\\\\\
- 1131014506, 879679996, -1385723834, -631195440, 1141124467, 855842277, -1442165665, -586318647,\\\\\\\
- 1342533948, 654459306, -1106571248, -921952122, 1466479909, 544179635, -1184443383, -832445281,\\\\\\\
- 1591671054, 702138776, -1328506846, -942167884, 1504918807, 783551873, -1212326853, -1061524307,\\\\\\\
- -306674912, -1698712650, 62317068, 1957810842, -355121351, -1647151185, 81470997, 1943803523,\\\\\\\
- -480048366, -1805370492, 225274430, 2053790376, -468791541, -1828061283, 167816743, 2097651377,\\\\\\\
- -267414716, -2029476910, 503444072, 1762050814, -144550051, -2140837941, 426522225, 1852507879,\\\\\\\
- -19653770, -1982649376, 282753626, 1742555852, -105259153, -1900089351, 397917763, 1622183637,\\\\\\\
- -690576408, -1580100738, 953729732, 1340076626, -776247311, -1497606297, 1068828381, 1219638859,\\\\\\\
- -670225446, -1358292148, 906185462, 1090812512, -547295293, -1469587627, 829329135, 1181335161,\\\\\\\
- -882789492, -1134132454, 628085408, 1382605366, -871598187, -1156888829, 570562233, 1426400815,\\\\\\\
- -977650754, -1296233688, 733239954, 1555261956, -1026031705, -1244606671, 752459403, 1541320221,\\\\\\\
- -1687895376, -328994266, 1969922972, 40735498, -1677130071, -351390145, 1913087877, 83908371,\\\\\\\
- -1782625662, -491226604, 2075208622, 213261112, -1831694693, -438977011, 2094854071, 198958881,\\\\\\\
- -2032938284, -237706686, 1759359992, 534414190, -2118248755, -155638181, 1873836001, 414664567,\\\\\\\
- -2012718362, -15766928, 1711684554, 285281116, -1889165569, -127750551, 1634467795, 376229701,\\\\\\\
- -1609899400, -686959890, 1308918612, 956543938, -1486412191, -799009033, 1231636301, 1047427035,\\\\\\\
- -1362007478, -640263460, 1088359270, 936918000, -1447252397, -558129467, 1202900863, 817233897,\\\\\\\
- -1111625188, -893730166, 1404277552, 615818150, -1160759803, -841546093, 1423857449, 601450431,\\\\\\\
- -1285129682, -1000256840, 1567103746, 711928724, -1274298825, -1022587231, 1510334235, 755167117 }\\\\\\\
- \\\\\\\
- --String Utils :\\\\\\\
- \\\\\\\
- function toCharTable(str) --Returns table of @str's chars\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009local chars = {}\\\\\\\
- \\\\009for n=1,#str do\\\\\\\
- \\\\009\\\\009chars[n] = str:sub(n,n)\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return chars\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toByteTable(str) --Returns table of @str's bytes\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009local bytes = {}\\\\\\\
- \\\\009for n=1,#str do\\\\\\\
- \\\\009\\\\009bytes[n] = str:byte(n)\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return bytes\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromCharTable(chars) --Returns string made of chracters in @chars\\\\\\\
- if not chars or type(chars)~=\\\\\\\"table\\\\\\\" then return nil end\\\\\\\
- \\\\009return table.concat(chars)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromByteTable(bytes) --Returns string made of bytes in @bytes\\\\\\\
- if not bytes or type(bytes)~=\\\\\\\"table\\\\\\\" then return nil end\\\\\\\
- \\\\009local str = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for n=1,#bytes do\\\\\\\
- \\\\009\\\\009str = str..string.char(bytes[n])\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return str\\\\\\\
- end\\\\\\\
- \\\\\\\
- function contains(str,find) --Returns true if @str contains @find\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009for n=1, #str-#find+1 do\\\\\\\
- \\\\009\\\\009if str:sub(n,n+#find-1) == find then return true end\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return false\\\\\\\
- end\\\\\\\
- \\\\\\\
- function startsWith(str,Start) --Check if @str starts with @Start\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- return str:sub(1,Start:len())==Start\\\\\\\
- end\\\\\\\
- \\\\\\\
- function endsWith(str,End) --Check if @str ends with @End\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- return End=='' or str:sub(#str-#End+1)==End\\\\\\\
- end\\\\\\\
- \\\\\\\
- function trim(str) --Trim @str of initial/trailing whitespace\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- return (str:gsub(\\\\\\\"^%s*(.-)%s*$\\\\\\\", \\\\\\\"%1\\\\\\\"))\\\\\\\
- end\\\\\\\
- \\\\\\\
- function firstLetterUpper(str) --Capitilizes first letter of @str\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009str = str:gsub(\\\\\\\"%a\\\\\\\", string.upper, 1)\\\\\\\
- return str\\\\\\\
- end\\\\\\\
- \\\\\\\
- function titleCase(str) --Changes @str to title case\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- local function tchelper(first, rest)\\\\\\\
- \\\\009\\\\009return first:upper()..rest:lower()\\\\\\\
- end\\\\\\\
- str = str:gsub(\\\\\\\"(%a)([%w_']*)\\\\\\\", tchelper)\\\\\\\
- \\\\009return str\\\\\\\
- end\\\\\\\
- \\\\\\\
- function isRepetition(str, pat) --Checks if @str is a repetition of @pat\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009return \\\\\\\"\\\\\\\" == str:gsub(pat, \\\\\\\"\\\\\\\")\\\\\\\
- end\\\\\\\
- \\\\\\\
- function isRepetitionWS(str, pat) --Checks if @str is a repetition of @pat seperated by whitespaces\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009return not str:gsub(pat, \\\\\\\"\\\\\\\"):find\\\\\\\"%S\\\\\\\"\\\\\\\
- end\\\\\\\
- \\\\\\\
- function urlDecode(str) --Url decodes @str\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009str = string.gsub (str, \\\\\\\"+\\\\\\\", \\\\\\\" \\\\\\\")\\\\\\\
- \\\\009str = string.gsub (str, \\\\\\\"%%(%x%x)\\\\\\\", function(h) return string.char(tonumber(h,16)) end)\\\\\\\
- \\\\009str = string.gsub (str, \\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\", \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
- \\\\009return str\\\\\\\
- end\\\\\\\
- \\\\\\\
- function urlEncode(str) --Url encodes @str\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009if (str) then\\\\\\\
- \\\\009\\\\009str = string.gsub (str, \\\\\\\"\\\\\\\\n\\\\\\\", \\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\")\\\\\\\
- \\\\009\\\\009str = string.gsub (str, \\\\\\\"([^%w ])\\\\\\\", function (c) return string.format (\\\\\\\"%%%02X\\\\\\\", string.byte(c)) end)\\\\\\\
- \\\\009\\\\009str = string.gsub (str, \\\\\\\" \\\\\\\", \\\\\\\"+\\\\\\\")\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return str\\\\\\\
- end\\\\\\\
- \\\\\\\
- function isEmailAddress(str) --Checks if @str is a valid email address\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- \\\\009if (str:match(\\\\\\\"[A-Za-z0-9%.%%%+%-]+@[A-Za-z0-9%.%%%+%-]+%.%w%w%w?%w?\\\\\\\")) then\\\\\\\
- \\\\009\\\\009return true\\\\\\\
- \\\\009else\\\\\\\
- \\\\009\\\\009return false\\\\\\\
- \\\\009end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function chunk(str, size) --Splits @str into chunks of length @size\\\\\\\
- \\\\009if not size then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local num2App = size - (#str%size)\\\\\\\
- \\\\009str = str..(rep(char(0), num2App) or \\\\\\\"\\\\\\\")\\\\\\\
- \\\\009assert(#str%size==0)\\\\\\\
- \\\\009local chunks = {}\\\\\\\
- \\\\009local numChunks = #str / size\\\\\\\
- \\\\009local chunk = 0\\\\\\\
- \\\\009while chunk < numChunks do\\\\\\\
- \\\\009\\\\009local start = chunk * size + 1\\\\\\\
- chunk = chunk+1\\\\\\\
- \\\\009\\\\009if start+size-1 > #str-num2App then\\\\\\\
- if str:sub(start, #str-num2App) ~= (nil or \\\\\\\"\\\\\\\") then\\\\\\\
- \\\\009\\\\009\\\\009 chunks[chunk] = str:sub(start, #str-num2App)\\\\\\\
- end\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009chunks[chunk] = str:sub(start, start+size-1)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return chunks\\\\\\\
- end\\\\\\\
- \\\\\\\
- function find(str, match, startIndex) --Finds @match in @str optionally after @startIndex\\\\\\\
- \\\\009if not match then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local _ = startIndex or 1\\\\\\\
- \\\\009local _s = nil\\\\\\\
- \\\\009local _e = nil\\\\\\\
- \\\\009local _len = match:len()\\\\\\\
- \\\\009while true do\\\\\\\
- \\\\009\\\\009local _t = str:sub( _ , _len + _ - 1)\\\\\\\
- \\\\009\\\\009if _t == match then\\\\\\\
- \\\\009\\\\009\\\\009_s = _\\\\\\\
- \\\\009\\\\009\\\\009_e = _ + _len - 1\\\\\\\
- \\\\009\\\\009\\\\009break\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009_ = _ + 1\\\\\\\
- \\\\009\\\\009if _ > str:len() then break end\\\\\\\
- \\\\009end\\\\\\\
- \\\\009if _s == nil then return nil else return _s, _e end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function separate(str, divider) --Separates @str on @divider\\\\\\\
- \\\\009if not divider then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local start = {}\\\\\\\
- \\\\009local endS = {}\\\\\\\
- \\\\009local n=1\\\\\\\
- \\\\009repeat\\\\\\\
- \\\\009\\\\009if n==1 then\\\\\\\
- \\\\009\\\\009\\\\009start[n], endS[n] = find(str, divider)\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009start[n], endS[n] = find(str, divider, endS[n-1]+1)\\\\\\\
- end\\\\\\\
- \\\\009\\\\009n=n+1\\\\\\\
- \\\\009until start[n-1]==nil\\\\\\\
- \\\\009local subs = {}\\\\\\\
- \\\\009for n=1, #start+1 do\\\\\\\
- \\\\009\\\\009if n==1 then\\\\\\\
- \\\\009\\\\009\\\\009subs[n] = str:sub(1, start[n]-1)\\\\\\\
- \\\\009\\\\009elseif n==#start+1 then\\\\\\\
- \\\\009\\\\009\\\\009subs[n] = str:sub(endS[n-1]+1)\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009subs[n] = str:sub(endS[n-1]+1, start[n]-1)\\\\\\\
- end\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return subs\\\\\\\
- end\\\\\\\
- \\\\\\\
- function replace(str, from, to) --Replaces @from to @to in @str\\\\\\\
- \\\\009if not from then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local pcs = seperate(str, from)\\\\\\\
- \\\\009str = pcs[1]\\\\\\\
- \\\\009for n=2,#pcs do\\\\\\\
- \\\\009\\\\009str = str..to..pcs[n]\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return str\\\\\\\
- end\\\\\\\
- \\\\\\\
- function jumble(str) --Jumbles @str\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local chars = {}\\\\\\\
- \\\\009for i = 1, #str do\\\\\\\
- \\\\009\\\\009chars[i] = str:sub(i, i)\\\\\\\
- \\\\009end\\\\\\\
- \\\\009local usedNums = \\\\\\\":\\\\\\\"\\\\\\\
- \\\\009local res = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009local rand = 0\\\\\\\
- \\\\009for i=1, #chars do\\\\\\\
- \\\\009\\\\009while true do\\\\\\\
- \\\\009\\\\009\\\\009rand = math.random(#chars)\\\\\\\
- \\\\009\\\\009\\\\009if find(usedNums, \\\\\\\":\\\\\\\"..rand..\\\\\\\":\\\\\\\") == nil then break end\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009res = res..chars[rand]\\\\\\\
- \\\\009\\\\009usedNums = usedNums..rand..\\\\\\\":\\\\\\\"\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return res\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toBase(str, base) --Encodes @str in @base\\\\\\\
- \\\\009if not base then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local res = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for i = 1, str:len() do\\\\\\\
- \\\\009\\\\009if i == 1 then\\\\\\\
- \\\\009\\\\009\\\\009res = basen(str:byte(i), base)\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009res = res..\\\\\\\":\\\\\\\"..basen(str:byte(i), base)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return res\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromBase(str, base) --Decodes @str from @base\\\\\\\
- \\\\009if not base then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local bytes = seperate(str, \\\\\\\":\\\\\\\")\\\\\\\
- \\\\009local res = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for i = 1, #bytes do\\\\\\\
- \\\\009\\\\009res = res..(string.char(basen(tonumber(bytes[i], base), 10)))\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return res\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toBinary(str) --Encodes @str in binary\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return toBase(str, 2)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromBinary(str) --Decodes @str from binary\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return fromBase(str, 2)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toOctal(str) --Encodes @str in octal\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return toBase(str, 8)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromOctal(str) --Decodes @str from octal\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return fromBase(str, 8)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toHex(str) --Encodes @str in hex\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return toBase(str, 16)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromHex(str) --Decodes @str from hex\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return fromBase(str, 16)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toBase36(str) --Encodes @str in Base36\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return toBase(str, 36)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromBase36(str) --Decodes @str from Base36\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009return fromBase(str, 36)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toBase32(str) --Encodes @str in Base32\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local byte=0\\\\\\\
- \\\\009local bits=0\\\\\\\
- \\\\009local rez=\\\\\\\"\\\\\\\"\\\\\\\
- \\\\009local i=0\\\\\\\
- \\\\009for i = 1, str:len() do\\\\\\\
- \\\\009\\\\009byte=byte*256+str:byte(i)\\\\\\\
- \\\\009\\\\009bits=bits+8\\\\\\\
- \\\\009\\\\009repeat\\\\\\\
- \\\\009\\\\009\\\\009bits=bits-5\\\\\\\
- \\\\009\\\\009\\\\009local mul=(2^(bits))\\\\\\\
- \\\\009\\\\009\\\\009local b32n=math.floor(byte/mul)\\\\\\\
- \\\\009\\\\009\\\\009byte=byte-(b32n*mul)\\\\\\\
- \\\\009\\\\009\\\\009b32n=b32n+1\\\\\\\
- \\\\009\\\\009\\\\009rez=rez..string.sub(base32,b32n,b32n)\\\\\\\
- \\\\009\\\\009until bits<5\\\\\\\
- \\\\009end\\\\\\\
- \\\\009if bits>0 then\\\\\\\
- \\\\009\\\\009local b32n= math.fmod(byte*(2^(5-bits)),32)\\\\\\\
- \\\\009\\\\009b32n=b32n+1\\\\\\\
- \\\\009\\\\009rez=rez..string.sub(base32,b32n,b32n)\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return rez\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromBase32(str) --Decodes @str from Base32\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local b32n=0\\\\\\\
- \\\\009local bits=0\\\\\\\
- \\\\009local rez=\\\\\\\"\\\\\\\"\\\\\\\
- \\\\009local i=0\\\\\\\
- \\\\009string.gsub(str:upper(), \\\\\\\"[\\\\\\\"..base32..\\\\\\\"]\\\\\\\", function (char)\\\\\\\
- \\\\009\\\\009local num = string.find(base32, char, 1, true)\\\\\\\
- \\\\009\\\\009b32n=b32n*32+(num - 1)\\\\\\\
- \\\\009\\\\009bits=bits+5\\\\\\\
- \\\\009\\\\009while bits>=8 do\\\\\\\
- \\\\009\\\\009\\\\009bits=bits-8\\\\\\\
- \\\\009\\\\009\\\\009local mul=(2^(bits))\\\\\\\
- \\\\009\\\\009\\\\009local byte = math.floor(b32n/mul)\\\\\\\
- \\\\009\\\\009\\\\009b32n=b32n-(byte*mul)\\\\\\\
- \\\\009\\\\009\\\\009rez=rez..string.char(byte)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end)\\\\\\\
- \\\\009return rez\\\\\\\
- end\\\\\\\
- \\\\\\\
- function toBase64(str) --Encodes @str in Base64\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local bytes = {}\\\\\\\
- \\\\009local result = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for spos=0,str:len()-1,3 do\\\\\\\
- \\\\009\\\\009for byte=1,3 do bytes[byte] = str:byte(spos+byte) or 0 end\\\\\\\
- \\\\009\\\\009result = string.format('%s%s%s%s%s',result,Base64.base64chars[Base64.rsh(bytes[1],2)],Base64.base64chars[Base64.lor(Base64.lsh((bytes[1] % 4),4), Base64.rsh(bytes[2],4))] or \\\\\\\"=\\\\\\\",((str:len()-spos) > 1) and Base64.base64chars[Base64.lor(Base64.lsh(bytes[2] % 16,2), Base64.rsh(bytes[3],6))] or \\\\\\\"=\\\\\\\",((str:len()-spos) > 2) and Base64.base64chars[(bytes[3] % 64)] or \\\\\\\"=\\\\\\\")\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return result\\\\\\\
- end\\\\\\\
- \\\\\\\
- function fromBase64(str) --Decodes @str from Base64\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local chars = {}\\\\\\\
- \\\\009local result=\\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for dpos=0,str:len()-1,4 do\\\\\\\
- \\\\009\\\\009for char=1,4 do chars[char] = Base64.base64bytes[(str:sub((dpos+char),(dpos+char)) or \\\\\\\"=\\\\\\\")] end\\\\\\\
- \\\\009\\\\009result = string.format('%s%s%s%s',result,string.char(Base64.lor(Base64.lsh(chars[1],2), Base64.rsh(chars[2],4))),(chars[3] ~= nil) and string.char(Base64.lor(Base64.lsh(chars[2],4), Base64.rsh(chars[3],2))) or \\\\\\\"\\\\\\\",(chars[4] ~= nil) and string.char(Base64.lor(Base64.lsh(chars[3],6) % 192, (chars[4]))) or \\\\\\\"\\\\\\\")\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return result\\\\\\\
- end\\\\\\\
- \\\\\\\
- function rot13(str) --Rot13s @str\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local rot = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009local len = str:len()\\\\\\\
- \\\\009for i = 1, len do\\\\\\\
- \\\\009\\\\009local k = str:byte(i)\\\\\\\
- \\\\009\\\\009if (k >= 65 and k <= 77) or (k >= 97 and k <=109) then\\\\\\\
- \\\\009\\\\009\\\\009rot = rot..string.char(k+13)\\\\\\\
- \\\\009\\\\009elseif (k >= 78 and k <= 90) or (k >= 110 and k <= 122) then\\\\\\\
- \\\\009\\\\009\\\\009rot = rot..string.char(k-13)\\\\\\\
- \\\\009\\\\009else\\\\\\\
- \\\\009\\\\009\\\\009rot = rot..string.char(k)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return rot\\\\\\\
- end\\\\\\\
- \\\\\\\
- function rot47(str) --Rot47s @str\\\\\\\
- \\\\009if not str then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local rot = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for i = 1, str:len() do\\\\\\\
- \\\\009\\\\009local p = str:byte(i)\\\\\\\
- \\\\009\\\\009if p >= string.byte('!') and p <= string.byte('O') then\\\\\\\
- \\\\009\\\\009\\\\009p = ((p + 47) % 127)\\\\\\\
- \\\\009\\\\009elseif p >= string.byte('P') and p <= string.byte('~') then\\\\\\\
- \\\\009\\\\009\\\\009p = ((p - 47) % 127)\\\\\\\
- \\\\009\\\\009end\\\\\\\
- \\\\009\\\\009rot = rot..string.char(p)\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return rot\\\\\\\
- end\\\\\\\
- \\\\\\\
- function SHA1(str) --Returns SHA1 Hash of @str\\\\\\\
- if not str then return nil end\\\\\\\
- str = tostring(str)\\\\\\\
- local H0,H1,H2,H3,H4 = 0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0\\\\\\\
- local msg_len_in_bits = #str * 8\\\\\\\
- local first_append = char(0x80)\\\\\\\
- local non_zero_message_bytes = #str +1 +8\\\\\\\
- local current_mod = non_zero_message_bytes % 64\\\\\\\
- local second_append = current_mod>0 and rep(char(0), 64 - current_mod) or \\\\\\\"\\\\\\\"\\\\\\\
- local B1, R1 = modf(msg_len_in_bits / 0x01000000)\\\\\\\
- local B2, R2 = modf( 0x01000000 * R1 / 0x00010000)\\\\\\\
- local B3, R3 = modf( 0x00010000 * R2 / 0x00000100)\\\\\\\
- local B4\\\\009 =\\\\0090x00000100 * R3\\\\\\\
- local L64 = char( 0) .. char( 0) .. char( 0) .. char( 0)\\\\\\\
- .. char(B1) .. char(B2) .. char(B3) .. char(B4)\\\\\\\
- str = str .. first_append .. second_append .. L64\\\\\\\
- assert(#str % 64 == 0)\\\\\\\
- local chunks = #str / 64\\\\\\\
- local W = { }\\\\\\\
- local start, A, B, C, D, E, f, K, TEMP\\\\\\\
- local chunk = 0\\\\\\\
- while chunk < chunks do\\\\\\\
- start,chunk = chunk * 64 + 1,chunk + 1\\\\\\\
- for t = 0, 15 do\\\\\\\
- W[t] = tSHA1.bytes_to_w32(str:byte(start, start + 3))\\\\\\\
- start = start + 4\\\\\\\
- end\\\\\\\
- for t = 16, 79 do\\\\\\\
- W[t] = tSHA1.w32_rot(1, tSHA1.w32_xor_n(W[t-3], W[t-8], W[t-14], W[t-16]))\\\\\\\
- end\\\\\\\
- A,B,C,D,E = H0,H1,H2,H3,H4\\\\\\\
- for t = 0, 79 do\\\\\\\
- if t <= 19 then\\\\\\\
- f = tSHA1.w32_or(tSHA1.w32_and(B, C), tSHA1.w32_and(tSHA1.w32_not(B), D))\\\\\\\
- K = 0x5A827999\\\\\\\
- elseif t <= 39 then\\\\\\\
- f = tSHA1.w32_xor_n(B, C, D)\\\\\\\
- K = 0x6ED9EBA1\\\\\\\
- elseif t <= 59 then\\\\\\\
- f = tSHA1.w32_or3(tSHA1.w32_and(B, C), tSHA1.w32_and(B, D), tSHA1.w32_and(C, D))\\\\\\\
- K = 0x8F1BBCDC\\\\\\\
- else\\\\\\\
- f = tSHA1.w32_xor_n(B, C, D)\\\\\\\
- K = 0xCA62C1D6\\\\\\\
- end\\\\\\\
- A,B,C,D,E = tSHA1.w32_add_n(tSHA1.w32_rot(5, A), f, E, W[t], K),\\\\\\\
- A, tSHA1.w32_rot(30, B), C, D\\\\\\\
- end\\\\\\\
- H0,H1,H2,H3,H4 = tSHA1.w32_add(H0, A),tSHA1.w32_add(H1, B),tSHA1.w32_add(H2, C),tSHA1.w32_add(H3, D),tSHA1.w32_add(H4, E)\\\\\\\
- end\\\\\\\
- local f = tSHA1.w32_to_hexstring\\\\\\\
- return f(H0) .. f(H1) .. f(H2) .. f(H3) .. f(H4)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function CRC32(str) --Returns CRC32 Hash of @str\\\\\\\
- local crc, l, i = 0xFFFFFFFF, string.len(str)\\\\\\\
- for i = 1, l, 1 do\\\\\\\
- crc = bit.bxor(bit.brshift(crc, 8), CRC.crc32[bit.band(bit.bxor(crc, string.byte(str, i)), 0xFF) + 1])\\\\\\\
- end\\\\\\\
- return bit.bxor(crc, -1)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function FCS16(str) --Returns FCS16 Hash of @str\\\\\\\
- local i\\\\\\\
- local l=string.len(str)\\\\\\\
- local uFcs16 = 65535\\\\\\\
- for i = 1,l do\\\\\\\
- uFcs16 = bit.bxor(bit.brshift(uFcs16,8), FCS[\\\\\\\"16\\\\\\\"][bit.band(bit.bxor(uFcs16, string.byte(str,i)), 255)])\\\\\\\
- end\\\\\\\
- return bit.bxor(uFcs16, 65535)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function FCS32(str) --Returns FCS32 Hash of @str\\\\\\\
- local i\\\\\\\
- local l = string.len(str)\\\\\\\
- local uFcs32 = -1\\\\\\\
- for i=1,l do\\\\\\\
- uFcs32 = bit.bxor(bit.brshift(uFcs32,8), FCS[\\\\\\\"32\\\\\\\"][bit.band(bit.bxor(uFcs32, string.byte(str,i)), 255)])\\\\\\\
- end\\\\\\\
- return bit.bnot(uFcs32)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function encrypt(str, key) --Encrypts @str with @key\\\\\\\
- \\\\009if not key then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local alphabet = \\\\\\\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\\\\]^_abcdefghijklmnopqrstuvwxyz{|}~\\\\\\\"\\\\\\\
- \\\\009local _rand = math.random(#alphabet-10)\\\\\\\
- \\\\009local iv = string.sub(jumble(alphabet), _rand, _rand + 9)\\\\\\\
- \\\\009iv = jumble(iv)\\\\\\\
- \\\\009str = iv..str\\\\\\\
- \\\\009local key = SHA1(key)\\\\\\\
- \\\\009local strLen = str:len()\\\\\\\
- \\\\009local keyLen = key:len()\\\\\\\
- \\\\009local j=1\\\\\\\
- \\\\009local result = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for i=1, strLen do\\\\\\\
- \\\\009\\\\009local ordStr = string.byte(str:sub(i,i))\\\\\\\
- \\\\009\\\\009if j == keyLen then j=1 end\\\\\\\
- \\\\009\\\\009local ordKey = string.byte(key:sub(j,j))\\\\\\\
- \\\\009\\\\009result = result..string.reverse(basen(ordStr+ordKey, 36))\\\\\\\
- \\\\009\\\\009j = j+1\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return result\\\\\\\
- end\\\\\\\
- \\\\\\\
- function decrypt(str, key) --Decrypts @str with @key\\\\\\\
- \\\\009if not key then return nil end\\\\\\\
- \\\\009str = tostring(str)\\\\\\\
- \\\\009local key = SHA1(key)\\\\\\\
- \\\\009local strLen = str:len()\\\\\\\
- \\\\009local keyLen = key:len()\\\\\\\
- \\\\009local j=1\\\\\\\
- \\\\009local result = \\\\\\\"\\\\\\\"\\\\\\\
- \\\\009for i=1, strLen, 2 do\\\\\\\
- \\\\009\\\\009local ordStr = basen(tonumber(string.reverse(str:sub(i, i+1)),36),10)\\\\\\\
- \\\\009\\\\009if j==keyLen then j=1 end\\\\\\\
- \\\\009\\\\009local ordKey = string.byte(key:sub(j,j))\\\\\\\
- \\\\009\\\\009result = result..string.char(ordStr-ordKey)\\\\\\\
- \\\\009\\\\009j = j+1\\\\\\\
- \\\\009end\\\\\\\
- \\\\009return result:sub(11)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function setRandSeed(seed) --Sets random seed to @seed\\\\\\\
- \\\\009math.randomseed(seed)\\\\\\\
- end\\\\\\\
- \\\\\\\
- \\\\\\\
- --\\\\\\\
- -- MODIFIED CODE FROM TESSERACT LIES BELOW. \\\\\\\
- --\\\\\\\
- \\\\\\\
- \\\\\\\
- function traverseKey(array, text)\\\\\\\
- for k,v in pairs(array) do\\\\\\\
- if v == text then\\\\\\\
- return true, k\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return false, nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function traverseValue(array, text)\\\\\\\
- for k,v in pairs(array) do\\\\\\\
- if k == text then\\\\\\\
- return true, v\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return false, nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function findKey(array, text)\\\\\\\
- for k,v in pairs(array) do\\\\\\\
- if k == text then\\\\\\\
- return true, k\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return false, nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function findValue(array, text)\\\\\\\
- for k,v in pairs(array) do\\\\\\\
- if v == text then\\\\\\\
- return true, v\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return false, nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function queryKey(array, text)\\\\\\\
- for k,v in pairs(array) do\\\\\\\
- if string.find(k, text) then\\\\\\\
- return true, k\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return false, nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function queryValue(array, text)\\\\\\\
- for k,v in pairs(array) do\\\\\\\
- if string.find(v, text) then\\\\\\\
- return true, v\\\\\\\
- end\\\\\\\
- end\\\\\\\
- return false, nil\\\\\\\
- end\\\\\\\
- \\\\\\\
- function iterateFileLines(path)\\\\\\\
- if not fs.exists(path) then return nil end\\\\\\\
- local handle = fs.open(path, fs.AF_READ)\\\\\\\
- local commands = {}\\\\\\\
- local line = handle.readLine()\\\\\\\
- while line do\\\\\\\
- commands[#commands + 1] = line\\\\\\\
- line = handle.readLine()\\\\\\\
- end\\\\\\\
- handle.close()\\\\\\\
- return commands\\\\\\\
- end\\\\\\\
- \\\\\\\
- function readFile(path)\\\\\\\
- if not fs.exists(path) then return nil end\\\\\\\
- local handle = fs.open(path, fs.AF_READ)\\\\\\\
- local content = handle.readAll()\\\\\\\
- handle.close()\\\\\\\
- return content\\\\\\\
- end\\\\\\\
- \\\\\\\
- function cload(path)\\\\\\\
- if fs.exists(path) and not fs.isDir(path) then\\\\\\\
- local lf = fs.open(path, \\\\\\\"r\\\\\\\")\\\\\\\
- local contents = lf.readAll()\\\\\\\
- lf.close()\\\\\\\
- return textutils.unserialize(contents)\\\\\\\
- else\\\\\\\
- return nil\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function csave(cTable, path)\\\\\\\
- if fs.exists(path) then\\\\\\\
- if fs.isDir(path) then\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- end\\\\\\\
- local sf = fs.open(path, \\\\\\\"w\\\\\\\")\\\\\\\
- sf.write(textutils.serialize(cTable))\\\\\\\
- sf.close()\\\\\\\
- return true\\\\\\\
- end\\\\\\\
- ]]\\\\\\\
- persist(\\\\\\\"stdlib\\\\\\\", libcode)\\\\\\\
- \\\\\\\
- return 1\\\"\",\
- \"F:libuser.2.so\",\
- \"\\\"local libcode = [[\\\\\\\
- CONSTANT_LINE = \\\\\\\"---------------------------------------------------\\\\\\\"\\\\\\\
- \\\\\\\
- --MenuAPI functions (mprint, drawBootMenu) by 1Ridav and MelnikovSM\\\\\\\
- --Context menu provided generously by MasonCipher\\\\\\\
- local function mprint(array, this, s1, s2, x, y)\\\\\\\
- local c = term.getTextColor()\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\
- for i = 1, #array do\\\\\\\
- term.setCursorPos(x, y)\\\\\\\
- --Check if option selected\\\\\\\
- if i == this then \\\\\\\
- --Option selected \\\\\\\
- write(s1)\\\\\\\
- else \\\\\\\
- --Option NOT selected\\\\\\\
- write(s2)\\\\\\\
- end\\\\\\\
- --Print the string\\\\\\\
- print(array[i])\\\\\\\
- y = y + 1 \\\\\\\
- end\\\\\\\
- term.setTextColor(c)\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function stdoutg(text, bg, fg)\\\\\\\
- local a = term.getBackgroundColor()\\\\\\\
- local b = term.getTextColor()\\\\\\\
- term.setBackgroundColor(bg or colors.black)\\\\\\\
- term.setTextColor(fg or colors.white)\\\\\\\
- write(text)\\\\\\\
- term.setBackgroundColor(a)\\\\\\\
- term.setTextColor(b)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function clearScreen(color)\\\\\\\
- term.setBackgroundColor(color or colors.black)\\\\\\\
- term.clear()\\\\\\\
- term.setCursorPos(1,1)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function button(text, x1, x2, y)\\\\\\\
- term.setCursorPos(x1, y)\\\\\\\
- print(text)\\\\\\\
- local a, b, xx, yy = os.pullEvent(\\\\\\\"mouse_click\\\\\\\")\\\\\\\
- if (xx >= x1 and xx <= x2 and yy == y) then\\\\\\\
- return true\\\\\\\
- else\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function counter(text, y)\\\\\\\
- for i=1,100 do\\\\\\\
- sleep(0.1)\\\\\\\
- term.setCursorPos(1, y)\\\\\\\
- print(text..\\\\\\\" [\\\\\\\"..tostring(i)..\\\\\\\"%]\\\\\\\")\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function drawProgress(txt, y)\\\\\\\
- term.setCursorPos(4, 4)\\\\\\\
- print(txt)\\\\\\\
- term.setCursorPos(1, y)\\\\\\\
- print(\\\\\\\"[ ]\\\\\\\")\\\\\\\
- term.setCursorPos(2, y)\\\\\\\
- textutils.slowPrint(\\\\\\\"==============================]\\\\\\\", 10)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function drawProgressBig(color)\\\\\\\
- term.setCursorPos(4, 10)\\\\\\\
- print(\\\\\\\"\\\\\\\\#-------------------------------------------\\\\\\\\#\\\\\\\")\\\\\\\
- term.setCursorPos(4, 11)\\\\\\\
- print(\\\\\\\"| |\\\\\\\")\\\\\\\
- term.setCursorPos(4, 12)\\\\\\\
- print(\\\\\\\"\\\\\\\\#-------------------------------------------\\\\\\\\#\\\\\\\")\\\\\\\
- term.setBackgroundColor(color or colors.yellow)\\\\\\\
- term.setCursorPos(5, 11)\\\\\\\
- textutils.slowWrite(\\\\\\\" \\\\\\\", 10)\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function printColoredTextLine(y, txt, bg, fg)\\\\\\\
- term.setCursorPos(1, y)\\\\\\\
- term.setBackgroundColor(bg or colors.lightGray)\\\\\\\
- term.write(\\\\\\\" \\\\\\\")\\\\\\\
- term.setCursorPos(1, y)\\\\\\\
- term.setTextColor(fg or colors.black)\\\\\\\
- print(txt)\\\\\\\
- term.setBackgroundColor(colors.black)\\\\\\\
- term.setTextColor(colors.white)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function outputInfo(header, msg)\\\\\\\
- term.setTextColor(colors.cyan)\\\\\\\
- write(header..\\\\\\\": \\\\\\\")\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\
- print(msg)\\\\\\\
- term.setTextColor(colors.white)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function outputWarning(header, msg)\\\\\\\
- term.setTextColor(colors.red)\\\\\\\
- write(header..\\\\\\\": \\\\\\\")\\\\\\\
- term.setTextColor(colors.orange)\\\\\\\
- print(msg)\\\\\\\
- term.setTextColor(colors.white)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function outputSuccess(header, msg)\\\\\\\
- term.setTextColor(colors.lime)\\\\\\\
- write(header..\\\\\\\": \\\\\\\")\\\\\\\
- term.setTextColor(colors.green)\\\\\\\
- print(msg)\\\\\\\
- term.setTextColor(colors.white)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function request(req)\\\\\\\
- while true do\\\\\\\
- term.setTextColor(colors.cyan)\\\\\\\
- write(req .. \\\\\\\"? \\\\\\\")\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\
- write(\\\\\\\"(\\\\\\\")\\\\\\\
- term.setTextColor(colors.lime)\\\\\\\
- write(\\\\\\\"Y\\\\\\\")\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\
- write(\\\\\\\"/\\\\\\\")\\\\\\\
- term.setTextColor(colors.red)\\\\\\\
- write(\\\\\\\"N\\\\\\\")\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\
- write(\\\\\\\") \\\\\\\")\\\\\\\
- local presel=read()\\\\\\\
- if presel==\\\\\\\"Y\\\\\\\" or presel==\\\\\\\"y\\\\\\\" then\\\\\\\
- return true\\\\\\\
- elseif presel==\\\\\\\"N\\\\\\\" or presel==\\\\\\\"n\\\\\\\" then\\\\\\\
- return false\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function drawImg(path, x, y)\\\\\\\
- if fs.exists(path) and not fs.isDir(path) then\\\\\\\
- local img = paintutils.loadImage(path)\\\\\\\
- paintutils.drawImage(img, x, y)\\\\\\\
- else\\\\\\\
- gui.outputWarning(\\\\\\\"gui\\\\\\\", \\\\\\\"image not found\\\\\\\")\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function drawDialogBox(prompt)\\\\\\\
- drawImg(\\\\\\\"/etc/resources/dialog_box.img\\\\\\\", 1, 1)\\\\\\\
- term.setCursorPos(6,7)\\\\\\\
- term.setBackgroundColor(colors.white)\\\\\\\
- term.setTextColor(colors.black)\\\\\\\
- print(prompt)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function drawDialogButton(text, newline)\\\\\\\
- stdoutg(text, colors.gray, colors.white)\\\\\\\
- if newline then\\\\\\\
- stdoutg(\\\\\\\"\\\\\\\\n\\\\\\\", colors.gray, colors.white)\\\\\\\
- else\\\\\\\
- stdoutg(\\\\\\\" \\\\\\\", colors.gray, colors.white)\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function printColored(text, color)\\\\\\\
- local tmp = term.getTextColor()\\\\\\\
- term.setTextColor(color)\\\\\\\
- print(text)\\\\\\\
- term.setTextColor(tmp)\\\\\\\
- end\\\\\\\
- \\\\\\\
- function drawBootMenu(array, state1, state2, pos_x, pos_y)\\\\\\\
- local select = 1\\\\\\\
- local x, y = term.getCursorPos()\\\\\\\
- \\\\\\\
- while true do\\\\\\\
- term.setCursorPos(x, y)\\\\\\\
- mprint(array, select, state1, state2, pos_x, pos_y)\\\\\\\
- event, key = os.pullEvent(\\\\\\\"key\\\\\\\")\\\\\\\
- --Enter\\\\\\\
- if key == 28 then \\\\\\\
- return select \\\\\\\
- end\\\\\\\
- \\\\\\\
- if #array > 1 then\\\\\\\
- --Arrow UP or W key\\\\\\\
- if key == 200 or key == 17 then \\\\\\\
- \\\\009\\\\009 select = select - 1 \\\\\\\
- \\\\009\\\\009\\\\009\\\\\\\
- if select < 1 then \\\\\\\
- select = #array \\\\\\\
- end\\\\\\\
- --Arrow Down or S key\\\\\\\
- elseif key == 208 or key == 31 then \\\\\\\
- \\\\009\\\\009 select = select + 1 \\\\\\\
- \\\\009\\\\009\\\\009 if select > #array then select = 1 end\\\\\\\
- \\\\009 end\\\\\\\
- end \\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- function drawContextMenu(...)\\\\\\\
- if #arg < 3 or type(arg[3]) ~= \\\\\\\"table\\\\\\\" then error(\\\\\\\"Usage: UI.drawContextMenu(number x, number y, table Element1, table Element2, table Element3...) \\\\\\\\nReturns: string Action \\\\\\\\n<Element> structure: {string Name[, boolean isElementHidden][,number colorOfText]}\\\\\\\") end\\\\\\\
- local xSize, ySize = term.getSize()\\\\\\\
- \\\\\\\
- local function text(x,y,text1,color)\\\\\\\
- term.setTextColor(color)\\\\\\\
- term.setCursorPos(x,y)\\\\\\\
- term.write(text1)\\\\\\\
- end\\\\\\\
- \\\\\\\
- local Objects = {}\\\\\\\
- local function newObj(name,isHidden,xStart,xEnd,y)\\\\\\\
- Objects[name]={}\\\\\\\
- Objects[name][\\\\\\\"isHidden\\\\\\\"] = isHidden\\\\\\\
- Objects[name][\\\\\\\"xStart\\\\\\\"] = xStart\\\\\\\
- Objects[name][\\\\\\\"xEnd\\\\\\\"] = xEnd\\\\\\\
- Objects[name][\\\\\\\"y\\\\\\\"] = y\\\\\\\
- end\\\\\\\
- \\\\\\\
- local theLongestElement = #arg[3][1]\\\\\\\
- for i=3,#arg do\\\\\\\
- if arg[i] ~= \\\\\\\"-\\\\\\\" and theLongestElement < #arg[i][1] then\\\\\\\
- theLongestElement = #arg[i][1]\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local xSizeOfMenu = theLongestElement + 4\\\\\\\
- local ySizeOfMenu = #arg-2\\\\\\\
- \\\\\\\
- local xStartToDisplay = nil\\\\\\\
- local yStartToDisplay = nil\\\\\\\
- \\\\\\\
- local function square(x1,y1,width,height,color)\\\\\\\
- local string = string.rep(\\\\\\\" \\\\\\\",width)\\\\\\\
- term.setBackgroundColor(color)\\\\\\\
- for y=y1,(y1+height-1) do\\\\\\\
- term.setCursorPos(x1,y)\\\\\\\
- term.write(string)\\\\\\\
- end\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function drawSeparator(x,y,size)\\\\\\\
- term.setTextColor(colors.lightGray)\\\\\\\
- term.setCursorPos(x,y)\\\\\\\
- term.write(string.rep(\\\\\\\"-\\\\\\\",size))\\\\\\\
- end\\\\\\\
- \\\\\\\
- local function drawMenu(xMenu,yMenu)\\\\\\\
- if yMenu+ySizeOfMenu - 1 >= ySize then yMenu = yMenu - (yMenu+ySizeOfMenu - 1 - ySize) - 1 end\\\\\\\
- if xMenu+xSizeOfMenu - 1 >= xSize then xMenu = xMenu - (xMenu+xSizeOfMenu - 1 - xSize) - 1 end\\\\\\\
- xStartToDisplay = xMenu + 2\\\\\\\
- yStartToDisplay = yMenu\\\\\\\
- square(xMenu+1,yMenu+1,xSizeOfMenu,ySizeOfMenu,colors.gray)\\\\\\\
- square(xMenu,yMenu,xSizeOfMenu,ySizeOfMenu,colors.white)\\\\\\\
- for i=3,#arg do\\\\\\\
- if arg[i] ~= \\\\\\\"-\\\\\\\" then\\\\\\\
- local contextColor = colors.black\\\\\\\
- if arg[i][2] == nil and arg[i][3] == nil then\\\\\\\
- contextColor = colors.black\\\\\\\
- elseif arg[i][2] == false and arg[i][3] == nil then\\\\\\\
- contextColor = colors.black\\\\\\\
- elseif arg[i][2] == false and arg[i][3] ~= nil then\\\\\\\
- contextColor = arg[i][3]\\\\\\\
- elseif arg[i][2] == true then\\\\\\\
- contextColor = colors.lightGray\\\\\\\
- end\\\\\\\
- text(xStartToDisplay,yStartToDisplay+i-3,arg[i][1],contextColor)\\\\\\\
- newObj(arg[i][1],arg[i][2],xMenu,xMenu+xSizeOfMenu-1,yStartToDisplay+i-3)\\\\\\\
- else\\\\\\\
- drawSeparator(xMenu,yStartToDisplay+i-3,xSizeOfMenu)\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- drawMenu(arg[1],arg[2])\\\\\\\
- local event,side,xClick,yClick = os.pullEvent()\\\\\\\
- if event == \\\\\\\"monitor_touch\\\\\\\" then side = 1 end\\\\\\\
- if event == \\\\\\\"mouse_click\\\\\\\" or event == \\\\\\\"monitor_touch\\\\\\\" then\\\\\\\
- for key,val in pairs(Objects) do\\\\\\\
- if xClick >= Objects[key][\\\\\\\"xStart\\\\\\\"] and xClick <= Objects[key][\\\\\\\"xEnd\\\\\\\"] and yClick == Objects[key][\\\\\\\"y\\\\\\\"] and Objects[key][\\\\\\\"isHidden\\\\\\\"] == false or xClick >= Objects[key][\\\\\\\"xStart\\\\\\\"] and xClick <= Objects[key][\\\\\\\"xEnd\\\\\\\"] and yClick == Objects[key][\\\\\\\"y\\\\\\\"] and Objects[key][\\\\\\\"isHidden\\\\\\\"] == nil then\\\\\\\
- for i=Objects[key][\\\\\\\"xStart\\\\\\\"],Objects[key][\\\\\\\"xEnd\\\\\\\"] do\\\\\\\
- paintutils.drawPixel(i,Objects[key][\\\\\\\"y\\\\\\\"],colors.blue)\\\\\\\
- end\\\\\\\
- text(xStartToDisplay,Objects[key][\\\\\\\"y\\\\\\\"],key,colors.white)\\\\\\\
- sleep(0.3)\\\\\\\
- return key\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- end\\\\\\\
- ]]\\\\\\\
- persist(\\\\\\\"UI\\\\\\\", libcode)\\\\\\\
- \\\\\\\
- return 1\\\"\",\
- }",
- "D:lib",
- [ 13 ] = "F:startup",
- [ 14 ] = "\"if not term.isColor() then\\\
- error(\\\"LEFI cannot run on non-advanced computers.\\\")\\\
- end\\\
- \\\
- -- Declare extended Lua attributes\\\
- \\\
- rawset(_G, \\\"__declare\\\", function(g, v)\\\
- return rawset(_G, g, v)\\\
- end)\\\
- \\\
- __declare(\\\"__declare_api\\\", function(a, g, v)\\\
- return rawset(_G[a], g, v)\\\
- end)\\\
- \\\
- __declare(\\\"__try\\\", function(f, e)\\\
- local r = {pcall(f)}\\\
- if table.remove(r, 1) == true then\\\
- return unpack(r)\\\
- else\\\
- if e ~= nil then\\\
- e(unpack(r))\\\
- else\\\
- return __kstop(0x0000FFFF, unpack(r))\\\
- end\\\
- end\\\
- end)\\\
- \\\
- __declare(\\\"__kstruct\\\", function(t)\\\
- if t == _G then\\\
- return setmetatable({}, {\\\
- __index = t,\\\
- __newindex = function(table, key, value)\\\
- __kstop(0x00000004, table, key, value)\\\
- end,\\\
- __metatable = {}\\\
- })\\\
- else\\\
- return setmetatable({}, {\\\
- __index = t,\\\
- __newindex = function(table, key, value)\\\
- __kstop(0x00000005, table, key, value)\\\
- end,\\\
- __metatable = {}\\\
- })\\\
- end\\\
- end)\\\
- \\\
- -- declare library persistence loader\\\
- __declare(\\\"persist\\\", function(n, c)\\\
- local h = fs.open(\\\"/tmp/\\\"..n, \\\"w\\\")\\\
- h.writeLine(c)\\\
- h.close()\\\
- os.loadAPI(\\\"/tmp/\\\"..n)\\\
- fs.delete(\\\"/tmp/\\\"..n)\\\
- end)\\\
- \\\
- __declare(\\\"drawBootManager\\\", function(opt)\\\
- term.setBackgroundColor(colors.black)\\\
- term.clear()\\\
- term.setCursorPos(1,1)\\\
- \\009if not opt then\\\
- boot_printColoredTextLine(2, \\\" Orbital Boot Manager v1.0 \\\", colors.lightGray, colors.black)\\\
- boot_printColoredTextLine(18, \\\" F2=ESI Setup F10=Boot Menu \\\", colors.lightGray, colors.black)\\\
- \\009else\\\
- boot_printColoredTextLine(2, \\\" Orbital Boot Manager v2.1 \\\", colors.red, colors.black)\\\
- boot_printColoredTextLine(18, \\\" CTRL+R=Reboot \\\", colors.red, colors.black)\\\
- \\009end\\\
- end)\\\
- \\\
- local sr = shell.run\\\
- \\\
- if not fs.isDir(\\\"/boot\\\") or not loadfile(\\\"/boot/esi/esiboot.b\\\") then\\\
- drawBootManager(true)\\\
- term.setBackgroundColor(colors.black)\\\
- term.setTextColor(colors.red)\\009\\\
- \\009term.setCursorPos(2,4)\\\
- \\009print(\\\"The Orbital Boot Manager was unable to boot the\\\")\\\
- \\009term.setCursorPos(2,5)\\\
- \\009print(\\\"operating system.\\\")\\\
- \\009term.setCursorPos(2,7)\\\
- \\009print(\\\"Status:\\\")\\\
- \\009term.setCursorPos(2,8)\\\
- \\009print(\\\"ESI_BINARIES_INVALID (0x00000002)\\\")\\\
- \\009term.setCursorPos(2,10)\\\
- \\009print(\\\"Information:\\\")\\\
- \\009term.setCursorPos(2,11)\\\
- \\009print(\\\"One or more ESI files are missing.\\\")\\\
- \\009term.setCursorPos(2,12)\\\
- \\009print(\\\"Please re-install the operating system.\\\")\\\
- while true do\\\
- \\009 sleep(1)\\\
- \\009end\\\
- end\\\
- \\\
- sr(\\\"/boot/esi/esiboot.b\\\")\"",
- [ 15 ] = "F:startup",
- }
Add Comment
Please, Sign In to add comment