Guest User

GridOS (Discontinued)

a guest
May 17th, 2015
306
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- GridOS version 0.1.0 by CrazedProgrammer
  2. -- This is a discontinued project.
  3. -- You may do anything with this and you don't have to give credit.
  4.  
  5. local function loadAPI(name, str)
  6.     local env = {}
  7.     setmetatable(env, {__index = _G})
  8.     local fn, err = loadstring(str, name)
  9.     if fn then
  10.         setfenv(fn, env)
  11.         local ok, err = pcall(fn)
  12.         if not ok then
  13.             error(err)
  14.         end
  15.     else
  16.         error(err)
  17.     end
  18.     local api = {}
  19.     for k,v in pairs(env) do
  20.         if k ~= "_ENV" then
  21.             api[k] = v
  22.         end
  23.     end
  24.     return api
  25. end
  26.  
  27. local surface = nil
  28. local startmenu = "local a={...}local b=a\[1\]local c=a\[2\]local d=a\[3\]local e,f,g,h,i=nil;local j=os.startTimer(0)local function k()g,h=term.getSize()i=b.create(g,h)e,f=2,2;if g<18 then e=1 end;if h<7 then f=1 end end;multishell.setTitle(multishell.getCurrent(),\"start menu\")k()while true do local l={os.pullEvent()}if l\[1\]==\"timer\"and l\[2\]==j then i:clear(nil,colors.white,colors.black)i:drawText(e,f,\"Launch Shell\")i:drawText(e,f+1,\"Shortcut Settings\")i:drawText(e,f+2,\"Skin Settings\")i:drawText(e,f+3,\"Close GridOS\")i:drawText(e,f+4,\"Shutdown\")i:drawText(e,f+5,\"Reboot\")i:render()j=os.startTimer(0)elseif l\[1\]==\"term_resize\"then k()elseif l\[1\]==\"mouse_click\"then if l\[3\]>=e and l\[3\]<=e+16 then if l\[4\]==f then multishell.setFocus(multishell.launch({shell=shell,multishell=multishell},\"rom/programs/shell\"))elseif l\[4\]==f+3 then d\[1\]=false elseif l\[4\]==f+4 then os.shutdown()elseif l\[4\]==f+5 then os.reboot()end end end end"
  29. local dir = fs.getDir(shell.getRunningProgram()).."/"
  30. local config = nil
  31. local parentTerm = term.current()
  32. local parentShell = shell
  33. local width, height, surf = nil
  34. local processes = { }
  35. local multishell = { }
  36. local order = { }
  37. local current = 1
  38. local offset = 0
  39. local mode = 0
  40. local lockX, lockY = nil
  41. local running = {true}
  42. local osTimer = os.startTimer(0)
  43.  
  44. local function loadConfig()
  45.     local f = fs.open(dir.."config.tab", "r")
  46.     if f then
  47.         config = textutils.unserialize(f.readAll())
  48.         f.close()
  49.     else
  50.         config = {bounds={},skin={bc=256,gridbc=32768,gridtc=1,taskbc=128,taskscrbc=128,taskscrtc=32768,taskacttc=1,tasknortc=256,taskmintc=32768,wintopbc=128,winrightbc=128,wintitletc=1,winminbc=128,winmintc=32768,winclosebc=128,winclosetc=16384,winresizebc=128,winresizetc=32768}}
  51.     end
  52. end
  53.  
  54. local function saveConfig()
  55.     if config then
  56.         local f = fs.open(dir.."config.tab", "w")
  57.         if f then
  58.             f.write(textutils.serialize(config))
  59.             f.close()
  60.         end
  61.     end
  62. end
  63.  
  64. local function checkOffset()
  65.     if offset < 0 then
  66.         offset = 0
  67.         return
  68.     elseif offset ~= 0 then
  69.         local m = 0
  70.         for i=1,#processes do
  71.             m = m + #processes[i].title + 2
  72.         end
  73.         if offset > m - width + 4 then
  74.             offset = m - width + 4
  75.         end
  76.         if offset < 0 then
  77.             offset = 0
  78.         end
  79.     end
  80. end
  81.  
  82. local function removeProcess(n)
  83.     config.bounds[processes[n].path] = {x = processes[n].x, y = processes[n].y, width = processes[n].width, height = processes[n].height}
  84.     table.remove(processes, n)
  85.     for i=1,#order do
  86.         if order[i] == n then
  87.             table.remove(order, i)
  88.             break
  89.         end
  90.     end
  91.     for i=1,#order do
  92.         if order[i] > n then
  93.             order[i] = order[i] - 1
  94.         end
  95.     end
  96.     checkOffset()
  97. end
  98.  
  99. local function resumeProcess(n, event, ...)
  100.     if processes[n].filter == nil or processes[n].filter == event or event == "terminate" then
  101.         current = n
  102.         local prev = term.redirect(processes[n].term)
  103.         local ok, result = coroutine.resume(processes[n].coroutine, event, ...)
  104.         processes[n].term = term.current()
  105.         term.redirect(prev)
  106.         if ok then
  107.             processes[n].filter = result
  108.         else
  109.             printError(result)
  110.         end
  111.         if coroutine.status(processes[n].coroutine) == "dead" then
  112.             removeProcess(n)
  113.         end
  114.     end
  115. end
  116.  
  117. local function resizeProcess(n, width, height)
  118.     if width < 6 then
  119.         width = 6
  120.     end
  121.     if height < 2 then
  122.         height = 2
  123.     end
  124.     if width ~= processes[n].width or height ~= processes[n].height then
  125.         processes[n].width = width
  126.         processes[n].height = height
  127.         local surf = surface.create(width - 1, height - 1)
  128.         surf:drawSurface(1, 1, processes[n].surface)
  129.         surf.blink, surf.curX, surf.curY = processes[n].surface.blink, processes[n].surface.curX, processes[n].surface.curY
  130.         processes[n].surface = surf
  131.         for k,v in pairs(surf:getTerm()) do
  132.             processes[n].surfterm[k] = v
  133.         end
  134.         resumeProcess(n, "term_resize")
  135.     end
  136. end
  137.  
  138. local function getBounds(x, y, w, h)
  139.     if w > width then
  140.         w = width
  141.     end
  142.     if h > height - 1 then
  143.         h = height - 1
  144.     end
  145.     if y > height then
  146.         y = height
  147.     end
  148.     if y < 2 then
  149.         y = 2
  150.     end
  151.     if x > width then
  152.         x = width
  153.     end
  154.     if x < 1 then
  155.         x = 1
  156.     end
  157.     return x, y, w, h
  158. end
  159.  
  160. local function distributeEvent(...)
  161.     local limit = #processes
  162.     for i=1,limit do
  163.         resumeProcess(i, ...)
  164.     end
  165. end
  166.  
  167. local function getFront()
  168.     local p = nil
  169.     for i=1,#order do
  170.         if not processes[order[i]].minimized then
  171.             p = order[i]
  172.             break
  173.         end
  174.     end
  175.     if p then
  176.         processes[p].interacted = true
  177.         return p
  178.     end
  179. end
  180.  
  181. local function resize()
  182.     width, height = parentTerm.getSize()
  183.     surf = surface.create(width, height)
  184.     local limit = #processes
  185.     for i=1,limit do
  186.         local x, y, w, h = getBounds(processes[i].x, processes[i].y, processes[i].width, processes[i].height)
  187.         processes[i].x, processes[i].y = x, y
  188.         if w ~= processes[i].width or h ~= processes[i].height then
  189.             resizeProcess(i, w, h)
  190.         end
  191.     end
  192. end
  193.  
  194. function multishell.getFocus()
  195.     return getFront() or 1
  196. end
  197.  
  198. function multishell.setFocus(n)
  199.     if processes[n] then
  200.         if n ~= getFront() then
  201.             for i=1,#order do
  202.                 if order[i] == n then
  203.                     table.remove(order, i)
  204.                     break
  205.                 end
  206.             end
  207.             table.insert(order, 1, n)
  208.             processes[n].minimized = false
  209.         end
  210.         processes[n].interacted = true
  211.         return true
  212.     end
  213.     return false
  214. end
  215.  
  216. function multishell.getTitle(n)
  217.     if processes[n] then
  218.         return processes[n].title
  219.     end
  220. end
  221.  
  222. function multishell.setTitle(n, title)
  223.     if processes[n] then
  224.         if title ~= "shell" then
  225.             --os.sleep(0.1)
  226.         end
  227.         processes[n].title = title
  228.     end
  229. end
  230.  
  231. function multishell.getCurrent()
  232.     return current
  233. end
  234.  
  235. function multishell.launch(env, path, ...)
  236.     local process = { }
  237.     local p = #processes + 1
  238.     process.path = path
  239.     process.title = fs.getName(path)
  240.     if path == "rom/programs/shell" and arg[1] then
  241.         process.path = arg[1]
  242.         process.title = fs.getName(arg[1])
  243.     end
  244.     if config.bounds[path] then
  245.         process.x, process.y, process.width, process.height = config.bounds[path].x, config.bounds[path].y, config.bounds[path].width, config.bounds[path].height
  246.     else
  247.         process.x, process.y, process.width, process.height = math.random(2, 10), math.random(2,5), 40, 15
  248.     end
  249.     process.x, process.y, process.width, process.height = getBounds(process.x, process.y, process.width, process.height)
  250.     process.minimized = false
  251.     process.surface = surface.create(process.width - 1, process.height - 1)
  252.     process.surfterm = process.surface:getTerm()
  253.     process.term = process.surfterm
  254.     process.coroutine = coroutine.create(function ()
  255.         os.run(env, path, unpack(arg))
  256.         if not process.interacted then
  257.             term.setCursorBlink(false)
  258.             print("Press any key to continue")
  259.             os.pullEvent("char")
  260.         end
  261.     end)
  262.     processes[p] = process
  263.     table.insert(order, p)
  264.     resumeProcess(p)
  265.     return p
  266. end
  267.  
  268. function multishell.getCount()
  269.     return #processes
  270. end
  271.  
  272. local function run()
  273.     surface = loadAPI("surface", "version=\"1.6.2\"local a,b,c,d,e=math.floor,math.cos,math.sin,table.concat,{\[1\]=\"0\",\[2\]=\"1\",\[4\]=\"2\",\[8\]=\"3\",\[16\]=\"4\",\[32\]=\"5\",\[64\]=\"6\",\[128\]=\"7\",\[256\]=\"8\",\[512\]=\"9\",\[1024\]=\"a\",\[2048\]=\"b\",\[4096\]=\"c\",\[8192\]=\"d\",\[16384\]=\"e\",\[32768\]=\"f\"}local function f(g,h,i,j,k,l)local m=k-i;local n=m>0 and 1 or-1;m=2*math.abs(m)local o=l-j;local p=o>0 and 1 or-1;o=2*math.abs(o)g\[(j-1)*h+i\]=true;if m>=o then local q=o-m/2;while i~=k do if q>=0 and q~=0 or n>0 then q=q-m;j=j+p end;q=q+o;i=i+n;g\[(j-1)*h+i\]=true end else local q=m-o/2;while j~=l do if q>=0 and q~=0 or p>0 then q=q-o;i=i+n end;q=q+m;j=j+p;g\[(j-1)*h+i\]=true end end end;local r={setBounds=function(s,i,j,k,l)if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;if k<1 or i>s.width or l<1 or j>s.height then return end;if i<1 then i=1 end;if k>s.width then k=s.width end;if j<1 then j=1 end;if l>s.height then l=s.height end;s.x1,s.y1,s.x2,s.y2=i,j,k,l end,getBounds=function(s)return s.x1,s.y1,s.x2,s.y2 end,copy=function(s)local u=create(s.width,s.height)u.x1,u.y1,u.x2,u.y2,u.blink,u.curX,u.curY,u.overwrite=s.x1,s.y1,s.x2,s.y2,s.blink,s.curX,s.curY,s.overwrite;for v=1,s.width*s.height*3 do u.buffer\[v\]=s.buffer\[v\]end;return u end,save=function(s,w,x)x=x or\"srf\"local y=fs.open(w,\"w\")if x==\"nfp\"then local z=nil;for A=1,s.height do if A>1 then y.write(\"\\n\")end;for v=1,s.width do z=s.buffer\[((A-1)*s.width+v)*3-1\]if z then y.write(e\[z\])else y.write(\" \")end end end elseif x==\"nft\"then local B,C,char=nil;for A=1,s.height do if A>1 then y.write(\"\\n\")end;B,C=nil;for v=1,s.width do if B~=s.buffer\[((A-1)*s.width+v)*3-1\]then y.write(string.char(30))B=s.buffer\[((A-1)*s.width+v)*3-1\]if B then y.write(e\[B\])else y.write(\" \")end end;if C~=s.buffer\[((A-1)*s.width+v)*3\]then y.write(string.char(31))C=s.buffer\[((A-1)*s.width+v)*3\]if C then y.write(e\[C\])else y.write(\" \")end end;char=s.buffer\[((A-1)*s.width+v)*3-2\]if char then y.write(char)else y.write(\" \")end end end elseif x==\"srf\"then y.write(s:saveString())end;y.close()end,saveString=function(s)local D={\"_\"..string.format(\"%04x\",s.width)..string.format(\"%04x\",s.height)}for A=1,s.height do for v=1,s.width do if s.buffer\[((A-1)*s.width+v)*3-2\]then D\[#D+1\]=string.format(\"%02x\",s.buffer\[((A-1)*s.width+v)*3-2\]:byte(1))else D\[#D+1\]=\"__\"end;if s.buffer\[((A-1)*s.width+v)*3-1\]then D\[#D+1\]=e\[s.buffer\[((A-1)*s.width+v)*3-1\]\]else D\[#D+1\]=\"_\"end;if s.buffer\[((A-1)*s.width+v)*3\]then D\[#D+1\]=e\[s.buffer\[((A-1)*s.width+v)*3\]\]else D\[#D+1\]=\"_\"end end end;return d(D)end,getTerm=function(s)local term,B,C={},colors.black,colors.white;function term.write(D)s:drawText(s.curX,s.curY,tostring(D),B,C)s.curX=s.curX+#tostring(D)end;function term.blit(D,E,F)for v=1,#D do if s.curX>=s.x1 and s.curY>=s.y1 and s.curX<=s.x2 and s.curY<=s.y2 then s.buffer\[((s.curY-1)*s.width+s.curX)*3-2\]=D:sub(v,v)s.buffer\[((s.curY-1)*s.width+s.curX)*3-1\]=2^tonumber(F:sub(v,v),16)s.buffer\[((s.curY-1)*s.width+s.curX)*3\]=2^tonumber(E:sub(v,v),16)end;s.curX=s.curX+1 end end;function term.clear()s:clear(\" \",B,C)end;function term.clearLine(G)s:drawHLine(s.x1,s.x2,s.curY,\" \",B,C)end;function term.getCursorPos()return s.curX,s.curY end;function term.setCursorPos(H,I)s.curX,s.curY=a(H),a(I)end;function term.setCursorBlink(J)s.blink=J end;function term.isColor()return true end;term.isColour=term.isColor;function term.setTextColor(z)C=z end;term.setTextColour=term.setTextColor;function term.setBackgroundColor(z)B=z end;term.setBackgroundColour=term.setBackgroundColor;function term.getSize()return s.width,s.height end;function term.scroll(G)s:shift(0,-G)end;function term.getTextColor()return C end;term.getTextColour=term.getTextColor;function term.getBackgroundColor()return B end;term.getBackgroundColour=term.getBackgroundColor;return term end,render=function(s,K,H,I,L,M,N,O)K,H,I,L,M,N,O=K or term,H or 1,I or 1,L or 1,M or 1,N or s.width,O or s.height;if L>N then local t=L;L,N=N,t end;if M>O then local t=M;M,O=O,t end;if N<1 or L>s.width or O<1 or M>s.height then return end;if L<1 then L=1 end;if N>s.width then N=s.width end;if M<1 then M=1 end;if O>s.height then O=s.height end;local P={}if K.blit then local D,F,E={},{},{}for A=M,O do for v=L,N do D\[v-L+1\]=s.buffer\[((A-1)*s.width+v)*3-2\]or\" \"F\[v-L+1\]=e\[s.buffer\[((A-1)*s.width+v)*3-1\]or 32768\]E\[v-L+1\]=e\[s.buffer\[((A-1)*s.width+v)*3\]or 1\]end;P\[#P+1\]=I+A-M;P\[#P+1\]=d(D)P\[#P+1\]=d(E)P\[#P+1\]=d(F)end;for v=1,#P,4 do K.setCursorPos(H,P\[v\])K.blit(P\[v+1\],P\[v+2\],P\[v+3\])end else local D,B,C,Q,R=\"\",0,0;for A=M,O do P\[#P+1\]=1;P\[#P+1\]=I+A-M;for v=L,N do Q,R=s.buffer\[((A-1)*s.width+v)*3-1\]or 32768,s.buffer\[((A-1)*s.width+v)*3\]or 1;if Q~=B then B=Q;if D~=\"\"then P\[#P+1\]=4;P\[#P+1\]=D;D=\"\"end;P\[#P+1\]=2;P\[#P+1\]=B end;if R~=C then C=R;if D~=\"\"then P\[#P+1\]=4;P\[#P+1\]=D;D=\"\"end;P\[#P+1\]=3;P\[#P+1\]=C end;D=D..s.buffer\[((A-1)*s.width+v)*3-2\]or\" \"end;P\[#P+1\]=4;P\[#P+1\]=D;D=\"\"end;local S,T=nil;for v=1,#P,2 do S,T=P\[v\],P\[v+1\]if S==1 then K.setCursorPos(H,T)elseif S==2 then K.setBackgroundColor(T)elseif S==3 then K.setTextColor(T)else K.write(T)end end end;if s.blink and s.curX>=1 and s.curY>=1 and s.curX<=s.width and s.curY<=s.height then K.setCursorPos(H+s.curX-L,I+s.curY-M)K.setCursorBlink(true)elseif s.blink==false then K.setCursorBlink(false)s.blink=nil end;return#P/2 end,clear=function(s,char,B,C)local U=s.overwrite;s.overwrite=true;s:fillRect(s.x1,s.y1,s.x2,s.y2,char,B,C)s.overwrite=U end,drawPixel=function(s,H,I,char,B,C)if H<s.x1 or I<s.y1 or H>s.x2 or I>s.y2 then return end;if char or s.overwrite then s.buffer\[((I-1)*s.width+H)*3-2\]=char end;if B or s.overwrite then s.buffer\[((I-1)*s.width+H)*3-1\]=B end;if C or s.overwrite then s.buffer\[((I-1)*s.width+H)*3\]=C end end,getPixel=function(s,H,I)if H<1 or I<1 or H>s.width or I>s.height then return end;return s.buffer\[((I-1)*s.width+H)*3-2\],s.buffer\[((I-1)*s.width+H)*3-1\],s.buffer\[((I-1)*s.width+H)*3\]end,drawText=function(s,H,I,E,B,C)local V=H;for v=1,#E do if E:sub(v,v)~=\"\\n\"then if H>=s.x1 and I>=s.y1 and H<=s.x2 and I<=s.y2 then s.buffer\[((I-1)*s.width+H)*3-2\]=E:sub(v,v)if B or s.overwrite then s.buffer\[((I-1)*s.width+H)*3-1\]=B end;if C or s.overwrite then s.buffer\[((I-1)*s.width+H)*3\]=C end end else H=V-1;I=I+1 end;H=H+1 end end,drawLine=function(s,i,j,k,l,char,B,C)local m=k-i;local n=m>0 and 1 or-1;m=2*math.abs(m)local o=l-j;local p=o>0 and 1 or-1;o=2*math.abs(o)s:drawPixel(i,j,char,B,C)if m>=o then local q=o-m/2;while i~=k do if q>=0 and q~=0 or n>0 then q=q-m;j=j+p end;q=q+o;i=i+n;s:drawPixel(i,j,char,B,C)end else local q=m-o/2;while j~=l do if q>=0 and q~=0 or p>0 then q=q-o;i=i+n end;q=q+m;j=j+p;s:drawPixel(i,j,char,B,C)end end end,drawLines=function(s,W,X,char,B,C)X=X or 1;if X==1 then for v=1,#W,4 do s:drawLine(W\[v\],W\[v+1\],W\[v+2\],W\[v+3\],char,B,C)end elseif X==2 then local Y,Z=W\[1\],W\[2\]for v=3,#W,2 do local _,a0=W\[v\],W\[v+1\]s:drawLine(Y,Z,_,a0,char,B,C)Y=_;Z=a0 end elseif X==3 then local a1,a2=W\[1\],W\[2\]for v=3,#W,2 do s:drawLine(a1,a2,W\[v\],W\[v+1\],char,B,C)end end end,drawHLine=function(s,i,k,I,char,B,C)if i>k then local t=i;i,k=k,t end;if I<s.y1 or I>s.y2 or k<s.x1 or i>s.x2 then return end;if i<s.x1 then i=s.x1 end;if k>s.x2 then k=s.x2 end;if char or s.overwrite then for H=i,k do s.buffer\[((I-1)*s.width+H)*3-2\]=char end end;if B or s.overwrite then for H=i,k do s.buffer\[((I-1)*s.width+H)*3-1\]=B end end;if C or s.overwrite then for H=i,k do s.buffer\[((I-1)*s.width+H)*3\]=C end end end,drawVLine=function(s,j,l,H,char,B,C)if j>l then local t=j;j,l=l,t end;if H<s.x1 or H>s.x2 or l<s.y1 or j>s.y2 then return end;if j<s.y1 then j=s.y1 end;if l>s.y2 then l=s.y2 end;if char or s.overwrite then for I=j,l do s.buffer\[((I-1)*s.width+H)*3-2\]=char end end;if B or s.overwrite then for I=j,l do s.buffer\[((I-1)*s.width+H)*3-1\]=B end end;if C or s.overwrite then for I=j,l do s.buffer\[((I-1)*s.width+H)*3\]=C end end end,drawRect=function(s,i,j,k,l,char,B,C)s:drawHLine(i,k,j,char,B,C)s:drawHLine(i,k,l,char,B,C)s:drawVLine(j,l,i,char,B,C)s:drawVLine(j,l,k,char,B,C)end,drawRoundRect=function(s,i,j,k,l,char,B,C)s:drawHLine(i+1,k-1,j,char,B,C)s:drawHLine(i+1,k-1,l,char,B,C)s:drawVLine(j+1,l-1,i,char,B,C)s:drawVLine(j+1,l-1,k,char,B,C)end,drawRoundedRect=function(s,i,j,k,l,a3,char,B,C)s:drawHLine(i+a3,k-a3,j,char,B,C)s:drawHLine(i+a3,k-a3,l,char,B,C)s:drawVLine(j+a3,l-a3,i,char,B,C)s:drawVLine(j+a3,l-a3,k,char,B,C)s:drawArc(i,j,i+a3*2+2,j+a3*2+2,-math.pi,-math.pi/2,char,B,C)s:drawArc(k,j,k-a3*2-2,j+a3*2+2,0,-math.pi/2,char,B,C)s:drawArc(i,l,i+a3*2+2,l-a3*2-2,math.pi,math.pi/2,char,B,C)s:drawArc(k,l,k-a3*2-2,l-a3*2-2,0,math.pi/2,char,B,C)end,fillRect=function(s,i,j,k,l,char,B,C)if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;if k<s.x1 or i>s.x2 or l<s.y1 or j>s.y2 then return end;if i<s.x1 then i=s.x1 end;if k>s.x2 then k=s.x2 end;if j<s.y1 then j=s.y1 end;if l>s.y2 then l=s.y2 end;if char or s.overwrite then for I=j,l do for H=i,k do s.buffer\[((I-1)*s.width+H)*3-2\]=char end end end;if B or s.overwrite then for I=j,l do for H=i,k do s.buffer\[((I-1)*s.width+H)*3-1\]=B end end end;if C or s.overwrite then for I=j,l do for H=i,k do s.buffer\[((I-1)*s.width+H)*3\]=C end end end end,fillRoundRect=function(s,i,j,k,l,char,B,C)s:drawHLine(i+1,k-1,j,char,B,C)s:drawHLine(i+1,k-1,l,char,B,C)s:drawVLine(j+1,l-1,i,char,B,C)s:drawVLine(j+1,l-1,k,char,B,C)s:fillRect(i+1,j+1,k-1,l-1,char,B,C)end,fillRoundedRect=function(s,i,j,k,l,a3,char,B,C)s:fillRect(i+a3,j,k-a3,l,char,B,C)s:fillRect(i,j+a3,i+a3,l-a3,char,B,C)s:fillRect(k-a3,j+a3,k,l-a3,char,B,C)s:fillPie(i,j,i+a3*2+2,j+a3*2+2,-math.pi,-math.pi/2,char,B,C)s:fillPie(k,j,k-a3*2-2,j+a3*2+2,0,-math.pi/2,char,B,C)s:fillPie(i,l,i+a3*2+2,l-a3*2-2,math.pi,math.pi/2,char,B,C)s:fillPie(k,l,k-a3*2-2,l-a3*2-2,0,math.pi/2,char,B,C)end,drawTriangle=function(s,i,j,k,l,a4,a5,char,B,C)s:drawLine(i,j,k,l,char,B,C)s:drawLine(k,l,a4,a5,char,B,C)s:drawLine(a4,a5,i,j,char,B,C)end,fillTriangle=function(s,i,j,k,l,a4,a5,char,B,C)local a6,a7,a8,a9=i,j,i,j;if k<a6 then a6=k end;if a4<a6 then a6=a4 end;if l<a7 then a7=l end;if a5<a7 then a7=a5 end;if k>a8 then a8=k end;if a4>a8 then a8=a4 end;if l>a9 then a9=l end;if a5>a9 then a9=a5 end;local h,aa,g,min,max=a8-a6+1,a9-a7+1,{},0,0;f(g,h,i-a6+1,j-a7+1,k-a6+1,l-a7+1)f(g,h,k-a6+1,l-a7+1,a4-a6+1,a5-a7+1)f(g,h,a4-a6+1,a5-a7+1,i-a6+1,j-a7+1)for A=1,aa do min,max=nil;for v=1,h do if g\[(A-1)*h+v\]then if not min then min=v end;max=v end end;s:drawHLine(min+a6-1,max+a6-1,A+a7-1,char,B,C)end end,drawTriangles=function(s,W,X,char,B,C)X=X or 1;if X==1 then for v=1,#W,6 do s:drawTriangle(W\[v\],W\[v+1\],W\[v+2\],W\[v+3\],W\[v+4\],W\[v+5\],char,B,C)end elseif X==2 then local Y,Z,ab,ac,_,a0=W\[1\],W\[2\],W\[3\],W\[4\]for v=5,#W,2 do _,a0=W\[v\],W\[v+1\]s:drawTriangle(Y,Z,ab,ac,_,a0,char,B,C)Y,Z,ab,ac=ab,ac,_,a0 end elseif X==3 then local a1,a2,Y,Z,_,a0=W\[1\],W\[2\],W\[3\],W\[4\]for v=5,#W,2 do _,a0=W\[v\],W\[v+1\]s:drawTriangle(a1,a2,Y,Z,_,a0,char,B,C)Y,Z=_,a0 end end end,fillTriangles=function(s,W,X,char,B,C)X=X or 1;if X==1 then for v=1,#W,6 do s:fillTriangle(W\[v\],W\[v+1\],W\[v+2\],W\[v+3\],W\[v+4\],W\[v+5\],char,B,C)end elseif X==2 then local Y,Z,ab,ac,_,a0=W\[1\],W\[2\],W\[3\],W\[4\]for v=5,#W,2 do _,a0=W\[v\],W\[v+1\]s:fillTriangle(Y,Z,ab,ac,_,a0,char,B,C)Y,Z,ab,ac=ab,ac,_,a0 end elseif X==3 then local a1,a2,Y,Z,_,a0=W\[1\],W\[2\],W\[3\],W\[4\]for v=5,#W,2 do _,a0=W\[v\],W\[v+1\]s:fillTriangle(a1,a2,Y,Z,_,a0,char,B,C)Y,Z=_,a0 end end end,drawEllipse=function(s,i,j,k,l,char,B,C)if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;local ad,ae,af,h,aa,ag,ah=math.pi*2/16,(i+k)/2,(j+l)/2,(k-i)/2,(l-j)/2,1,1;for v=1,17 do local H,I=a(ae+b(ad*v)*h+0.5),a(af+c(ad*v)*aa+0.5)if v>1 then s:drawLine(ag,ah,H,I,char,B,C)end;ag,ah=H,I end end,fillEllipse=function(s,i,j,k,l,char,B,C)if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;local ai,ad,ae,af,h,aa,ag,ah,aj,ak,g=16,math.pi*2/16,(i+k)/2,(j+l)/2,(k-i)/2,(l-j)/2,1,1,k-i+1,l-j+1,{}for v=1,ai+1 do local H,I=a(ae+b(ad*v)*h+0.5),a(af+c(ad*v)*aa+0.5)if v>1 then f(g,aj,ag-i+1,ah-j+1,H-i+1,I-j+1)end;ag,ah=H,I end;for A=1,ak do min,max=nil;for v=1,aj do if g\[(A-1)*aj+v\]then if not min then min=v end;max=v end end;s:drawHLine(min+i-1,max+i-1,A+j-1,char,B,C)end end,drawArc=function(s,i,j,k,l,al,am,char,B,C)if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;if al>am then local t=al;al,am=am,t end;local ad,ae,af,h,aa,ag,ah=(am-al)/16,(i+k)/2,(j+l)/2,(k-i)/2,(l-j)/2,1,1;for v=1,17 do local H,I=a(ae+b(ad*v-1+al)*h+0.5),a(af-c(ad*v-1+al)*aa+0.5)if v>1 then s:drawLine(ag,ah,H,I,char,B,C)end;ag,ah=H,I end end,drawPie=function(s,i,j,k,l,al,am,char,B,C)if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;if al>am then local t=al;al,am=am,t end;local ad,ae,af,h,aa,ag,ah=(am-al)/16,(i+k)/2,(j+l)/2,(k-i)/2,(l-j)/2,1,1;for v=1,17 do local H,I=a(ae+b(ad*v-1+al)*h+0.5),a(af-c(ad*v-1+al)*aa+0.5)if v>1 then s:drawLine(ag,ah,H,I,char,B,C)end;ag,ah=H,I end;s:drawLine(a(ae+0.5),a(af+0.5),a(ae+b(al)*h+0.5),a(af-c(al)*aa+0.5),char,B,C)s:drawLine(a(ae+0.5),a(af+0.5),a(ae+b(am)*h+0.5),a(af-c(am)*aa+0.5),char,B,C)end,fillPie=function(s,i,j,k,l,al,am,char,B,C)if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;if al>am then local t=al;al,am=am,t end;local ad,ae,af,h,aa,ag,ah,aj,ak,g=(am-al)/16,(i+k)/2,(j+l)/2,(k-i)/2,(l-j)/2,1,1,k-i+1,l-j+1,{}for v=1,17 do local H,I=a(ae+b(ad*v-1+al)*h+0.5),a(af-c(ad*v-1+al)*aa+0.5)if v>1 then f(g,aj,ag-i+1,ah-j+1,H-i+1,I-j+1)end;ag,ah=H,I end;f(g,aj,a(ae+0.5)-i+1,a(af+0.5)-j+1,a(ae+b(al)*h+0.5)-i+1,a(af-c(al)*aa+0.5)-j+1)f(g,aj,a(ae+0.5)-i+1,a(af+0.5)-j+1,a(ae+b(am)*h+0.5)-i+1,a(af-c(am)*aa+0.5)-j+1)for A=1,ak do min,max=nil;for v=1,aj do if g\[(A-1)*aj+v\]then if not min then min=v end;max=v end end;if min then s:drawHLine(min+i-1,max+i-1,A+j-1,char,B,C)end end end,floodFill=function(s,H,I,char,B,C)if H<s.x1 or I<s.y1 or H>s.x2 or I>s.y2 then return end;local an,ao,ap,aq={H,I},s.buffer\[((I-1)*s.width+H)*3-2\],s.buffer\[((I-1)*s.width+H)*3-1\],s.buffer\[((I-1)*s.width+H)*3\]if ao==char and ap==B and aq==C then return end;while#an>0 do local ar,as=an\[#an-1\],an\[#an\]an\[#an\]=nil;an\[#an\]=nil;if ar>=s.x1 and as>=s.y1 and ar<=s.x2 and as<=s.y2 then local at,au,av=s.buffer\[((as-1)*s.width+ar)*3-2\],s.buffer\[((as-1)*s.width+ar)*3-1\],s.buffer\[((as-1)*s.width+ar)*3\]if ao==at and ap==au and aq==av then if char or s.overwrite then s.buffer\[((as-1)*s.width+ar)*3-2\]=char end;if B or s.overwrite then s.buffer\[((as-1)*s.width+ar)*3-1\]=B end;if C or s.overwrite then s.buffer\[((as-1)*s.width+ar)*3\]=C end;an\[#an+1\]=ar-1;an\[#an+1\]=as;an\[#an+1\]=ar+1;an\[#an+1\]=as;an\[#an+1\]=ar;an\[#an+1\]=as-1;an\[#an+1\]=ar;an\[#an+1\]=as+1 end end end end,drawSurface=function(s,H,I,u)for A=1,u.height do for v=1,u.width do s:drawPixel(v+H-1,A+I-1,u.buffer\[((A-1)*u.width+v)*3-2\],u.buffer\[((A-1)*u.width+v)*3-1\],u.buffer\[((A-1)*u.width+v)*3\])end end end,drawSurfacePart=function(s,H,I,L,M,N,O,u)if L>N then local t=L;L,N=N,t end;if M>O then local t=M;M,O=O,t end;if N<1 or L>u.width or O<1 or M>u.height then return end;if L<1 then L=1 end;if N>u.width then N=u.width end;if M<1 then M=1 end;if O>u.height then O=u.height end;for A=M,O do for v=L,N do s:drawPixel(H+v-L,I+A-M,u.buffer\[((A-1)*u.width+v)*3-2\],u.buffer\[((A-1)*u.width+v)*3-1\],u.buffer\[((A-1)*u.width+v)*3\])end end end,drawSurfaceScaled=function(s,i,j,k,l,u)local H,h,aw,I,aa,ax=0,0,false,0,0,false;if i<=k then H=i;h=k-i+1 else H=k;h=i-k+1;aw=true end;if j<=l then I=j;aa=l-j+1 else I=l;aa=j-l+1;ax=true end;local ay,az,V,aA=h/u.width,aa/u.height;for A=1,aa do for v=1,h do if aw then V=a((h-v+0.5)/ay)+1 else V=a((v-0.5)/ay)+1 end;if ax then aA=a((aa-A+0.5)/az)+1 else aA=a((A-0.5)/az)+1 end;s:drawPixel(H+v-1,I+A-1,u.buffer\[((aA-1)*u.width+V)*3-2\],u.buffer\[((aA-1)*u.width+V)*3-1\],u.buffer\[((aA-1)*u.width+V)*3\])end end end,drawSurfaceRotated=function(s,H,I,aB,aC,aD,u)local cos,sin,aE=b(aD),c(aD),a(math.sqrt(u.width*u.width+u.height*u.height))H,I=H-a(cos*aB-1+sin*aC-1+0.5),I-a(cos*aC-1-sin*aB-1+0.5)for A=-aE,aE do for v=-aE,aE do local aF,aG=a(v*cos-A*sin),a(v*sin+A*cos)if aF>=0 and aF<u.width and aG>=0 and aG<u.height then s:drawPixel(H+v,I+A,u.buffer\[(aG*u.width+aF)*3+1\],u.buffer\[(aG*u.width+aF)*3+2\],u.buffer\[(aG*u.width+aF)*3+3\])end end end end,shader=function(s,y,i,j,k,l)i,j,k,l=i or s.x1,j or s.y1,k or s.x2,l or s.y2;if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;if k<s.x1 or i>s.x2 or l<s.y1 or j>s.y2 then return end;if i<s.x1 then i=s.x1 end;if k>s.x2 then k=s.x2 end;if j<s.y1 then j=s.y1 end;if l>s.y2 then l=s.y2 end;local h,g=k-i+1,{}for A=j,l do for v=i,k do g\[((A-j)*h+v-i)*3+1\],g\[((A-j)*h+v-i)*3+2\],g\[((A-j)*h+v-i)*3+3\]=y(s.buffer\[((A-1)*s.width+v)*3-2\],s.buffer\[((A-1)*s.width+v)*3-1\],s.buffer\[((A-1)*s.width+v)*3\],v,A)end end;for A=j,l do for v=i,k do s.buffer\[((A-1)*s.width+v)*3-2\],s.buffer\[((A-1)*s.width+v)*3-1\],s.buffer\[((A-1)*s.width+v)*3\]=g\[((A-j)*h+v-i)*3+1\],g\[((A-j)*h+v-i)*3+2\],g\[((A-j)*h+v-i)*3+3\]end end end,shift=function(s,H,I,i,j,k,l)i,j,k,l=i or s.x1,j or s.y1,k or s.x2,l or s.y2;if i>k then local t=i;i,k=k,t end;if j>l then local t=j;j,l=l,t end;if k<s.x1 or i>s.x2 or l<s.y1 or j>s.y2 then return end;if i<s.x1 then i=s.x1 end;if k>s.x2 then k=s.x2 end;if j<s.y1 then j=s.y1 end;if l>s.y2 then l=s.y2 end;local h,g=k-i+1,{}for A=j,l do for v=i,k do if v-H>=1 and A-I>=1 and v-H<=s.width and A-I<=s.height then g\[((A-j)*h+v-i)*3+1\],g\[((A-j)*h+v-i)*3+2\],g\[((A-j)*h+v-i)*3+3\]=s.buffer\[((A-I-1)*s.width+v-H)*3-2\],s.buffer\[((A-I-1)*s.width+v-H)*3-1\],s.buffer\[((A-I-1)*s.width+v-H)*3\]end end end;for A=j,l do for v=i,k do s.buffer\[((A-1)*s.width+v)*3-2\],s.buffer\[((A-1)*s.width+v)*3-1\],s.buffer\[((A-1)*s.width+v)*3\]=g\[((A-j)*h+v-i)*3+1\],g\[((A-j)*h+v-i)*3+2\],g\[((A-j)*h+v-i)*3+3\]end end end}function create(h,aa,char,B,C)local s={}for aH,aI in pairs(r)do s\[aH\]=aI end;s.width,s.height,s.x1,s.y1,s.x2,s.y2,s.curX,s.curY,s.overwrite,s.buffer=h,aa,1,1,h,aa,1,1,false,{}if char then for v=1,h*aa do s.buffer\[v*3-2\]=char end end;if B then for v=1,h*aa do s.buffer\[v*3-1\]=B end end;if C then for v=1,h*aa do s.buffer\[v*3\]=C end end;return s end;function load(w)local aJ,y={},fs.open(w,\"r\")for aK in y.readLine do aJ\[#aJ+1\]=aK end;y.close()local aa=#aJ;if aJ\[1\]:byte(1)==30 then local h,v=0,1;while v<=#aJ\[1\]do local char=aJ\[1\]:byte(v)if char==30 or char==31 then v=v+1 else h=h+1 end;v=v+1 end;local s,B,C,v,V,char,z=create(h,aa)for A=1,aa do v=1;V=1;while v<=#aJ\[A\]do char=aJ\[A\]:byte(v)if char==30 then v=v+1;char=aJ\[A\]:byte(v)z=tonumber(aJ\[A\]:sub(v,v),16)if z then B=2^z else B=nil end elseif char==31 then v=v+1;char=aJ\[A\]:byte(v)z=tonumber(aJ\[A\]:sub(v,v),16)if z then C=2^z else C=nil end else s.buffer\[((A-1)*s.width+V)*3-2\]=aJ\[A\]:sub(v,v)s.buffer\[((A-1)*s.width+V)*3-1\]=B;s.buffer\[((A-1)*s.width+V)*3\]=C;V=V+1 end;v=v+1 end end;return s elseif aJ\[1\]:byte(1)==95 then return loadString(aJ\[1\])else local h=0;for v=1,#aJ do if#aJ\[v\]>h then h=#aJ\[v\]end end;local s,z=create(h,aa)for A=1,aa do for v=1,h do z=tonumber(aJ\[A\]:sub(v,v),16)if z then s.buffer\[((A-1)*s.width+v)*3-1\]=2^z end end end;return s end end;function loadString(D)local h,aa,G=tonumber(D:sub(2,5),16),tonumber(D:sub(6,9),16),10;local s=create(h,aa)for A=1,aa do for v=1,h do if D:byte(G)~=95 then s.buffer\[((A-1)*s.width+v)*3-2\]=string.char(tonumber(D:sub(G,G+1),16))end;if D:byte(G+2)~=95 then s.buffer\[((A-1)*s.width+v)*3-1\]=2^tonumber(D:sub(G+2,G+2),16)end;if D:byte(G+3)~=95 then s.buffer\[((A-1)*s.width+v)*3\]=2^tonumber(D:sub(G+3,G+3),16)end;G=G+4 end end;return s end")
  274.     loadConfig()
  275.     resize()
  276.     while running[1] do
  277.         local e, front = {os.pullEventRaw()}, getFront()
  278.         if e[1] == "timer" and e[2] == osTimer then
  279.             osTimer = os.startTimer(0)
  280.             surf:clear(nil, config.skin.bc)
  281.             surf:drawHLine(1, width, 1, nil, config.skin.taskbc)
  282.             local x = 6 - offset
  283.             for i=1,#processes do
  284.                 if i == front then
  285.                     surf:drawText(x, 1, processes[i].title, nil, config.skin.taskacttc)
  286.                 elseif processes[i].minimized then
  287.                     surf:drawText(x, 1, processes[i].title, nil, config.skin.taskmintc)
  288.                 else
  289.                     surf:drawText(x, 1, processes[i].title, nil, config.skin.tasknortc)
  290.                 end
  291.                 x = x + #processes[i].title + 2
  292.             end
  293.             surf:drawText(1, 1, "Grid", config.skin.gridbc, config.skin.gridtc)
  294.             surf:drawPixel(5, 1, "<", config.skin.taskscrbc, config.skin.taskscrtc)
  295.             surf:drawPixel(width, 1, ">", config.skin.taskscrbc, config.skin.taskscrtc)
  296.             for i=#order,1,-1 do
  297.                 local process = processes[order[i]]
  298.                 if not process.minimized then
  299.                     surf:fillRect(process.x, process.y, process.x + process.width - 1, process.y + process.height - 1, " ", colors.black, colors.white)
  300.                     surf:drawHLine(process.x, process.x + process.width - 1, process.y, nil, config.skin.wintopbc, config.skin.wintitletc)
  301.                     surf:drawVLine(process.y + 1, process.y + process.height - 1, process.x + process.width - 1, nil, config.skin.winrightbc)
  302.                     surf:drawPixel(process.x + process.width - 2, process.y, "-", config.skin.winminbc, config.skin.winmintc)
  303.                     surf:drawPixel(process.x + process.width - 1, process.y, "X", config.skin.winclosebc, config.skin.winclosetc)
  304.                     surf:drawPixel(process.x + process.width - 1, process.y + process.height - 1, "/", config.skin.winresizebc, config.skin.winresizetc)
  305.                     surf:drawText(process.x + 1, process.y, #process.title > process.width - 4 and process.title:sub(1, process.width - 6 < 0 and 0 or process.width - 6)..".." or process.title)
  306.                     surf:drawSurface(process.x, process.y + 1, process.surface)
  307.                 end
  308.             end
  309.             surf:render(parentTerm)
  310.             parentTerm.setCursorBlink(false)
  311.             if front then
  312.                 if processes[front].surface.curX >= 1 and processes[front].surface.curX < processes[front].surface.width and processes[front].surface.curY >= 1 and processes[front].surface.curY < processes[front].surface.height then
  313.                     parentTerm.setCursorPos(processes[front].surface.curX + processes[front].x - 1, processes[front].surface.curY + processes[front].y)
  314.                     parentTerm.setCursorBlink(processes[front].surface.blink or false)
  315.                 end
  316.             end
  317.         elseif e[1] == "term_resize" then
  318.             resize()
  319.         elseif e[1] == "char" or e[1] == "key" or e[1] == "key_up" or e[1] == "paste" then
  320.             if front then
  321.                 resumeProcess(front, unpack(e))
  322.             end
  323.         elseif e[1] == "terminate" then
  324.             if front then
  325.                 resumeProcess(front, "terminate")
  326.             else
  327.                 running[1] = false
  328.             end
  329.         elseif e[1] == "mouse_click" then
  330.             mode = 0
  331.             if e[4] == 1 then
  332.                 if e[3] >= 1 and e[3] <= 4 then
  333.                     local found = false
  334.                     for i=1,#processes do
  335.                         if processes[i].path == dir.."startmenu.lua" then
  336.                             found = true
  337.                             multishell.setFocus(i)
  338.                             break
  339.                         end
  340.                     end
  341.                     if not found then
  342.                         local f = fs.open(dir.."startmenu.lua", "w")
  343.                         f.write(startmenu)
  344.                         f.close()
  345.                         multishell.setFocus(multishell.launch({shell = parentShell, multishell = multishell}, dir.."startmenu.lua", surface, config, running))
  346.                         fs.delete(dir.."startmenu.lua")
  347.                     end
  348.                 elseif e[3] == 5 then
  349.                     offset = offset - math.ceil((width - 6) / 3)
  350.                     checkOffset()
  351.                 elseif e[3] == width then
  352.                     offset = offset + math.ceil((width - 6) / 3)
  353.                     checkOffset()
  354.                 else
  355.                     local x = 6 - offset
  356.                     for i=1,#processes do
  357.                         if e[3] >= x and e[3] < x + #processes[i].title then
  358.                             if i == front then
  359.                                 processes[i].minimized = true
  360.                             else
  361.                                 multishell.setFocus(i)
  362.                             end
  363.                         end
  364.                         x = x + #processes[i].title + 2
  365.                     end
  366.                 end
  367.             else
  368.                 for i=1,#order do
  369.                     if not processes[order[i]].minimized and e[3] >= processes[order[i]].x and e[4] >= processes[order[i]].y and e[3] < processes[order[i]].x + processes[order[i]].width and e[4] < processes[order[i]].y + processes[order[i]].height then
  370.                         if order[i] ~= front then
  371.                             multishell.setFocus(order[i])
  372.                         end
  373.                         front = getFront()
  374.                         break
  375.                     end
  376.                 end
  377.             end
  378.             if front then
  379.                 if e[3] >= processes[front].x and e[4] > processes[front].y and e[3] < processes[front].x + processes[front].width - 1 and e[4] < processes[front].y + processes[front].height then
  380.                     resumeProcess(front, e[1], e[2], e[3] - processes[front].x + 1, e[4] - processes[front].y)
  381.                 elseif e[3] == processes[front].x + processes[front].width - 1 and e[4] == processes[front].y then
  382.                     local process = processes[front]
  383.                     resumeProcess(front, "terminate")
  384.                     for i=1,#processes do
  385.                         if processes[i] == process then
  386.                             removeProcess(i)
  387.                             break
  388.                         end
  389.                     end
  390.                 elseif e[3] == processes[front].x + processes[front].width - 2 and e[4] == processes[front].y then
  391.                     processes[front].minimized = true
  392.                 elseif e[3] >= processes[front].x and e[3] < processes[front].x + processes[front].width - 2 and e[4] == processes[front].y then
  393.                     mode = 1
  394.                     lockX = e[3]
  395.                     lockY = e[4]
  396.                 elseif e[3] == processes[front].x + processes[front].width - 1 and e[4] == processes[front].y + processes[front].height - 1 then
  397.                     mode = 2
  398.                     lockX = e[3]
  399.                     lockY = e[4]
  400.                 end
  401.             end
  402.         elseif e[1] == "mouse_drag" then
  403.             if front then
  404.                 if mode == 0 and e[3] >= processes[front].x and e[4] > processes[front].y and e[3] < processes[front].x + processes[front].width - 1 and e[4] < processes[front].y + processes[front].height then
  405.                     resumeProcess(front, e[1], e[2], e[3] - processes[front].x + 1, e[4] - processes[front].y)
  406.                 elseif mode == 1 then
  407.                     processes[front].x = processes[front].x + e[3] - lockX
  408.                     processes[front].y = processes[front].y + e[4] - lockY
  409.                     lockX = e[3]
  410.                     lockY = e[4]
  411.                     if processes[front].y < 2 then
  412.                         processes[front].y = 2
  413.                         lockY = lockY + 1
  414.                     end
  415.                 elseif mode == 2 then
  416.                     local width = e[3] - processes[front].x + 1
  417.                     local height = e[4] - processes[front].y + 1
  418.                     resizeProcess(front, width, height)
  419.                 end
  420.             end
  421.         elseif e[1] == "mouse_up" or e[2] == "mouse_scroll" then
  422.             if front and mode == 0 then
  423.                 if e[3] >= processes[front].x and e[4] > processes[front].y and e[3] < processes[front].x + processes[front].width - 1 and e[4] < processes[front].y + processes[front].height then
  424.                     resumeProcess(front, e[1], e[2], e[3] - processes[front].x + 1, e[4] - processes[front].y)
  425.                 end
  426.             end
  427.         else
  428.             distributeEvent(unpack(e))
  429.         end
  430.     end
  431. end
  432.  
  433. local ok, err = pcall(run)
  434. saveConfig()
  435. if not ok then
  436.     term.redirect(parentTerm)
  437.     printError("GridOS has crashed!\nPlease notify CrazedProgrammer of the error.\nError message:\n"..err)
  438. end
RAW Paste Data