Advertisement
Oeed

PearOS Preview 2

Apr 3rd, 2013
6,438
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 134.31 KB | None | 0 0
  1. local pkg = {["System"]={["PearOS.lua"]="--[[!@#&!@#&                                                         #!@#&                                                      #!@#&!@#&                                                      ###!@#&                                                    #####!@#&                                                       #####!@#&                                                     #########!@#&                                                  ##########!@#&                                                  #########!@#&                                                   ##########!@#&                                                   #########!@#&!@#&                                                    PearOS!@#&                                                     Preview 2!@#&!@#&PearOS by Oliver 'oeed' Cooper.!@#&PearOS is released under Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported (CC BY-NC-ND 3.0) License!@#&!@#&In simple terms this means that...!@#&!@#&You are free to:!@#&- Share, copy, distribute and transmit the work.!@#&!@#&Under the following conditions:!@#&- Attribution - You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).!@#&- Noncommercial - You may not use this work for commercial purposes.!@#&- No Derivative Works - You may not alter, transform, or build upon this work. (With out permission from myself)!@#&!@#&With the understanding that:!@#&- Waiver - Any of the above conditions can be waived if you get permission from the copyright holder.!@#&- Public Domain - Where the work or any of its elements is in the public domain under applicable law, that status is in no way affected by the license.!@#&- Other Rights - In no way are any of the following rights affected by the license:!@#&- Your fair dealing or fair use rights, or other applicable copyright exceptions and limitations;!@#&- The author's moral rights;!@#&- Rights other persons may have either in the work itself or in how the work is used, such as publicity or privacy rights.!@#&- Notice - For any reuse or distribution, you must make clear to others the license terms of this work.!@#&!@#&See http://creativecommons.org/licenses/by-nc-nd/3.0/ for more information.!@#&!@#&!@#&The stuff that only big city lawyers can read:!@#&!@#&CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN \"AS-IS\" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.!@#&License!@#&!@#&THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE (\"CCPL\" OR \"LICENSE\"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.!@#&!@#&BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.!@#&!@#&1. Definitions!@#&!@#&\"Adaptation\" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image (\"synching\") will be considered an Adaptation for the purpose of this License.!@#&\"Collection\" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.!@#&\"Distribute\" means to make available to the public the original and copies of the Work through sale or other transfer of ownership.!@#&\"Licensor\" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.!@#&\"Original Author\" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.!@#&\"Work\" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.!@#&\"You\" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.!@#&\"Publicly Perform\" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.!@#&\"Reproduce\" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.!@#&2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.!@#&!@#&3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:!@#&!@#&to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; and,!@#&to Distribute and Publicly Perform the Work including as incorporated in Collections.!@#&The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats, but otherwise you have no rights to make Adaptations. Subject to 8(f), all rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights set forth in Section 4(d).!@#&!@#&4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:!@#&!@#&You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested.!@#&You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in connection with the exchange of copyrighted works.!@#&If You Distribute, or Publicly Perform the Work or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution (\"Attribution Parties\") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work. The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Collection, at a minimum such credit will appear, if a credit for all contributing authors of Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.!@#&For the avoidance of doubt:!@#&!@#&Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;!@#&Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License if Your exercise of such rights is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(b) and otherwise waives the right to collect royalties through any statutory or compulsory licensing scheme; and,!@#&Voluntary License Schemes. The Licensor reserves the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License that is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(b).!@#&Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation.!@#&5. Representations, Warranties and Disclaimer!@#&!@#&UNLESS OTHERWISE MUTUALLY AGREED BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.!@#&!@#&6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.!@#&!@#&7. Termination!@#&!@#&This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.!@#&Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.!@#&8. Miscellaneous!@#&!@#&Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.!@#&If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.!@#&No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.!@#&This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.!@#&The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.!@#&Creative Commons Notice!@#&!@#&Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor.!@#&!@#&Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark \"Creative Commons\" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License.!@#&!@#&]]--!@#&!@#&--Slightly Modified os.loadAPI--!@#&local tAPIsLoading = {}!@#&!@#&CopyTable = function(t)!@#&    local u = { __index = _G }!@#&  for k, v in pairs(t) do!@#&     u[k] = v!@#&    end!@#& return setmetatable(u, getmetatable(t))!@#&end!@#&!@#&function includeFile(_sPath)!@#&  local sName = fs.getName( _sPath )!@#&  if tAPIsLoading[sName] == true then!@#&     printError( \"API \"..sName..\" is already being loaded\" )!@#&     return false!@#&    end!@#& tAPIsLoading[sName] = true!@#&!@#&  local tEnv = getfenv()!@#&!@#&!@#&  setmetatable( tEnv, { __index = _G } )!@#&  tEnv['OSSettings'] = OSSettings!@#& local fnAPI, err = loadfile( _sPath )!@#&   if fnAPI then!@#&       setfenv( fnAPI, tEnv )!@#&      fnAPI()!@#& else!@#&        printError( err )!@#&        tAPIsLoading[sName] = nil!@#&      return false!@#&    end!@#& !@#&    local oldv = nil!@#&!@#&    local tAPI = {}!@#& for k,v in pairs( tEnv ) do!@#&     tAPI[k] =  v!@#&        oldv = k!@#&    end!@#& _G[sName] = tAPI!@#&    tAPIsLoading[sName] = nil!@#&   if verbose then!@#&     sleep(0)!@#&    end!@#& return true!@#&end!@#&!@#&function include(_sDir)!@#&   if fs.isDir(_sDir) then!@#&     for _, file in pairs(fs.list(_sDir)) do!@#&         if string.sub(file,1,1) ~= \".\" then!@#&               if fs.isDir(_sDir..\"/\"..file) then!@#&                    include(_sDir..\"/\"..file)!@#&             else!@#&                    includeFile(_sDir..\"/\"..file)!@#&                 if verbose then!@#&                     print(\"Included \"..file)!@#&                  end!@#&             end!@#&         end!@#&     end!@#& else!@#&        error(\"Attempt to dir-include a non-directory\")!@#&   end!@#&end!@#&!@#&OSVersion = 0.2!@#&OSVersionLong = \"Preview 2\"!@#&!@#&OSCurrentWindow = nil --the window in focus!@#&OSSelectedEntity = nil!@#&OSUpdateTimer = nil!@#&OSWindowDragTimer = nil!@#&OSWindowResizeTimer = nil!@#&OSCommandKeyTimer = nil!@#&OSSleepTimer = nil!@#&!@#&OSFirstRunMode = false!@#&--default settings!@#&OSSettings = {!@#&   boot_arg = \"\", !@#&   desktop_bg = colours.grey,!@#&  machine_name = \"\",!@#&    user_name = \"\",!@#&   update_frequency = 1,!@#&   extension_associations = {},!@#&    sleep_delay = 0!@#&}    !@#&!@#&OSReloadSettings = function()!@#&   OSSaveSettings()!@#&    desktop.BackgroundColour = OSSettings['desktop_bg']!@#& desktop:Draw()!@#&  OSSettings = OSTableIO.load(\"Settings\")!@#&   --load the extension associations!@#&   --OSExtensionAssociations.list = OSSettings!@#&end!@#&!@#&OSChangeSetting = function(_key, _value, _reload)!@#& OSSettings[_key] = _value!@#&   if _reload then!@#&     OSReloadSettings()!@#&  end!@#&end!@#&!@#&OSSaveSettings = function()!@#&   OSSettings['extension_associations'] = OSExtensionAssociations.list!@#& OSTableIO.save(OSSettings,\"Settings\")!@#&end!@#&!@#&OSLog = function(message)!@#& term.setBackgroundColour(colours.white)!@#& term.setTextColour(colours.black)!@#&   print(message)!@#&end!@#&!@#&OSUpdate = function()!@#&  if OSServices.shouldHideAllMenus then!@#&       OSServices.hideAllMenus()!@#&       OSServices.shouldHideAllMenus = false!@#&   end!@#& --!@#&  --sleep(0.1)!@#&    OSDrawing.Draw()!@#&    OSUpdateTimer = os.startTimer(OSServices.updateFrequency) !@#&end!@#&!@#&OSExtensionAssociations = {!@#&--essentially, what this does is sets what application should open certain file types--!@#&!@#& list = {!@#&        txt = \"System/Applications/TextEdit.app\"!@#&  },!@#&!@#&  register = function(extention, applicationPath) --return false if the register fails!@#&        --TODO: prompt the user on what application they want for an extension!@#&      if not OSExtensionAssociations.list[extension] then --prevent the extension from being overwritten!@#&          OSExtensionAssociations.list[extention] = applicationPath!@#&           return true!@#&     else!@#&            return false!@#&        end!@#& end!@#&}!@#&!@#&function OSHandleClick (x, y)!@#&   OSSelectedEntity = nil!@#&  for _,entity in pairs(OSInterfaceEntities.list) do!@#&  !@#&        --check if the click overlaps an entities!@#&       if OSServices.pointOverlapsRect({x = x, y = y}, entity)  then!@#&           if OSServices.clickEntity(entity, x, y) then!@#&            return!@#&          end!@#&     end!@#& end!@#&!@#&         --check windows!@#&         --first click on the current window!@#& for _,key in ipairs(OSInterfaceApplications.order) do!@#&       local application = OSInterfaceApplications.list[key]!@#&       for _,window in pairs(application.windows) do!@#&!@#&           --check if the click overlaps an entities!@#&           if window.isMinimised then!@#&              break!@#&           end!@#&         !@#&            if OSServices.pointOverlapsRect({x = x, y = y}, window)   then!@#&              !@#&                local relativeX = x - window.x + 1!@#&              local relativeY = y - window.y!@#&              OSCurrentWindow = window!@#&                OSInterfaceApplications.switchTo(application)!@#&               window:action(relativeX, relativeY)!@#&             return!@#&          end!@#&     end!@#& end!@#&end!@#&!@#&function OSHandleCharacter (char) !@#&    if OSSelectedEntity then!@#&    OSSelectedEntity:insertCharacter(char)!@#&  end!@#&end!@#&!@#&function OSHandleKeystroke (keystroke) !@#&   local name = keys.getName(keystroke)!@#&    if name == \"left\" then!@#&        if OSSelectedEntity then!@#&        OSSelectedEntity:moveCursor(-1)!@#&     end!@#& elseif name == \"right\" then!@#&       if OSSelectedEntity then!@#&        OSSelectedEntity:moveCursor(1)!@#&      end!@#& elseif name == \"backspace\" then!@#&       if OSSelectedEntity then!@#&        OSSelectedEntity:removeCharacter (-1)!@#&       end!@#& elseif name == \"delete\" then!@#&      if OSSelectedEntity then!@#&        OSSelectedEntity:removeCharacter (0)!@#&        end!@#& elseif name == \"enter\" then!@#&       if OSSelectedEntity then!@#&        OSSelectedEntity:submit()!@#&       end!@#& elseif keystroke == 219 or keystroke == 220 or name == \"leftCtrl\" or name == \"rightCtrl\" then!@#&       OSCommandKeyTimer = os.startTimer(OSServices.commandTimeout) !@#&   elseif #name == 1 then -- a character!@#&       if OSCommandKeyTimer then!@#&       --if the user pressed the command key (presumably its still down)!@#&       OSHandleKeyCommand(name:upper())!@#&        end!@#& else!@#&    --      print(name)!@#& end!@#&end!@#&!@#&function OSHandleKeyCommand (key)!@#& local application = OSInterfaceApplications.current() --the current application!@#& if key == \"R\" and false then --this is disabled, enable it if you wish!@#&        os.reboot()!@#& else!@#&        if OSKeyboardShortcuts.list[key] then!@#&           local action = OSKeyboardShortcuts.list[key]!@#&            action()!@#&        end!@#& end!@#& OSUpdate()!@#&end!@#&!@#&function OSHandleScroll (x, y, direction)!@#&  --only windows are checked, only windows should have a scrolling view!@#&   for _,application in pairs(OSInterfaceApplications.list) do!@#&     for _,window in pairs(application.windows) do!@#&           --check if the click overlaps an entities!@#&           if OSServices.pointOverlapsRect({x = x, y = y}, window)   then!@#&!@#&              --give the window focus!@#&             OSCurrentWindow = window!@#&                --get the click position relative to the window!@#&             local relativeX = x - window.x + 1!@#&              local relativeY = y - window.y!@#&!@#&              --if the y of the click was 0 (the window frame) do special actions!@#&             if relativeY == 0 then!@#&!@#&                  if relativeX == 1 then --close button!@#&                   window:close()!@#&                  return!@#&                  elseif relativeX == 2 and window.canMinimise then --minimise button!@#&!@#&                 elseif relativeX == 3 and window.canMaximise then --maximise button!@#&!@#&                 else --main bar!@#&                 window.dragX = relativeX  + 1!@#&                   OSWindowDragTimer = os.startTimer(OSServices.dragTimeout)!@#&                   end!@#&             else -- it was in the window content!@#&                    for _,entity in pairs(window.entities) do!@#&!@#&                       --check if the click overlaps an entities!@#&                       if entity.canScroll == true and OSServices.pointOverlapsRect({x = relativeX - 1, y = relativeY - 1}, entity)  then!@#&!@#&                          local newScroll = entity.scrollY - direction!@#&                            if newScroll >= entity.maxScrollY and newScroll <= 0  then!@#&                              entity.scrollY = newScroll!@#&                              OSUpdate()!@#&                          end!@#&!@#&                     end!@#&                 end!@#&             end!@#&!@#&         end!@#&     end!@#& end!@#&end!@#&!@#&function OSHandleDrag (x,y)!@#&   --check the window should be draged!@#& if OSWindowDragTimer and not OSFirstRunMode then!@#&        OSCurrentWindow.x = x - OSCurrentWindow.dragX!@#&       if y == 1 then!@#&          y = 2!@#&       end!@#&     OSCurrentWindow.y = y  !@#&     --update the time out!@#&       OSWindowDragTimer = os.startTimer(OSServices.dragTimeout)!@#&       --redraw the screen!@#&     OSUpdate()!@#&  elseif OSWindowResizeTimer then!@#&     --resize the window!@#&     OSCurrentWindow:resize(x - OSCurrentWindow.x + 1, y - OSCurrentWindow.y + 1)!@#&        --update the time out!@#&       OSWindowResizeTimer = os.startTimer(OSServices.dragTimeout)!@#& end!@#& if OSSelectedEntity then!@#&        if OSServices.pointOverlapsRect({x = x, y = y}, OSSelectedEntity)  then!@#&         local endPos = x + (y * OSSelectedEntity.width)!@#&         OSSelectedEntity.Selection[2] = endPos!@#&      end!@#& end!@#&end!@#&!@#&function EventHandler ()!@#&  OSUpdateTimer = os.startTimer(OSServices.updateFrequency)!@#&   OSServices.resetSleepTimer()!@#&    while true do!@#&       local event, arg, x, y = os.pullEventRaw()!@#&!@#&      if event == \"timer\" then!@#&      if arg == OSUpdateTimer then!@#&            OSUpdate()!@#&          if clock then!@#&               clock:Draw()!@#&            end!@#&         --[[!@#&            It would be very easy to turn off constant refreshing. It would work, a few problems with the button selection colour prevent me from doing so.!@#&         To switch, comment out OSUpdate!@#&         ]]!@#&          OSUpdateTimer = os.startTimer(OSServices.updateFrequency)!@#&           elseif arg == OSWindowDragTimer then!@#&            OSWindowDragTimer = nil!@#&         elseif arg == OSCommandKeyTimer then!@#&            OSCommandKeyTimer = nil!@#&         elseif arg == OSWindowResizeTimer then!@#&          OSWindowResizeTimer = nil!@#&           elseif arg == OSSleepTimer then!@#&         --OSServices.sleep()!@#&        end!@#&     elseif event == \"char\" then!@#&           OSServices.resetSleepTimer()!@#&            OSHandleCharacter(arg)!@#&      elseif event == \"key\" then!@#&            OSServices.resetSleepTimer()!@#&            OSHandleKeystroke(arg)!@#&      elseif event == \"mouse_click\"  then!@#&           OSServices.resetSleepTimer()!@#&            if arg == 1 then --left click!@#&               OSHandleClick(x, y)!@#&         else --right click!@#&          --os.reboot()!@#&           end!@#&     elseif event == \"monitor_touch\" then!@#&          OSServices.resetSleepTimer()!@#&            OSHandleClick(x, y)!@#&     elseif event == \"mouse_drag\" then!@#&         OSServices.resetSleepTimer()!@#&            OSHandleDrag(x, y)!@#&      elseif event == \"mouse_scroll\" then!@#&           OSServices.resetSleepTimer()!@#&            OSHandleScroll(x, y, arg)!@#&       else!@#&        --              print(event)!@#&        --              print(arg)!@#&      end!@#& end!@#&end!@#&!@#&function initMenuBar()!@#&    local menuItems = {!@#&     OSMenuItem:new(\"About this Pear\", function() Finder.environment:aboutSystem() end),!@#&       OSMenuItem:new(\"Software Update\", nil), --TODO: add software update!@#&       OSMenuItem:new(\"App Store\", nil), --TODO: add app store!@#&       OSMenuSplitter:new(),!@#&       OSMenuItem:new(\"System Preferences\", function() !@#&                                              local systemPreferences = OSApplication:load(\"System/Applications/System Preferences.app\")!@#&                                                OSApplication.run(systemPreferences)!@#&                                            end),!@#&       OSMenuSplitter:new(),!@#&       OSMenuItem:new(\"Switch Screen\", function() OSServices.switchScreen() end),!@#&        OSMenuItem:new(\"Enter CraftOS\", function() OSServices.craftos() end),!@#&     OSMenuItem:new(\"Sleep\", function() OSServices.sleep() end),!@#&       OSMenuItem:new(\"Restart\", function() OSServices.restart() end),!@#&       OSMenuItem:new(\"Shut Down\", function() OSServices.shutdown() end)!@#& }!@#&   local menu = OSMenu:new(1, 1, \"P\", menuItems)!@#&!@#& clock = OSClockButton:new(20,1,\"--:--:--\")!@#&!@#&    desktop = OSDesktop:new()!@#&   OSInterfaceEntities.add(OSMenuBar:new())!@#&    OSInterfaceEntities.add(clock)!@#&  OSInterfaceEntities.add(menu)!@#&end!@#&!@#&function initDock()!@#& local dockItems = {}!@#&    local applicationsPath = \"System/Applications/\"!@#&   for _,name in ipairs(OSFileSystem.list(applicationsPath)) do!@#&        if OSFileSystem.extension(name) == \"app\" then!@#&         table.insert(dockItems, OSDockItem:new(applicationsPath..name))!@#&     end!@#& end!@#& Dock = OSDock:new(dockItems)!@#&    OSInterfaceEntities.add(Dock)!@#&end!@#&!@#&function startFinder()!@#&  Finder = OSApplication:load(\"System/Applications/Finder.app\")!@#& OSApplication.run(Finder)!@#&end!@#&!@#&function init()!@#& term.setTextColour(colours.black)!@#&   sleep(1)!@#&!@#&    --add Macintosh command keys because computercraft doesn't have them in the keys api *cough* cloudy & dan200, add them *cough*!@#&  keys[219] = \"leftCommand\"!@#& keys[220] = \"rightCommand\"!@#&    --this isn't working, it is implimented manually when needed!@#&!@#&    if fs.exists(\"Settings\") then!@#&     OSSettings = OSTableIO.load(\"Settings\")!@#&       os.setComputerLabel(OSSettings['machine_name'])!@#&!@#&     include(\"System/Library/Frameworks\")!@#&      initMenuBar()!@#&       initDock()!@#&      startFinder()!@#&       clock:Draw()!@#&    else!@#&        firstRun()!@#&  end!@#&!@#& OSUpdate()!@#&  EventHandler()!@#&end!@#&!@#&function firstRun()!@#&    include(\"System/Library/Frameworks\")!@#&  OSFirstRunMode = true!@#&   desktop = OSDesktop:new()!@#&   FirstRun = OSApplication:load(\"System/Library/FirstRun.app\")!@#&  OSApplication.run(FirstRun)!@#&end",["Library"]={["Interface"]={["icon_l"]="  8!@#&!@#& 88                       !@#&8888!@#&8888",["PearLogo"]="    8!@#&   8                           !@#&!@#&  888                          !@#& 88888                         !@#&8888888!@#&8888888!@#& 88888",["minimise"]="e88                                              !@#&000                                              !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 ",},["OSDrawingOld"]="--OSDrawing--!@#&!@#&!@#&    MainLoop = {!@#&!@#&    DrawEntity = function(entity)!@#&       entity:Draw()!@#&       OSDrawing.releaseOffset() --just incase there is an offset!@#&!@#&  end,!@#&!@#&    DrawApplicationWindows = function(application)!@#&      local containsCurrent = false!@#&       for _,window in pairs(application.windows) do!@#&           if window == OSCurrentWindow then!@#&               containsCurrent = true!@#&          else!@#&                window:Draw()!@#&               OSDrawing.releaseOffset() --just incase there is an offset!@#&          end!@#&     end!@#&!@#&     if containsCurrent then!@#&         OSCurrentWindow:Draw()!@#&      end!@#& end,!@#&!@#&!@#&    Draw = function (self)!@#&      --draw the desktop!@#&      desktop:Draw()!@#&!@#&      --draw all windows!@#&!@#&      --TODO: figure out how to correctly order the windows!@#&       --[[!@#&        for _,application in pairs(OSInterfaceApplications.list) do!@#&     OSDrawing.MainLoop.DrawApplicationWindows(application)!@#&      end!@#&     ]]--!@#&!@#&        local currentApplication = OSInterfaceApplications.current()!@#&        for _,key in ipairs(OSInterfaceApplications.order) do!@#&           local application = OSInterfaceApplications.list[key]!@#&           --don't render the current applications windows, we do that later!@#&           if application.id ~= currentApplication.id then!@#&             OSDrawing.MainLoop.DrawApplicationWindows(application)!@#&          end!@#&     end!@#&!@#&     -- draw the current application!@#&     OSDrawing.MainLoop.DrawApplicationWindows(currentApplication)!@#&!@#&       --draw other entities!@#&!@#&       OSDrawing.releaseOffset() --just incase there is an offset (which shouldn't be there!!)!@#&!@#&     for _,entity in ipairs(OSInterfaceEntities.list) do!@#&         OSDrawing.MainLoop.DrawEntity(entity)!@#&           if OSServices.shouldBreakDrawLoop then!@#&              break!@#&           end!@#&     end!@#&     OSDrawing.releaseOffset() --just incase there is an offset (which shouldn't be there!!)!@#& end!@#& }!@#&!@#&   Offset = {!@#&  x = 0,!@#&  y = 0!@#&   }!@#&!@#&   addOffset = function (_x, _y)!@#&       OSDrawing.Offset.x = OSDrawing.Offset.x + _x - 1 --1 is subtracted as we want the units to be from 1, not 0!@#&     OSDrawing.Offset.y = OSDrawing.Offset.y + _y - 1!@#&    end!@#&!@#& setOffset = function (_x, _y)!@#&       OSDrawing.Offset.x = _x - 1!@#&     OSDrawing.Offset.y = _y - 1!@#& end!@#&!@#& releaseOffset = function ()!@#&     OSDrawing.Offset.x = 0!@#&      OSDrawing.Offset.y = 0!@#&  end,!@#&!@#&    DrawCharacters = function (x, y, characters, textColour,bgColour)!@#&       term.setTextColour(textColour)!@#&      term.setBackgroundColour(bgColour)!@#&      term.setCursorPos(x + OSDrawing.Offset.x, y + OSDrawing.Offset.y)!@#&       term.write(characters)!@#&  end!@#&!@#& DrawBlankArea = function (x, y, w, h, color)!@#&        OSDrawing.DrawArea (x, y, w, h, \" \", color, 1)!@#&    end!@#&!@#& DrawArea = function (x, y, w, h, character, bgColour, textColour)!@#&       --with must be greater than 1, other wise we get a stack overflow!@#&!@#&       if w < 0 then!@#&           w = w * -1!@#&      elseif w == 0 then!@#&          w = 1!@#&       end!@#&!@#&!@#&     term.setBackgroundColour(bgColour)!@#&      term.setTextColour(textColour)!@#&      for ix = 1, w do!@#&            local currX = x + ix!@#&            for iy = 1, h do!@#&                local currY = y + iy !@#&               term.setCursorPos(currX + OSDrawing.Offset.x - 1, currY + OSDrawing.Offset.y - 1)!@#&               term.write(character)!@#&           end!@#&     end!@#& end,!@#&!@#&    DrawShadow = function (x, y, w, h) --the x, y etc are of the entity that shadow is being made from!@#&      --draw the vertical shadow!@#&      term.setBackgroundColour(colours.black)!@#&     for iy = 1, h do!@#&            term.setCursorPos(x + w + OSDrawing.Offset.x,  iy + y + OSDrawing.Offset.y)!@#&         term.write(\" \")       !@#&        end!@#&     for ix = 1, w - 1 do!@#&            term.setCursorPos(ix + x + OSDrawing.Offset.x,  y + h + OSDrawing.Offset.y)!@#&         term.write(\" \")       !@#&        end!@#& end!@#&!@#& DrawImage = function(x,y,image)!@#&     paintutils.drawImage(image, x + OSDrawing.Offset.x, y + OSDrawing.Offset.y)!@#& end!@#&",["Frameworks"]={["Interface"]={["OSControl"]="--OSControl--!@#&!@#&    __index = OSEntity!@#&!@#&  action = nil!@#&!@#&    enabled = true!@#&!@#&  isSelected = false!@#&!@#&  canScroll = false!@#&!@#&   tag = 0",["OSMenuBar"]="--OSMenuBar--!@#& !@#&  x = 1!@#&   y = 1!@#&   width = 1!@#&   height = 1!@#&  action = nil!@#&!@#&    type = \"OSMenuBar\"!@#&    BackgroundColour = colours.white!@#&    TextColour = colours.black!@#&  SelectedBackgroundColour = colours.lightBlue!@#&    SelectedTextColour = colours.white!@#&  !@#&    new = function(self)!@#&        local w, h = term.getSize()!@#&     self.width = w!@#&      return self!@#& end!@#& !@#&    Draw = function (self)!@#&      OSDrawing.DrawBlankArea(self.x, self.y, self.width, self.height, self.BackgroundColour)!@#& end",["OSEntity"]="--OSEntity--!@#&!@#& __index = OSObject!@#&!@#&  x = 0!@#&   y = 0!@#&   width = 0!@#&   height = 0!@#&  title = \"\"!@#&    tag = 0!@#&!@#& remove = function(self)!@#&     OSInterfaceEntities.remove(self)!@#&    end!@#&!@#& cleanup = function(self)!@#&!@#&    end",["OSDrawing"]="--OSDrawing--!@#&!@#&   local _w, _h = term.getSize()!@#&   !@#&    Screen = {!@#&      Width = _w,!@#&     Height = _h!@#& }!@#&!@#&   DrawEntity = function(entity)!@#&       entity:Draw()!@#&       OSDrawing.releaseOffset() --just incase there is an offset!@#&  end!@#&!@#& DrawApplicationWindows = function(application)!@#&      local containsCurrent = false!@#&       for _,window in pairs(application.windows) do!@#&           if window == OSCurrentWindow then!@#&               containsCurrent = true!@#&          else!@#&                window:Draw()!@#&               OSDrawing.releaseOffset() --just incase there is an offset!@#&          end!@#&     end!@#&!@#&     if containsCurrent then!@#&         OSCurrentWindow:Draw()!@#&      end!@#& end!@#&!@#& Draw = function ()!@#&      --draw the desktop!@#&      desktop:Draw()!@#&!@#&      --draw all windows!@#&!@#&      --TODO: figure out how to correctly order the windows!@#&       --[[!@#&        for _,application in pairs(OSInterfaceApplications.list) do!@#&     OSDrawing.MainLoop.DrawApplicationWindows(application)!@#&      end!@#&     ]]--!@#&!@#&        local currentApplication = OSInterfaceApplications.current()!@#&        for _,key in ipairs(OSInterfaceApplications.order) do!@#&           local application = OSInterfaceApplications.list[key]!@#&           --don't render the current applications windows, we do that later!@#&           if application.id ~= currentApplication.id then!@#&             OSDrawing.DrawApplicationWindows(application)!@#&           end!@#&     end!@#&!@#&     -- draw the current application!@#&     OSDrawing.DrawApplicationWindows(currentApplication)!@#&!@#&        --draw other entities!@#&!@#&       OSDrawing.releaseOffset() --just incase there is an offset (which shouldn't be there!!)!@#&!@#&     for _,entity in ipairs(OSInterfaceEntities.list) do!@#&         OSDrawing.DrawEntity(entity)!@#&            if OSServices.shouldBreakDrawLoop then!@#&              break!@#&           end!@#&     end!@#&     OSDrawing.releaseOffset() --just incase there is an offset (which shouldn't be there!!)!@#&     OSDrawing.DrawBuffer()!@#&  end!@#&!@#& Offset = {!@#&  x = 0,!@#&  y = 0!@#&   }!@#&!@#&   addOffset = function (_x, _y)!@#&       OSDrawing.Offset.x = OSDrawing.Offset.x + _x - 1 --1 is subtracted as we want the units to be from 1, not 0!@#&     OSDrawing.Offset.y = OSDrawing.Offset.y + _y - 1!@#&    end!@#&!@#& setOffset = function (_x, _y)!@#&       OSDrawing.Offset.x = _x - 1!@#&     OSDrawing.Offset.y = _y - 1!@#& end!@#&!@#& releaseOffset = function ()!@#&     OSDrawing.Offset.x = 0!@#&      OSDrawing.Offset.y = 0!@#&  end!@#&!@#& DrawCharacters = function (x, y, characters, textColour,bgColour)!@#&       OSDrawing.WriteStringToBuffer(x, y, characters, textColour, bgColour)!@#&   end!@#& !@#&    DrawBlankArea = function (x, y, w, h, colour)!@#&       OSDrawing.DrawArea (x, y, w, h, \" \", colour, 1)!@#&   end!@#&!@#& DrawArea = function (x, y, w, h, character, bgColour, textColour)!@#&       --width must be greater than 1, other wise we get a stack overflow!@#&      if w < 0 then!@#&           w = w * -1!@#&      elseif w == 0 then!@#&          w = 1!@#&       end!@#&!@#&     for ix = 1, w do!@#&            local currX = x + ix - 1!@#&            for iy = 1, h do!@#&                local currY = y + iy - 1!@#&                OSDrawing.WriteToBuffer(currX, currY, character, textColour, bgColour)!@#&          end!@#&     end!@#& end!@#&!@#&!@#& DrawShadow = function (x, y, w, h) --the x, y etc are of the entity that shadow is being made from!@#&      --draw the vertical shadow!@#&!@#&      for iy = 1, h do!@#&            OSDrawing.WriteStringToBuffer(x + w, iy + y, \" \", colours.black, colours.black)!@#&       end!@#&     for ix = 1, w - 1 do!@#&            OSDrawing.WriteStringToBuffer(ix + x, y + h, \" \", colours.black, colours.black)!@#&       end!@#& end!@#&!@#& DrawImage = function(xPos,yPos,tImage)!@#&      for y=1,#tImage do!@#&          local tLine = tImage[y]!@#&         for x=1,#tLine do!@#&               if tLine[x] > 0 then!@#&                    OSDrawing.WriteToBuffer(x + xPos - 1, y + yPos - 1, \" \", colours.black,tLine[x])!@#&              end!@#&         end!@#&     end!@#& end!@#&!@#&!@#& DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour)!@#&        w = w or OSDrawing.Screen.Width!@#&     h = h or OSDrawing.Screen.Height!@#&        x = x or math.floor((w - #characters) / 2)!@#&      y = y or math.floor(h / 2)!@#&!@#&      OSDrawing.DrawCharacters(x, y, characters, textColour, bgColour)!@#&    end!@#&!@#& Clear = function (_colour)!@#&      _colour = _colour or colours.black!@#&      OSDrawing.ClearBuffer()!@#&     OSDrawing.DrawBlankArea(1, 1, OSDrawing.Screen.Width, OSDrawing.Screen.Height, _colour)!@#& end!@#&!@#& Buffer = {}!@#& BackBuffer = {}!@#&!@#& DrawBuffer = function()!@#&     for y,row in pairs(OSDrawing.Buffer) do!@#&         for x,pixel in pairs(row) do!@#&                local shouldDraw = true!@#&             local hasBackBuffer = true!@#&!@#&              if OSDrawing.BackBuffer[y] == nil or OSDrawing.BackBuffer[y][x] == nil or #OSDrawing.BackBuffer[y][x] ~= 3 then!@#&                 hasBackBuffer = false!@#&               end!@#&             if hasBackBuffer and OSDrawing.BackBuffer[y][x][1] == OSDrawing.Buffer[y][x][1] and OSDrawing.BackBuffer[y][x][2] == OSDrawing.Buffer[y][x][2] and OSDrawing.BackBuffer[y][x][3] == OSDrawing.Buffer[y][x][3] then!@#&                  shouldDraw = false!@#&              end!@#&             --shouldDraw = true!@#&             if shouldDraw then!@#&                  term.setBackgroundColour(pixel[3])!@#&                  term.setTextColour(pixel[2])!@#&                    term.setCursorPos(x, y)!@#&                 term.write(pixel[1])!@#&                end!@#&         end!@#&     end!@#&     --OSDrawing.BackBuffer = OSDrawing.Buffer!@#&       OSDrawing.Buffer = {}!@#&       term.setCursorPos(1,10)!@#& end!@#&!@#& ClearBuffer = function()!@#&        OSDrawing.Buffer = {}!@#&   end!@#&!@#& WriteStringToBuffer = function (x, y, characters, textColour,bgColour)!@#&      for i = 1, #characters do!@#&               local character = characters:sub(i,i)!@#&               OSDrawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour)!@#&      end!@#& end!@#&!@#& WriteToBuffer = function(x, y, character, textColour,bgColour)!@#&      y = y + OSDrawing.Offset.y!@#&      x = x + OSDrawing.Offset.x!@#&      OSDrawing.Buffer[y] = OSDrawing.Buffer[y] or {}!@#&     OSDrawing.Buffer[y][x] = {character, textColour, bgColour}!@#&  end",["OSHSplitter"]="--OSHSplitter--!@#&!@#&   __index = OSControl!@#& type = \"OSHSplitter\"!@#&!@#&  character = \"-\"   !@#&    TextColour = colours.grey!@#&   BackgroundColour = colours.white!@#&!@#&    new = function(self, _x, _y, _length)!@#&       local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSHSplitter} )!@#&        new.width = _length!@#&     new.height = 1!@#&      new.x = _x!@#&      new.y = _y!@#&      new.enabled = true!@#&      return new!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.DrawArea(self.x, self.y, self.width, self.height, self.character, self.BackgroundColour, self.TextColour)!@#& end",["OSObject"]="--OSObject--!@#& type = \"OSObject\"!@#& subtype = \"\"!@#&  id = 0",["OSListView"]="--OSListView--!@#&!@#&  __index = OSControl!@#&!@#& type = \"OSListView\"!@#&   items = {}!@#&  scrollY = 0!@#& maxScrollY = 0!@#&  canScroll = true!@#&!@#&    SpliterColour = colours.grey!@#&    SpliterBackgroundColour = colours.white!@#&!@#& new = function(self, _x, _y, _width, _height, _items)!@#&       local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSListView} )!@#&     new.x = _x!@#&      new.y = _y!@#&      new.width = _width!@#&      new.height = _height!@#&        for _,item in pairs(_items) do!@#&          item.width = _width!@#&     end!@#&     new.items = _items!@#&      new.maxScrollY = new.height - #new.items!@#&        return new!@#&  end!@#&!@#& Draw = function(self)!@#&!@#&       for i = 1, #self.items do!@#&           local listItem = self.items[i]!@#&          listItem.x = self.x!@#&         listItem.y = self.y + i + self.scrollY - 1!@#&          listItem.width = self.width!@#&         --calculate whether or not the item should be drawn!@#&         --print(self.y)!@#&!@#&         if  listItem.y >= self.y and listItem.y < self.height + 3 then!@#&              listItem:Draw()!@#&         end!@#&     end!@#& end!@#&!@#& action = function(self, x, y)!@#&       --check that the item won't be out of bounds!@#&        if y - self.scrollY + 1 <= #self.items then!@#&         local item = self.items[y - self.scrollY + 1]!@#&           item.isSelected = true!@#&          OSUpdate()!@#&          sleep(0.2)!@#&          if item.action then!@#&             item:action()!@#&           end!@#&     end!@#& end",["OSDesktop"]="--OSDesktop--!@#&!@#&   __index = OSEntity!@#&!@#&  type = \"OSDesktop\"!@#&    BackgroundColour = OSSettings['desktop_bg']!@#&!@#& x = 1!@#&   y = 1!@#&   width = 51!@#&  height = 19!@#&!@#& Draw = function (self)!@#&      OSDrawing.DrawBlankArea(1, 1, OSDrawing.Screen.Width, OSDrawing.Screen.Height, self.BackgroundColour)--OSSettings['desktop_bg'])!@#&    end!@#& !@#&    new = function(self)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSDesktop} ) -- copy an instance of OSMenuItem!@#&        return new!@#&  end!@#&!@#& action = function()!@#&     OSServices.hideAllMenus()!@#&   end",["OSCheckBox"]="--OSCheckBox--!@#&!@#& __index = OSControl!@#&!@#& type = \"OSCheckBox\"!@#&   TextColour = colours.black!@#&  DisabledTextColour = colours.lightGrey!@#&  OnDisabledBackgroundColour = colours.grey!@#&   OffDisabledBackgroundColour = colours.lightGrey!@#& BackgroundColour = colours.white!@#&    OnBackgroundColour = colours.lime!@#&   OffBackgroundColour = colours.red!@#&   OnTextColour = colours.white!@#&!@#&    valueChangedAction = nil!@#&    state = false!@#&   new = function(self, _x, _y, _title, _state, _valueChangedAction)!@#&       local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSCheckBox} ) -- copy an instance of OSMenuItem!@#&!@#&       new.width = string.len(_title)+2!@#&        new.height = 1!@#&      new.x = _x!@#&      new.y = _y!@#&      new.title = _title!@#&      new.state = _state!@#&      new.valueChangedAction = _valueChangedAction!@#&        new.action = _action!@#&        new.enabled = true!@#&!@#&      return new!@#&  end!@#&!@#&!@#& action = function(self)!@#&     self.state = not self.state!@#& end!@#&!@#& Draw = function(self)!@#&       local bgColour = colors.black!@#&       local textColour = colours.black!@#&        local check = \"x\"!@#&     if self.state then!@#&          if self.enabled then!@#&                bgColour = self.OnBackgroundColour!@#&              textColour = self.OnTextColour!@#&          else!@#&                bgColour = self.OnDisabledBackgroundColour!@#&              textColour = self.DisabledTextColour!@#&            end!@#&     else!@#&            if self.enabled then!@#&                bgColour = self.OffBackgroundColour!@#&         else!@#&                bgColour = self.OffDisabledBackgroundColour!@#&             textColour = self.DisabledTextColour!@#&            end!@#&         check = \" \"!@#&       end!@#&!@#&     OSDrawing.DrawCharacters(self.x,self.y, check, textColour, bgColour)!@#&        OSDrawing.DrawCharacters(self.x+2,self.y, self.title, self.TextColour, self.BackgroundColour)!@#&   end",["OSVSplitter"]="--OSVSplitter--!@#&!@#&   __index = OSHSplitter!@#&   type = \"OSVSplitter\"!@#&!@#&  character = \"|\"!@#&   TextColour = colours.grey!@#&   BackgroundColour = colours.white!@#&!@#&    new = function(self, _x, _y, _length)!@#&       local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSVSplitter} )!@#&        new.width = 1!@#&       new.height = _length!@#&        new.x = _x!@#&      new.y = _y!@#&      new.enabled = true!@#&      return new!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.DrawArea(self.x, self.y, self.width, self.height, self.character, self.BackgroundColour, self.TextColour)!@#& end",["OSDockItem"]="--OSDockItem--!@#&!@#& __index = OSMenuItem -- parent class!@#&!@#&    type = \"OSDockItem\"!@#&   width = 3!@#&   height = 2!@#&  x = 0!@#&   y = 0!@#&   icon = nil!@#&  path = nil!@#&  applicationName = nil!@#&   IndicatorColour = colours.white!@#& Indicator = \"*\"!@#&!@#&   new = function(self, _path)!@#&     local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSDockItem} ) -- copy an instance of OSMenuItem!@#&       new.icon = paintutils.loadImage(_path..\"/Icon\")!@#&       new.path = _path!@#&        new.applicationName = OSFileSystem.shortName(_path)!@#&     return new!@#&  end!@#&!@#& newMinimise = function(self, _window)!@#&       local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSDockItem} ) -- copy an instance of OSMenuItem!@#&       new.icon = paintutils.loadImage(\"System/Library/Interface/minimise\")!@#&      new.action = function()!@#&         _window:restore()!@#&       end!@#&     return new!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.DrawImage(self.x, self.y, self.icon)!@#&      --draw the indicator if the application is open!@#&     if OSInterfaceApplications.list[self.applicationName] then!@#&          OSDrawing.DrawCharacters(self.x + 1, self.y+ 2, self.Indicator, self.IndicatorColour, OSDock.BackgroundColour)!@#&      end!@#& end!@#&!@#& action = function(self)!@#&     local application = OSApplication:load(self.path)!@#&       OSApplication.run(application)!@#&  end",["OSProgressBar"]="--OSProgressBar--!@#& !@#&  __index = OSControl!@#&!@#& type = \"OSProgressBar\"!@#&    value = 0!@#&   BackgroundColour = colours.white!@#&    ProgressBackgroundColour = colours.lightBlue!@#&!@#&    new = function(self, _x, _y, _width, _value)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSProgressBar} ) -- copy an instance of OSMenuItem!@#&        new.width = _width!@#&      new.height = 1!@#&      new.x = _x!@#&      new.y = _y!@#&      new.value = _value!@#&      return new!@#&  end!@#&!@#& Draw = function(self)!@#&       if self.value > 100 then self.value = 0 end --prevent value from going above 100 percent!@#&        local progressEnd = OSServices.round(((self.value)/100)*self.width)!@#&     OSDrawing.DrawBlankArea(self.x, self.y, progressEnd, self.height, self.ProgressBackgroundColour)!@#&        OSDrawing.DrawBlankArea(self.x + progressEnd, self.y, self.width - progressEnd, self.height, self.BackgroundColour)!@#& end",["OSMenuItem"]="--OSMenuItem--!@#&!@#& __index = OSEntity -- parent class!@#&!@#&  isSelected = false!@#&  type = \"OSMenuItem\"!@#&   subtype = \"\"!@#&  shortcut = nil!@#&  !@#&    new = function(self, _title, _action, _shortcut)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSMenuItem} ) -- copy an instance of OSMenuItem!@#&       new.width = 0 --this is set to the string length of the longest item + 2 for padding!@#&        new.height = 1!@#&      new.title = _title!@#&      if _action then!@#&         new.action = function(self)!@#&         self.isSelected = true!@#&          self:Draw()!@#&         sleep(0.2)!@#&          _action()!@#&           OSUpdate()!@#&      end!@#&     end!@#&     if _shortcut then!@#&           new.shortcut = _shortcut!@#&            OSKeyboardShortcuts.register(_shortcut, _action)!@#&        end!@#&     return new!@#&  end!@#&!@#& updateCords = function(menuItem, _x, _y)!@#&        menuItem.x = _x!@#&     menuItem.y = _y!@#& end!@#&!@#& Draw = function(self)!@#&       local bgColour = OSMenu.BackgroundColour!@#&        local textColour = OSMenu.TextColour!@#&        --if the menu self doesn't have an action grey out the text!@#&     if self.action == nil then!@#&          textColour = OSMenu.DisabledTextColour!@#&      end!@#&!@#&     --if the self is selected give it the background and text color !@#&        if self.isSelected then!@#&         bgColour = OSMenu.SelectedBackgroundColour!@#&          textColour = OSMenu.SelectedTextColour!@#&          --hide all menus!@#&            self.isSelected = false!@#&         OSServices.shouldHideAllMenus = true!@#&        end!@#&!@#&     OSDrawing.DrawBlankArea(self.x, self.y, self.width, self.height, bgColour)!@#&      OSDrawing.DrawCharacters(self.x + 1, self.y, self.title, textColour, bgColour)!@#&      if self.shortcut then!@#&           OSDrawing.DrawCharacters(self.x + self.width - 3, self.y, \"#\"..self.shortcut, textColour, bgColour) !@#&      end!@#& end!@#&!@#& cleanup = function (self)!@#&       self = nil!@#&  end",["OSMenuSplitter"]="--OSMenuSplitter--!@#&!@#& __index = OSMenuItem -- parent class!@#&!@#&    subtype = \"OSMenuSplitter\"!@#&    type = \"OSMenuItem\"!@#&!@#&   new = function(self)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSMenuSplitter} ) -- copy an instance of OSMenuItem!@#&       new.width = 1 --this is set to the string length of the longest item later on (first draw)!@#&      new.height = 1!@#&!@#&      --create a string with the right amount of hyphens !@#&     new.id = 100!@#&        new.title = \"title\"!@#&       new.action = nil!@#&        return new!@#&  end!@#&!@#& updateCords = function(menuItem, _x, _y)!@#&        menuItem.x = _x!@#&     menuItem.y = _y!@#& end!@#&!@#& Draw = function(self)!@#&!@#&       --extend the length of the title if it isn't long enough!@#&        if string.len(self.title) < self.width then!@#&         --check if the menu self is a splitter (dont have the padding)!@#&          local title = \"\"!@#&          for i = 1, self.width do!@#&                title = title..\"-\"!@#&            end!@#&         self.title = title!@#&      end!@#&     --term.write(self.title)!@#&        OSDrawing.DrawArea(self.x, self.y, self.width, self.height, \"-\", OSMenu.BackgroundColour, OSMenu.DisabledTextColour)!@#&  end",["OSLabel"]="--OSLabel--!@#&   __index = OSControl!@#& !@#&    type = \"OSLabel\"!@#&!@#&  TextColour = colours.black!@#&  DisabledTextColour = colours.grey!@#&   BackgroundColour = colours.white!@#&!@#&    new = function(self, _x, _y, _title)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSLabel} )!@#&        new.width = string.len(_title)!@#&      new.height = 1!@#&      new.x = _x!@#&      new.y = _y!@#&      new.title = _title!@#&      new.enabled = true!@#&      return new!@#&  end!@#&!@#& Draw = function(self)!@#&       --if the self doesn't have an action grey out the text!@#&      local textColour = self.TextColour!@#&      --if the self is selected give it the background and text color !@#&        local bgColour = self.BackgroundColour!@#&      if not self.enabled then!@#&            textColour = self.DisabledTextColour!@#&        end!@#&     OSDrawing.DrawCharacters(self.x,self.y, self.title, textColour, bgColour)!@#&   end!@#&!@#& action = function()end",["OSDock"]="--OSDock--!@#&!@#&  __index = OSEntity!@#&!@#&  type = \"OSDock\"!@#&   width = 1!@#&   height = 3 --this includes the dock and its items!@#&   maxItems = 11 --(default screen width ([51] - the margin [3 * 2]) / 4)!@#&  items = {}!@#&  BackgroundColour = colours.lightGrey!@#&!@#&    new = function(self, _items)!@#&        self.width = (#_items * 4) + 4 - 1 -- width include the white bit at the end, the -1 is to compensate for the margin added by the last item!@#&     local dW, dH = term.getSize()!@#&       self.x = (dW/2) - (self.width/2)!@#&        self.y = dH - self.height!@#&       self.items = _items!@#&     return self!@#& end!@#&!@#& Draw = function (self)!@#&      OSDrawing.setOffset(self.x+1, self.y+1)!@#&     OSDrawing.DrawBlankArea(2, 2,  self.width-2, 1, self.BackgroundColour) --the upper dock bar !@#&        OSDrawing.DrawBlankArea(1, 3,  self.width, 1, self.BackgroundColour) --the lower dock bar!@#&       local itemX = 3 !@#&        local itemY = 1!@#&     for _,item in pairs(self.items) do!@#&          --update the absolue position of the dock item!@#&          item.x = itemX!@#&          item.y = itemY!@#&          item:Draw()!@#&         itemX = itemX + item.width + 1!@#&      end!@#& end!@#&!@#& add = function(self, _dockItem)!@#&     for i = 1, 2 do!@#&         self.width = self.width + 2!@#&         local dW, dH = term.getSize()!@#&           self.x = (dW/2) - (self.width/2)!@#&            OSUpdate()!@#&          sleep(0.1)!@#&      end!@#&     table.insert(self.items, _dockItem)!@#& end!@#&!@#& remove = function(self, _dockItem)!@#&      OSServices.removeTableItem(self.items, _dockItem)!@#&       for i = 1, 2 do!@#&         self.width = self.width - 2!@#&         local dW, dH = term.getSize()!@#&           self.x = (dW/2) - (self.width/2)!@#&            OSUpdate()!@#&          sleep(0.1)!@#&      end!@#& end!@#&!@#& action = function(self, x, y)!@#&       for _,item in pairs(self.items) do!@#&          --check if the click overlaps an items!@#&          if OSServices.pointOverlapsRect({x = x, y = y}, item)  then!@#&             OSServices.hideAllMenus()!@#&               item:action()!@#&               OSUpdate()!@#&              return!@#&          end!@#&     end!@#& end",["OSTextField"]="--OSTextField--!@#&!@#&   __index = OSControl!@#& type = \"OSTextField\"!@#&!@#&  text = \"\"!@#& Selection = {0,0} --start character, end character!@#&  CursorPosition = 0!@#&  Blink = false  --whether the blinking character should be shown!@#& BlinkCharacter = \"_\"!@#&  Offset = 0 --the amount of characters hidden!@#&    MoveDirection = 0!@#&   submit = nil!@#&!@#&    TextColour = colours.black!@#&  SelectedTextColour = colours.lightBlue!@#&  BackgroundColour = colours.white!@#&!@#&    new = function(self, _x, _y, _width, _text, _submit)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSTextField} )!@#&        new.width = _width!@#&      new.height = 1!@#&      new.x = _x!@#&      new.y = _y!@#&      new.text = _text!@#&        if _submit == nil then!@#&          new.submit = function() end!@#&     else!@#&            new.submit = _submit!@#&        end!@#&     return new!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.DrawBlankArea(self.x, self.y, self.width, self.height, self.BackgroundColour)!@#&!@#&     if #self.text < self.width - 1 then!@#&         self.Offset = 0!@#&     --the text box text is shorter that the maximum!@#&     OSDrawing.DrawCharacters(self.x + 1, self.y, self.text, self.TextColour, self.BackgroundColour)!@#&     else!@#&            self.Offset = #self.text - self.width + 2!@#&           if self.CursorPosition <= self.Offset then!@#&!@#&              self:moveCursor(-1)!@#&             self.Offset = self.CursorPosition!@#&!@#&           end!@#&         OSDrawing.DrawCharacters(self.x + 1, self.y, string.sub(self.text, self.Offset), self.TextColour, self.BackgroundColour)!@#&        end!@#&     if self.isSelected then!@#&         if self.Blink then!@#&              OSDrawing.DrawCharacters(self.x + self.CursorPosition - self.Offset, self.y, self.BlinkCharacter, self.TextColour, self.BackgroundColour)!@#&           end!@#&         self.Blink = not self.Blink!@#&     end!@#& end!@#&!@#& insertCharacter = function(self, char)!@#&      self.text = string.sub(self.text, 1, self.CursorPosition - 1) .. char .. string.sub(self.text, self.CursorPosition)!@#&     self.CursorPosition = self.CursorPosition + 1!@#&       self.Blink = true!@#&       OSUpdate()!@#&  end!@#&!@#& removeCharacter = function(self, direction)!@#&     if direction == 0 or self.CursorPosition > 1 then!@#&           self.text = string.sub(self.text, 1, self.CursorPosition - 1 + direction) .. string.sub(self.text, self.CursorPosition + 1 + direction)!@#&         self:moveCursor(direction)!@#&      end!@#&     self.Blink = true!@#&       OSUpdate()!@#&  end!@#&!@#& moveCursor = function(self, direction)!@#&      local c = self.CursorPosition + direction!@#&       if c < 1 then --make sure cursor is greater than 1!@#&          c = 1!@#&       end!@#&!@#&     if c > #self.text + 1 then --make sure cursor is the character after the last at maximum!@#&            c = #self.text + 1!@#&      end!@#&     self.CursorPosition = c!@#&     self.Blink = true!@#&       OSUpdate()!@#&  end!@#&!@#& action = function(self, x, y)!@#&       if x < 1 then --make sure x is greater than 1!@#&           x = 1!@#&       end!@#&!@#&     if x > #self.text + 1 then --make sure x is the character after the last at maximum!@#&         x = #self.text + 1!@#&      end!@#&!@#&     self.CursorPosition = x + self.Offset!@#&       self.Blink = true!@#&       OSSelectedEntity = self --gain focus!@#&    end",["OSAboutWindow"]="--OSAboutWindow--!@#&!@#&!@#&   __index = OSWindow!@#&!@#&  type = \"OSWindow\"!@#& subtype = \"OSAboutWindow\"!@#& title = \"About\"!@#&   entities = {}!@#&   environment = nil!@#&   canMaximise = false!@#& canMinimise = true!@#&  isMinimised = false!@#& canClose = true!@#& hasFrame = true!@#& minWidth = 11!@#&   minHeight = 5!@#&!@#&!@#&   action = function(self, x, y)!@#&   end!@#&!@#& local getCenter = function(_width, _length)!@#&     return math.ceil((_width - _length) / 2)!@#&    end!@#&!@#& new = function(self, _title, _version, _author, _path, _environment)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSWindow} )!@#&       new.title = \"About \".._title!@#&      !@#&        new.width = 20!@#&      new.height = 11 + 1 --for the menu bar!@#&      local w, h = OSServices.availableScreenSize()!@#&       new.x = getCenter(w, new.width)!@#&     new.y = getCenter(h, new.height) + 1!@#&        new.id = OSServices.generateID()!@#&        new.environment = _environment!@#&      OSCurrentWindow = new!@#&       local versionText = \"Version \".._version!@#&      new.canMaximise = false!@#&     local versionLabel = OSLabel:new(getCenter(new.width, #versionText), 9, \"Version \".._version)!@#&     versionLabel.TextColour = colours.grey!@#&!@#&      local copyrightLabel = OSLabel:new(4, 10, \"Copyright 2013\")!@#&       copyrightLabel.TextColour = colours.lightGrey!@#&!@#&       new.entities = {!@#&            OSImageView:new(8, 2, _path..\"/icon_l\"),!@#&          OSLabel:new(getCenter(new.width, #_title), 7, _title),!@#&          !@#&            versionLabel,!@#&           copyrightLabel,!@#&         OSLabel:new(getCenter(new.width, #_author)+1, 11, _author),!@#&     }!@#&!@#&       return new!@#&  end",["OSApplication"]="--OSApplication--!@#&!@#&   __index = OSObject --subclass of osobject!@#&   !@#&    type = \"OSApplication\"!@#&    title = \"\"!@#&    windows = {}!@#&    menus = {}!@#&  id = 0!@#&  environment = {}!@#&!@#&    new = function(_title, _menus, _windows)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSApplication} )!@#&      new.title = _title!@#&      new.menus = _menus!@#&      new.windows = _windows!@#&      new.id = OSServices.generateID()!@#&        return new!@#&  end!@#&!@#& load = function(self, _path)!@#&    --check if the application is already open!@#&      local name = OSFileSystem.shortName(_path)!@#&      if OSInterfaceApplications.list[name] then!@#&          --the application is already open, return that!@#&          return OSInterfaceApplications.list[name]!@#&       else!@#&            --load an application from a path and assign the environment!@#&!@#&            self.environment = OSServices.copyTable(getfenv())!@#&          --add additional commands for the application!@#&           self.environment['quit'] = function()term.setTextColour(colours.black) OSInterfaceApplications.remove(self) end!@#&         self.environment.name = name!@#&            self.environment.path = _path!@#&           self.environment.environment = self.environment!@#&!@#&         --initialise the application!@#&            local ok, err = os.run(self.environment, _path..\"/\"..name)!@#&            if not ok then --the application has an error in its code!@#&               if self.name then --application returned name!@#&                   error(\"The application \"..self.name..\" did not start correctly.\")!@#&               else!@#&                    error(\"An application crashed while trying to start.\")!@#&!@#&                end !@#&            else    !@#&                self.environment:init()     !@#&            end!@#&!@#&         return OSApplication.new(self.environment.name, self.environment.menus, self.environment.windows)!@#&       end!@#& end!@#&!@#& run = function(_application)!@#&        --if the application is already open bring focus to it !@#&     if OSInterfaceApplications.list[_application.title] then!@#&            OSInterfaceApplications.switchTo(OSInterfaceApplications.list[_application.title])!@#&      else!@#&            OSInterfaceApplications.switchTo(_application)!@#&      end!@#&     return _application!@#& end!@#&!@#& quit = function(self)!@#&       for _,window in pairs(self.windows) do!@#&          window:restore()!@#&        end!@#&     OSInterfaceApplications.remove(self)!@#&    end",["OSWindow"]="--OSWindow--!@#&!@#& __index = OSEntity!@#&!@#&  type = \"OSWindow\"!@#& title = \"\"!@#&    entities = {}!@#&   environment = nil!@#&   dragX = 0 --for getting the relative postion of the window when dragging!@#&    canMaximise = true!@#&  canMinimise = true!@#&  isMinimised = false!@#& canClose = true!@#& hasFrame = true!@#& BackgroundColour = colours.white!@#&    FrameTextColour = colours.black!@#& FocusFrameColour = colours.lightGrey!@#&    ButtonTextColour = colours.white!@#&    CloseColour = colours.red!@#&   MinimiseColour = colours.orange!@#& MaximiseColour = colours.lime!@#&   HandleCharacter = \"%\"!@#& HandleColour = colours.lightGrey!@#&    HandleBackgroundColour = colours.white!@#&  minWidth = 10!@#&   minHeight = 5!@#&   minimiseDockItem = nil!@#&!@#&  close = function(self)!@#&      --first check whether the application is ok with the close (or the checking function is not set)!@#&        if self.canClose then!@#&           if self.environment.windowShouldClose == nil or self.environment.windowShouldClose(self) then!@#&               term.setTextColour(colours.white)!@#&           --remove the window from the window list!@#&            local i = 0!@#&         for _,window in pairs(self.environment.windows) do!@#&              i = i + 1!@#&               if window == self then!@#&                  --remove the entity!@#&                 self.environment.windows[_]=nil!@#&                 OSServices.compactArray(self.environment.windows)!@#&                   if self.environment.windowDidClose then!@#&                     self.environment.windowDidClose(self)!@#&                   end!@#&                 OSUpdate()!@#&                  break!@#&                   end!@#&             end!@#&         end!@#&     end!@#& end!@#&!@#& minimise = function(self)!@#&       if not self.isMinimised then!@#&            self.isMinimised = true!@#&         OSCurrentWindow = nil!@#&           OSSelectedEntity = nil!@#&          self.minimiseDockItem = OSDockItem:newMinimise(self)!@#&            OSDock:add(self.minimiseDockItem)!@#&           OSUpdate()!@#&      end!@#& end!@#&!@#& restore = function(self)!@#&        if self.isMinimised then!@#&            OSDock:remove(self.minimiseDockItem)!@#&            self.minimiseItem = nil!@#&         self.isMinimised = false!@#&            OSCurrentWindow = self!@#&          OSUpdate()!@#&      end!@#& end!@#&!@#& maximise = function(self)!@#&       self.x = 1!@#&      self.y = 2!@#&      self:resize(OSServices.availableScreenSize())!@#&   end!@#&!@#& resize = function(self, w, h)!@#&       if not self.canMaximise then!@#&            return!@#&      end!@#&     if w <= self.minWidth then!@#&          w = self.minWidth!@#&       end!@#&!@#&     if h <= self.minHeight then!@#&         h = self.minHeight!@#&      end!@#&!@#&     self.width = w!@#&      self.height = h!@#&     if self.environment.windowDidResize then!@#&            self.environment.windowDidResize(self, w, h - 1)!@#&        end!@#&     OSUpdate()!@#&  end!@#&!@#& action = function(self, x, y)!@#&       --if the y of the click was 0 (the window frame) do special actions!@#&     if y == 0 then!@#&          if x == 1 then --close button!@#&               self:close()!@#&            elseif x == 2 and self.canMinimise then --minimise button!@#&               self:minimise()!@#&     !@#&            elseif x == 3 and self.canMaximise then --maximise button!@#&               self:maximise()!@#&         else --main bar!@#&             self.dragX = x - 1!@#&!@#&              OSWindowDragTimer = os.startTimer(OSServices.dragTimeout)!@#&           end!@#&         elseif x == self.width and y == self.height - 1 then!@#&                OSWindowResizeTimer = os.startTimer(OSServices.dragTimeout)!@#&         else -- it was in the window content!@#&                for _,entity in pairs(self.entities) do!@#&!@#&         --check if the click overlaps an entities!@#&!@#&               if OSServices.pointOverlapsRect({x = x, y = y}, entity)  then!@#&                   if OSServices.clickEntity(entity, x, y) then!@#&                        OSUpdate()!@#&                      return!@#&                  end!@#&             end!@#&         end!@#&     end!@#&     OSUpdate()!@#&  end!@#&!@#& Draw = function(self)!@#&       if self.isMinimised then!@#&            return!@#&      end!@#&!@#&     OSDrawing.setOffset(self.x, self.y + 1) -- 1 is added to the y offset because of the title bar!@#&!@#&      if self.hasFrame then!@#&           --draw the title bar!@#&            local frameColour = OSWindow.FocusFrameColour!@#&           if not self == OSCurrentWindow then!@#&             frameColour = OSWindow.FrameColour!@#&          end!@#&!@#&         OSDrawing.DrawBlankArea(1, 0, self.width, 1, frameColour)!@#&!@#&           --draw the title bar buttons!@#&            if self.canClose then!@#&               OSDrawing.DrawCharacters(1, 0, \"x\", OSWindow.ButtonTextColour, OSWindow.CloseColour)!@#&          end!@#&!@#&         if self.canMinimise then!@#&                OSDrawing.DrawCharacters(2, 0, \"-\", OSWindow.ButtonTextColour, OSWindow.MinimiseColour)!@#&           end!@#&!@#&         if self.canMaximise then!@#&                OSDrawing.DrawCharacters(3, 0, \"+\", OSWindow.ButtonTextColour, OSWindow.MaximiseColour)!@#&           end!@#&!@#&         --draw the title!@#&            local titleX = math.max(math.ceil((self.width / 2) - (#self.title / 2)), 0)!@#&         OSDrawing.DrawCharacters(titleX, 0, self.title, OSWindow.FrameTextColour, OSWindow.FocusFrameColour)!@#&!@#&        end!@#&!@#&     --draw the window background!@#&        OSDrawing.DrawBlankArea(1, 1, self.width, self.height - 1, OSWindow.BackgroundColour)!@#&!@#&       --draw the shadow!@#&       OSDrawing.DrawShadow(1, 0, self.width, self.height)!@#&!@#&     --draw the controls!@#&!@#&     for _,entity in pairs(self.entities) do!@#&         entity:Draw()!@#&       end!@#&!@#&     if self.canMaximise then!@#&            --draw the drag handle!@#&          OSDrawing.DrawCharacters(self.width, self.height-1, self.HandleCharacter, OSWindow.HandleColour, OSWindow.HandleBackgroundColour)!@#&       end!@#& end!@#&!@#& new = function(self, _title, _entities, _width, _height, _environment)!@#&      local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSWindow} )!@#&       new.title = _title!@#&      new.entities = _entities!@#&        new.width = _width!@#&      new.height = _height + 1 --for the menu bar!@#&     local w, h = OSServices.availableScreenSize()!@#&       new.x = math.ceil((w - _width) / 2)!@#&     new.y = math.ceil((h - _height) / 2) + 1!@#&        new.id = OSServices.generateID()!@#&        new.environment = _environment!@#&      OSCurrentWindow = new!@#&       return new!@#&  end",["OSButton"]="--OSButton--!@#&!@#& __index = OSControl!@#& !@#&    type = \"OSButton\"!@#&!@#& TextColour = colours.black!@#&  DisabledTextColour = colours.grey!@#&   BackgroundColour = colours.lightGrey!@#&    DisabledBackgroundColour = colours.lightGrey!@#&    SelectedBackgroundColour = colours.lightBlue!@#&    SelectedTextColour = colours.white!@#&!@#&  new = function(self, _x, _y, _title, _action)!@#&       local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSButton} )!@#&       new.width = string.len(_title)+2!@#&        new.height = 1!@#&      new.x = _x!@#&      new.y = _y!@#&      new.title = _title!@#&      new.action = _action!@#&        new.enabled = true!@#&      return new!@#&  end!@#&!@#& Draw = function(self)!@#&       --if the button doesn't have an action grey out the text!@#&        local textColour = nil!@#&!@#&!@#&      --if the button is selected give it the background and text color !@#&      local bgColour = nil!@#&        if self.isSelected then!@#&         bgColour = self.SelectedBackgroundColour!@#&            textColour = self.SelectedTextColour!@#&            self.isSelected = false!@#&     else!@#&            if self.enabled and self.action then!@#&                bgColour = self.BackgroundColour!@#&                textColour = self.TextColour!@#&            else!@#&                bgColour = self.DisabledBackgroundColour!@#&                textColour = self.DisabledTextColour!@#&            end!@#&     end!@#&     OSDrawing.DrawCharacters(self.x,self.y, \" \"..self.title..\" \", textColour, bgColour)!@#& end",["OSTextView"]="--OSTextView--!@#&!@#& __index = OSControl!@#& type = \"OSTextView\"!@#&!@#&   text = \"\"!@#& Selection = {0,0} --start character, end character!@#&  CursorPosition = 0!@#&  Blink = false  --whether the blinking character should be shown!@#& BlinkCharacter = \"|\"!@#&  MoveDirection = 0!@#&   submit = nil!@#&!@#&    TextColour = colours.black!@#&  SelectedBackgroundColour = colours.lightBlue!@#&    SelectedTextColour = colours.white!@#&  BackgroundColour = colours.white!@#&!@#&    new = function(self, _x, _y, _width, _height, _text)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSTextView} )!@#&     new.width = _width!@#&      new.height = _height!@#&        new.x = _x!@#&      new.y = _y!@#&      new.text = _text!@#&        new:calculateWrapping()!@#&     return new!@#&  end!@#&!@#&!@#& --Thanks to Kingdaro for this snippet :D!@#&    calculateWrapping = function(self)!@#&!@#&      local lines = {''}!@#&        for word, space in self.text:gmatch('(%S+)(%s*)') do!@#&                local temp = lines[#lines] .. word .. space:gsub('\\n','')!@#&                if #temp > self.width then!@#&                        table.insert(lines, '')!@#&                end!@#&                if space:find('\\n') then!@#&                        lines[#lines] = lines[#lines] .. word!@#&                        !@#&                        space = space:gsub('\\n', function()!@#&                                table.insert(lines, '')!@#&                                return ''!@#&                        end)!@#&                else!@#&                        lines[#lines] = lines[#lines] .. word .. space!@#&                end!@#&        end!@#&      self.lines = lines!@#&      OSUpdate()!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.DrawBlankArea(self.x, self.y, self.width, self.height, self.BackgroundColour)!@#&!@#&     for _,line in ipairs(self.lines) do!@#&         if _ <= self.height then!@#&            local startChar = (_-1) * self.width!@#&            local endChar   = startChar + #line!@#&!@#&         OSDrawing.DrawCharacters(self.x, self.y+_-1, line, self.TextColour, self.BackgroundColour)!@#&          if startChar < self.Selection[1] then!@#&               local selStr = string.sub(line,self.Selection[1],self.Selection[2])!@#&             OSDrawing.DrawCharacters(self.x+self.Selection[1]-1, self.y+_-1, selStr, self.SelectedTextColour, self.SelectedBackgroundColour)!@#&            else!@#&                OSDrawing.DrawCharacters(self.x, self.y+_-1, line, self.TextColour, self.BackgroundColour)!@#&          end         !@#&            end!@#&     end!@#&!@#&     if self.isSelected then!@#&         if self.Blink then!@#&              local cX, cY = (self.CursorPosition % self.width) + self.x, math.floor(self.CursorPosition/self.width) + self.y !@#&                OSDrawing.DrawCharacters(cX, cY, self.BlinkCharacter, self.TextColour, self.BackgroundColour)!@#&           end!@#&         self.Blink = not self.Blink!@#&     end!@#& end!@#&!@#& insertCharacter = function(self, char)!@#&      self.text = string.sub(self.text, 1, self.CursorPosition) .. char .. string.sub(self.text, self.CursorPosition + 1)!@#&     self.CursorPosition = self.CursorPosition + 1!@#&       self.Blink = true!@#&       self:calculateWrapping()!@#&    end!@#&!@#& removeCharacter = function(self, direction)!@#&     if direction == 0 or self.CursorPosition > 0 then!@#&           self.text = string.sub(self.text, 1, self.CursorPosition - 1 + direction) .. string.sub(self.text, self.CursorPosition + 1 + direction)!@#&         self:moveCursor(direction)!@#&      end!@#&     self.Blink = true!@#&       self:calculateWrapping()!@#&    end!@#&!@#& moveCursor = function(self, direction)!@#&      local c = self.CursorPosition + direction!@#&       if c < 0 then --make sure cursor is greater than 0!@#&          c = 0!@#&       end!@#&!@#&     if c > #self.text + 1 then --make sure cursor is the character after the last at maximum!@#&            c = #self.text + 1!@#&      end!@#&     self.CursorPosition = c!@#&     self.Blink = true!@#&       OSUpdate()!@#&  end!@#&!@#& action = function(self, x, y)!@#&       local pos  = 0!@#&      if y > #self.lines then!@#&         pos = #self.text!@#&        else!@#&            pos = x + (y *  self.width)!@#&     end!@#&     self.CursorPosition = pos!@#&       self.Blink = true!@#&       --self.Selection = {pos, pos}!@#&       OSSelectedEntity = self --gain focus!@#&    end",["OSListItem"]="--OSListItem--!@#&!@#& __index = OSMenuItem -- parent class!@#&!@#&    type = \"OSListItem\"!@#&   SelectedBackgroundColour = colours.lightBlue!@#&    SelectedTextColour = colours.white!@#&  BackgroundColour = colours.white!@#&    TextColour = colours.black!@#&!@#&  new = function(self, _title, _action)!@#&       local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSListItem} ) -- copy an instance of OSMenuItem!@#&       new.height = 1!@#&      new.title = _title!@#&      new.action = _action!@#&        return new!@#&  end!@#&!@#& Draw = function(self)!@#&       local bgColour = self.BackgroundColour!@#&      local textColour = self.TextColour!@#&      --if the item is selected give it the background and text color !@#&        if self.isSelected then!@#&         bgColour = OSListItem.SelectedBackgroundColour!@#&          textColour = OSListItem.SelectedTextColour  !@#&            self.isSelected = false!@#&     end !@#&!@#&        local title = self.title!@#&        if string.len(self.title) > self.width-1 then!@#&       --check if the menu self is a splitter (dont have the padding)!@#&      title = string.sub(self.title, 1, self.width-4) .. \"...\"!@#&      end!@#&!@#&     OSDrawing.DrawBlankArea(self.x, self.y, self.width, self.height, bgColour)!@#&      OSDrawing.DrawCharacters (self.x, self.y, \" \".. title, textColour,bgColour)!@#&   end!@#& ",["OSContainer"]="--OSContainer--!@#&!@#&  __index = OSEntity!@#&!@#&  type = \"OSContainer\"!@#&  entities = {}!@#&!@#&   new = function(self, _x, _y, _width, _height, _entities)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSContainer} ) -- copy an instance of OSMenuItem!@#&      new.width = _width!@#&      new.height = _height!@#&        new.x = _x!@#&      new.y = _y!@#&      new.entities = _entities!@#&        return new!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.addOffset(self.x, self.y)!@#&     for _,entity in pairs(self.entities) do!@#&         entity:Draw()!@#&       end!@#& end!@#&!@#& action = function(self, x, y)!@#&       x = x + 1!@#&       y = y + 1!@#&!@#&       for _,entity in pairs(self.entities) do!@#&         --check if the click overlaps an entities!@#&           if OSServices.pointOverlapsRect({x = x, y = y}, entity)  then!@#&               OSServices.clickEntity(entity, x, y)!@#&            end!@#&     end!@#& end",["OSClockButton"]="--OSClockButton--!@#&!@#&   __index = OSButton!@#&!@#&  type = \"OSButton\"!@#& subtype = \"OSClockButton\"!@#&!@#& new = function(self, _x, _y, _title)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSClockButton} ) -- copy an instance of OSMenuItem!@#&        new.width = string.len(_title)!@#&      new.height = 1!@#&      new.x = _x!@#&      new.y = _y!@#&      new.title = _title!@#&      new.enabled = false!@#&     return new!@#&  end!@#& !@#&    Draw = function(self)!@#&       local w, h = term.getSize()!@#&     local time = textutils.formatTime(os.time(), false)!@#&     self.x = w-string.len(time)!@#&     self.y = 1!@#&!@#&      local textColour = OSMenuBar.TextColour!@#&     local backgroundColour = OSMenuBar.BackgroundColour!@#&!@#&     self.title = time!@#&       OSDrawing.DrawCharacters(self.x, self.y, self.title, textColour, backgroundColour)!@#&  end",["OSInterfaceApplications"]="  --OSInterfaceApplications--!@#&!@#& list = {}!@#&!@#&   currentKey = ''!@#&!@#& previousKey = ''!@#&!@#&    currentID = 0!@#&!@#&   order = {} --as key based tables cant keep an order have a table with the order of the keys!@#&!@#& setCurrentKey = function(key)!@#&       OSInterfaceApplications.previousKey = OSInterfaceApplications.currentKey!@#&        OSInterfaceApplications.currentKey = key!@#&        for i,v in ipairs(OSInterfaceApplications.order) do!@#&         if v == key then!@#&                table.remove(OSInterfaceApplications.order, i)!@#&          end !@#&        end!@#&     table.insert(OSInterfaceApplications.order,1,key)!@#&   end!@#&!@#& current = function () --a helper function, returns the current application!@#&      return OSInterfaceApplications.list[OSInterfaceApplications.currentKey]!@#& end!@#&!@#& remove = function(application)!@#&      --prevent finder from being quit!@#&        if application == Finder then!@#&           return!@#&      end!@#&     for i,v in ipairs(OSInterfaceApplications.order) do!@#&         if v == application.title then!@#&              table.remove(OSInterfaceApplications.order, i)!@#&              OSInterfaceApplications.list[application.title] = nil!@#&           end !@#&        end!@#&     OSInterfaceApplications.switchTo(OSInterfaceApplications.list[OSInterfaceApplications.order[1]])!@#&    end!@#&!@#& switchTo = function(application)!@#&!@#&        --remove the previous applications menu, if there was a previous application!@#&        if OSInterfaceApplications.currentID > 0 then!@#&           local previousID = OSInterfaceApplications.currentID!@#&            --remove all menu items with the same tag as the previous application!@#&           for i = 1, #OSInterfaceEntities.list do!@#&             if OSInterfaceEntities.list[i] and OSInterfaceEntities.list[i].tag == previousID then!@#&                   OSInterfaceEntities.list[i]:cleanup()!@#&                   OSInterfaceEntities.list[i]=nil!@#&             end!@#&         end!@#&         OSServices.compactArray(OSInterfaceEntities.list)!@#&       end!@#&!@#&     --switch over to the new application    !@#&        OSInterfaceApplications.setCurrentKey(application.title)!@#&        OSInterfaceApplications.currentID = application.id!@#&      OSInterfaceApplications.list[OSInterfaceApplications.currentKey] = application  !@#&!@#&        --draw the current applications menus!@#&       cursorX = 4 --the first pixel after the P menu!@#&      if not OSFirstRunMode then!@#&          local appMenuItems = {!@#&              OSMenuItem:new(\"About \"..application.title, function () application.environment.about(application) end),!@#&              OSMenuSplitter:new(),!@#&               OSMenuItem:new(\"Preferences...\", function () application:quit() end, \",\"),!@#&              OSMenuSplitter:new(),!@#&               OSMenuItem:new(\"Close Window\", function () OSCurrentWindow:close() end, \"W\"),!@#&               OSMenuItem:new(\"Quit \"..application.title, function () application:quit() end, \"Q\")!@#&         }!@#&!@#&           if application.title == \"Finder\" then!@#&             --give a special  menu for finder!@#&               appMenuItems = {!@#&                OSMenuItem:new(\"About \"..application.title, function () application.environment.about(application) end),!@#&              OSMenuSplitter:new(),!@#&               OSMenuItem:new(\"Preferences...\", nil),!@#&                OSMenuSplitter:new(),!@#&               OSMenuItem:new(\"Close Window\", function () OSCurrentWindow:close() end, \"W\"),!@#&           }!@#&           end!@#&         local appMenu = OSMenu:new(cursorX, 1, application.title, appMenuItems)!@#&         appMenu.tag = application.id!@#&!@#&            OSInterfaceEntities.add(appMenu)!@#&        end!@#&     cursorX = cursorX + string.len(application.title) + 2!@#&!@#&       for i = 1, #application.menus do!@#&            local menu = application.menus[i]!@#&           menu.x = cursorX!@#&            menu.tag = application.id!@#&           OSInterfaceEntities.add(menu)!@#&           cursorX = cursorX + menu.width!@#&      end!@#& end",["OSInterfaceEntities"]="--OSInterfaceEntities--!@#&!@#&   list = {}!@#&!@#&   add = function(entity)!@#&      table.insert(OSInterfaceEntities.list, entity)!@#&  end!@#&!@#& remove = function(_entity)!@#&      for i = 1, #OSInterfaceEntities.list do!@#&         local entity = OSInterfaceEntities.list[i]!@#&          if entity == _entity then!@#&               --remove the entity!@#&             OSInterfaceEntities.list[i]=nil!@#&             OSServices.compactArray(OSInterfaceEntities.list)!@#&           end!@#&     end!@#& end",["OSImageView"]="--OSImageView--!@#&!@#&   __index = OSControl!@#& type = \"OSImageView\"!@#&!@#&  image = nil!@#&!@#& new = function(self, _x, _y, _path)!@#&     local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSImageView} )!@#&        new.x = _x!@#&      new.y = _y!@#&      new.image = paintutils.loadImage(_path)!@#&     return new!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.DrawImage(self.x, self.y, self.image)!@#& end",["OSMenu"]="--OSMenu--!@#&!@#& __index = OSControl -- parent class!@#&!@#& items = {}!@#&!@#&  isHidden = true!@#& isFirstDraw = true!@#&  type = \"OSMenu\"!@#&   shouldHide = false!@#&  hasShortcut = false!@#& id = 0!@#&!@#&  TextColour = colours.black!@#&  DisabledTextColour = colours.lightGrey!@#&  BackgroundColour = colours.white!@#&    SelectedBackgroundColour = colours.lightBlue!@#&    SelectedTextColour = colours.white!@#&!@#&  new = function(self, _x, _y, _title, _items)!@#&        local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSMenu} ) !@#&        new.x = _x!@#&      new.y = _y!@#&      new.width = string.len(_title) + 2 -- 2 is for the outer padding!@#&        new.height = 1!@#&      new.title = _title!@#&      new.items = _items!@#&      local hasShortcut = false!@#&       for _,i in ipairs(_items) do!@#&            if i.shortcut then!@#&              hasShortcut = true!@#&              break!@#&           end!@#&     end!@#&     self.hasShortcut = hasShortcut!@#&      --assign a unique id to each item!@#&       new.id = OSServices.generateID()--math.random()!@#&     return new!@#&  end!@#&!@#& action = function(menu)!@#&     if not menu.isHidden then!@#&           --menu is currently displayed, change it and hide the items!@#&         menu.isHidden = not menu.isHidden!@#&           menu:hideItems(menu)!@#&        else!@#&            --the menu is closed, hide other menus and enrole this for display!@#&          OSServices.hideAllMenus()!@#&           menu.isHidden = not menu.isHidden!@#&       end!@#&     OSUpdate()!@#&  end!@#&!@#& hideItems = function (self, menu)!@#&       --hide the menu items!@#&       for _,entity in ipairs(OSInterfaceEntities.list) do                     -- make sure the item is in the right menu!@#&          if entity.type == \"OSMenuItem\" and entity.id == menu.id then!@#&              OSInterfaceEntities.list[_]=nil!@#&         end!@#&     end!@#&!@#&     OSServices.compactArray(OSInterfaceEntities.list)!@#&       menu.isFirstDraw = true --set to first draw again so it will draw the menu!@#&  end!@#& !@#&    cleanup = function (self)!@#&       if not self.isHidden then --if the menu is open close it!@#&            self:hideItems(self)!@#&        end!@#& end!@#&!@#& DrawHiddenMenu = function(self)!@#&     --only draw the title of the self, not the content!@#&      OSDrawing.DrawCharacters(self.x, self.y, \" \"..self.title..\" \", self.TextColour, self.BackgroundColour)!@#&  end!@#&!@#& DrawFullMenu = function(self)!@#&       OSDrawing.DrawCharacters(self.x, self.y, \" \"..self.title..\" \", self.SelectedTextColour, self.SelectedBackgroundColour)!@#&!@#&      currentY = self.y!@#&!@#&       --if the menu hasn't been draw yet!@#&      if self.isFirstDraw then!@#&            --if not already set, calculate the width of the self!@#&           local menuWidth = 0!@#&         if self.items[1].width == 0 then!@#&                menuWidth =  OSServices.longestStringInArray(self.items) + 2--add two for padding!@#&               if self.hasShortcut then!@#&                    menuWidth = menuWidth + 3!@#&               end!@#&         else!@#&                menuWidth = self.items[1].width!@#&         end!@#&!@#&         for _,menuItem in pairs(self.items) do!@#&              menuItem.id = self.id!@#&               currentY = currentY + 1!@#&             menuItem:updateCords(self.x, currentY)!@#&              menuItem.width = menuWidth!@#&              menuItem:Draw()!@#&             OSInterfaceEntities.add(menuItem)!@#&           end!@#&         self.isFirstDraw = false!@#&        end!@#&     --draw the shadow!@#&       OSDrawing.DrawShadow(self.x, self.y, self.items[1].width, #self.items + 1)!@#&  end!@#& !@#&    Draw = function(self)!@#&       --if the menu has been told to close (should hide) close it!@#&     if not self.isHidden then!@#&           self:DrawFullMenu()!@#&     else!@#&            self:DrawHiddenMenu()!@#&       end!@#& end!@#& ",["OSBox"]="--OSBox--!@#&!@#&  __index = OSControl!@#& !@#&    type = \"OSBox\"!@#&!@#&    new = function(self, _x, _y, _width, _height, _colour)!@#&      local new = {}    -- the new instance!@#&       setmetatable( new, {__index = OSBox} )!@#&      new.x = _x!@#&      new.y = _y!@#&      new.width = _width!@#&      new.height = _height!@#&        new.color = _colour!@#&     return new!@#&  end!@#&!@#& Draw = function(self)!@#&       OSDrawing.DrawBlankArea(self.x, self.y, self.width, self.height, self.color)!@#&    end",},["Services"]={["OSTableIO"]="   function save(  tbl,filename )!@#&      local file = fs.open(filename, \"w\")!@#&      file.write(textutils.serialize(tbl))!@#&      file.close()!@#&   end!@#&   !@#&   function load( filename )!@#&      local file = fs.open(filename, \"r\")!@#&      local tbl = textutils.unserialize(file.readAll())!@#&      file.close()!@#&      return tbl!@#&   end",["OSServices"]="--OSServices--!@#&!@#& updateFrequency = OSSettings['update_frequency']!@#&    dragTimeout = 1!@#& commandTimeout = 1!@#&  shouldHideAllMenus = false!@#&  !@#&    rescheduleTimer = function()!@#&        OSUpdateTimer = os.startTimer(OSServices.updateFrequency) !@#&  end!@#& !@#&    resetSleepTimer = function()!@#&        if OSSettings['sleep_delay'] > 0 then!@#&           OSSleepTimer = os.startTimer(OSSettings['sleep_delay'])!@#&     end!@#& end!@#& !@#&    shutdown = function()!@#&       shell.run(\"System/Library/Computer/Shutdown\")!@#& end!@#& !@#&    restart = function()!@#&        shell.run(\"System/Library/Computer/Restart\")!@#&  end!@#& !@#&    switchScreen = function()!@#&       shell.run(\"System/Library/Computer/SwitchScreen\")!@#&     OSServices.rescheduleTimer()!@#&    end!@#& !@#&    craftos = function()!@#&        shell.run(\"System/Library/Computer/CraftOS\")!@#&  end!@#& !@#&    sleep2 = function()!@#&     term.setTextColour(colours.white)!@#&       shell.run(\"System/Library/Computer/Sleep\")!@#&    end!@#& !@#&    compactArray = function (table) --remove any array items set as nil!@#&     local j=0!@#&       for i=1, #table do!@#&          if table[i]~=nil then!@#&               j=j+1!@#&               table[j]=table[i]!@#&           end!@#&     end!@#&     for i=j+1, #table do!@#&            table[i]=nil!@#&        end!@#&     return table!@#&    end!@#& !@#&    removeTableItem = function(_table, _item)!@#&       for _,item in ipairs(_table) do!@#&         if item == _item then!@#&               table.remove(_table, _)!@#&         end!@#&     end!@#& end!@#& !@#&    --copied from http://stackoverflow.com/questions/640642/how-do-you-copy-a-lua-table-by-value!@#&    copyTable =function(t)!@#&      local u = { }!@#&       for k, v in pairs(t) do!@#&         u[k] = v!@#&        end!@#&     return setmetatable(u, getmetatable(t))!@#& end!@#& !@#&    longestStringInArray = function(input)!@#&      local length = 0!@#&        for i = 1, #input do!@#&            --if the string length is larger then the set length reset it!@#&           local titleLength = string.len(input[i].title)!@#&          if titleLength > length then!@#&                length = titleLength!@#&            end!@#&     end!@#&     return length!@#&   end!@#& !@#&    availableScreenSize = function()!@#&        local w, h = term.getSize()!@#&     return w, h - 4!@#& end!@#& !@#&    round = function(num, idp)!@#&      local mult = 10^(idp or 0)!@#&      return math.floor(num * mult + 0.5) / mult!@#&  end!@#& !@#&    lastID = 0  --the last used id number, this is used in generateID!@#&   generateID = function()!@#&     OSServices.lastID = OSServices.lastID + 1!@#&       return OSServices.lastID!@#&    end!@#&!@#& clickEntity = function(entity, x, y)!@#&        --make sure the entity has an action!@#&        if entity.action then!@#&           --if the entity doen't have the 'enabled' key or enabled is true!@#&            if entity.enabled == nil or entity.enabled then!@#&             local entityRelativeX = x - entity.x!@#&                local entityRelativeY = y - entity.y!@#&                entity:action(entityRelativeX, entityRelativeY)!@#&             entity.isSelected = true!@#&                return true --prevent any other clicks from being registered in the same place!@#&          end!@#&     end!@#&     return false!@#&    end!@#& !@#&    hideAllMenus = function ()!@#&      for i = 1, #OSInterfaceEntities.list do                     -- first delete all the list items!@#&          if OSInterfaceEntities.list[i].type == \"OSMenuItem\" then!@#&              OSInterfaceEntities.list[i]=nil!@#&         end!@#&     end!@#&     OSServices.compactArray(OSInterfaceEntities.list)!@#&!@#&       for i = 1, #OSInterfaceEntities.list do  --then set all menus to hidden     removed -->(the menu that just had it's items removed set to hidden)!@#&            if OSInterfaceEntities.list[i].type == \"OSMenu\" then!@#&              OSInterfaceEntities.list[i].isHidden = true!@#&             OSInterfaceEntities.list[i].isFirstDraw = true!@#&          end!@#&     end!@#& end!@#& !@#&    pointOverlapsRect = function (point, rect)!@#&      return point.x >= rect.x and point.x <=rect.x + rect.width - 1 and point.y >= rect.y and point.y <=rect.y + rect.height - 1!@#& end!@#&!@#& split = function(str, sep)!@#&      local sep, fields = sep or \":\", {}!@#&        local pattern = string.format(\"([^%s]+)\", sep)!@#&        str:gsub(pattern, function(c) fields[#fields+1] = c end)!@#&        return fields!@#&   end",["OSKeyboardShortcuts"]="--OSKeyboardShortcuts--!@#&!@#&   list = {}!@#&   register = function(_shortcut, _action)!@#&     OSKeyboardShortcuts.list[_shortcut] = _action!@#&   end",["OSInterfaceEntities"]="--OSInterfaceEntities--!@#&!@#&   list = {}!@#&!@#&   add = function(entity)!@#&      table.insert(OSInterfaceEntities.list, entity)!@#&  end!@#&!@#& remove = function(_entity)!@#&      for i = 1, #OSInterfaceEntities.list do!@#&         local entity = OSInterfaceEntities.list[i]!@#&          if entity == _entity then!@#&               --remove the entity!@#&             OSInterfaceEntities.list[i]=nil!@#&             OSServices.compactArray(OSInterfaceEntities.list)!@#&           end!@#&     end!@#& end",["OSFileSystem"]="--OSFileSystem--!@#&!@#& HomePath = \"/Home/\"!@#&   SystemPath = \"/System/\"!@#&!@#&   isDirectory = function(path) --return true if the path given is a folder (directory)!@#&        --if a directory has an extension (e.g. '.app') it is not considered a directory!@#&        return fs.isDir(path) and not OSFileSystem.hasExtention(path)!@#&   end!@#&     !@#&    exists = function(path)!@#&     return fs.exists(path)!@#&  end!@#&     !@#&    list = function(path) --list, but filter out hidden items!@#&       local t = {}!@#&        for _,v in ipairs(fs.list(path)) do!@#&         if not OSFileSystem.isHidden(path..v) then!@#&              table.insert(t, v)!@#&          end!@#&     end!@#&     return t!@#&    end!@#&     !@#&    isReadOnly = function(path)!@#&     return fs.isReadOnly(path)!@#&  end!@#&     !@#&    isHidden = function(path)!@#&       return string.sub(OSFileSystem.getName(path),1,string.len(1)) == \".\"!@#&  end!@#&     !@#&    hasExtention = function(path)!@#&       return string.find(OSFileSystem.getName(path), \"%.\")!@#&  end!@#&     !@#&    getName = function(path)!@#&        return fs.getName(path)!@#& end!@#&     !@#&    getSize = function(path)!@#&        return fs.getSize(path)!@#& end!@#&     !@#&    copy = function(path)!@#&       return fs.copy(path)!@#&    end!@#&     !@#&    move = function(path)!@#&       return fs.move(path)!@#&    end!@#&     !@#&    delete = function(path)!@#&     return fs.delete(path)!@#&  end!@#&     !@#&    merge = function(path)!@#&      return fs.combine(path)!@#& end!@#&     !@#&    extension = function(path) --get the file extension of a path (e.g. '/System/Applications/Finder.app' to '.app')!@#&        return string.match(path, \"([^%.]+)$\")!@#&    end!@#&     !@#&    shortName = function(path) --gets the file name with out the extension (e.g. above becomes 'Finder')!@#&        --if you know a better way to do this, please suggest a way!@#&     local str = OSFileSystem.getName(path)!@#&      if string.find(str, \"%.\") then!@#&            str = string.match(str, \".-%.\")!@#&           str = string.sub(str, 0,  #str - 1)!@#&     end!@#&     return str!@#&  end!@#&     !@#&    openFile = function(path)!@#&       local ext = OSFileSystem.extension(path)!@#&        if ext == \"app\" then!@#&          local app = OSApplication:load(path)!@#&            OSApplication.run(app)!@#&      else!@#&            --get the application that uses the extension!@#&           if OSExtensionAssociations.list[ext] then!@#&               local appPath = OSExtensionAssociations.list[ext]!@#&               local app = OSApplication:load(appPath)!@#&             local _app = OSApplication.run(app)!@#&             --open the file!@#&             _app.environment.openFile(path)!@#&         end         !@#&        end!@#& end",},},["Computer"]={["Sleep2"]="!@#&function PrintCentered(text)!@#&    local w, h = term.getSize()!@#&    x = math.max(math.ceil((w / 2) - (#text / 2)), 0)!@#&    y = math.max(math.ceil((h / 2)), 0)!@#&    term.setCursorPos(x, y)!@#&    print(text)!@#&end!@#&!@#&--add a message saying that the display has been moved to monitor!@#&term.setBackgroundColor(colors.black)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&!@#&PrintCentered(\"Zzzzzzz\")!@#&sleep(1)!@#&os.pullEventRaw()",["CraftOS"]="!@#&function PrintCentered(text)!@#&    local w, h = term.getSize()!@#&    x = math.max(math.ceil((w / 2) - (#text / 2)), 0)!@#&    y = math.max(math.ceil((h / 2)), 0)!@#&    term.setCursorPos(x, y)!@#&    print(text)!@#&end!@#&!@#&term.setBackgroundColor(colors.lightBlue)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&!@#&PrintCentered(\"Restoring CraftOS...\")!@#&sleep(1)!@#&OSSettings['boot_arg'] = \"craftos\"!@#&OSTableIO.save(OSSettings, \"Settings\")!@#&os.reboot()",["Restart"]="!@#&function PrintCentered(text)!@#&    local w, h = term.getSize()!@#&    x = math.max(math.ceil((w / 2) - (#text / 2)), 0)!@#&    y = math.max(math.ceil((h / 2)), 0)!@#&    term.setCursorPos(x, y)!@#&    print(text)!@#&end!@#&!@#&--add a message saying that the display has been moved to monitor!@#&term.setBackgroundColor(colors.lightBlue)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&!@#&PrintCentered(\"Restarting...\")!@#&sleep(1)!@#&os.reboot()",["Shutdown"]="!@#&function PrintCentered(text)!@#&    local w, h = term.getSize()!@#&    x = math.max(math.ceil((w / 2) - (#text / 2)), 0)!@#&    y = math.max(math.ceil((h / 2)), 0)!@#&    term.setCursorPos(x, y)!@#&    print(text)!@#&end!@#&!@#&--add a message saying that the display has been moved to monitor!@#&term.setBackgroundColor(colors.lightBlue)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&!@#&PrintCentered(\"Shutting down, good bye.\")!@#&sleep(2)!@#&os.shutdown()",["SwitchScreen"]="sides = {!@#&\"front\",!@#&\"back\",!@#&\"left\",!@#&\"right\",!@#&\"top\",!@#&\"bottom\"!@#&}!@#&!@#&function PrintCentered(text, y)!@#&    local w, h = term.getSize()!@#&    x = math.max(math.ceil((w / 2) - (#text / 2)), 0)!@#&    if not y then y = math.max(math.ceil((h / 2)), 0) end --set y to center if not assigned!@#&    term.setCursorPos(x, y)!@#&    print(text)!@#&end!@#&!@#&!@#&--add a message saying that the display has been moved to monitor!@#&term.setBackgroundColor(colors.lightBlue)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&!@#&PrintCentered(\"Switching display...\")!@#&sleep(2)!@#&!@#&if not usingMonitor then!@#&   --use the monitor!@#&   for _,side in pairs(sides) do!@#&       if peripheral.isPresent(side) and peripheral.getType(side) == \"monitor\" then!@#&          displayMovedMessage()!@#&           term.redirect(peripheral.wrap(side))!@#&            usingMonitor = true!@#&     end!@#& end!@#&else !@#&    --clear the monitor!@#& term.setBackgroundColor(colors.black)!@#&   term.clear()!@#&    term.restore()!@#&  usingMonitor = false!@#&end",},["FirstRun.app"]={["FirstRun"]="!@#& name = \"FirstRun\"!@#& menus = {}!@#&  windows = {}!@#&    version = \"1.0\"!@#&   !@#&    firstTime = nil --if the user has used pearos before!@#&    !@#&    init = function(self)!@#&           self:firstRun()!@#& end!@#& !@#&!@#&    firstRun = function(self)!@#&       firstRunWindow = OSWindow:new(\"\", {!@#&           !@#&        }, 47,16, self)!@#&     firstRunWindow.x = 3!@#&        firstRunWindow.y = 1!@#&        firstRunWindow.canMaximise = false!@#&      --firstRunWindow.canClose = false!@#&       --firstRunWindow.FocusFrameColour = colours.white!@#&       firstRunWindow.hasFrame = false!@#&     self:changePage(1)!@#&      self.windows['firstRun'] = firstRunWindow!@#&   end !@#&    !@#&    changePage = function(self, page)!@#&       if page == 1 then!@#&           firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Shutdown\", function() os.shutdown() end),!@#&             OSLabel:new(3,2 ,\"Welcome to PearOS\"),!@#&                OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"This guide will help you get up and\"),!@#&              OSLabel:new(3,6 ,\"running as quick as possible.\"),!@#&                OSLabel:new(3,8 ,\"To continue, click 'Next'\"),!@#&                OSButton:new(39,15 ,\"Next\", function() self:changePage(7) end)!@#&            }!@#&       elseif page == 2 then           --new?!@#&          firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(page - 1) end),!@#&             OSLabel:new(3,2 ,\"Are you new?\"),!@#&             OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"Have you used PearOS before?\"),!@#&             OSLabel:new(3,7 ,\"This will help us determine how to set up\"),!@#&                OSLabel:new(3,8 ,\"your computer and whether you need to be\"),!@#&             OSLabel:new(3,9 ,\"shown how to use it.\"),!@#&             OSButton:new(35,15 ,\"Yes\", function() firstTime = false self:changePage(3) end),!@#&              OSButton:new(41,15 ,\"No\", function() firstTime = true self:changePage(7) end)!@#&             !@#&            }!@#&       elseif page == 3 then       -- ask restore settings from disk!@#&           firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(page - 1) end),!@#&             OSLabel:new(3,2 ,\"Restore previous settings?\"),!@#&               OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"Do you want to restore your settings and\"),!@#&             OSLabel:new(3,6 ,\"applications  from a different computer?\"),!@#&             OSLabel:new(3,8 ,\"If the other computer is not in this world\"),!@#&               OSLabel:new(3,9 ,\"you can not restore files, click 'No'\"),!@#&                OSButton:new(35,15 ,\"Yes\", function() self:changePage(4) end),!@#&                OSButton:new(41,15 ,\"No\", function() self:changePage(7) end)!@#&              !@#&            }!@#&       elseif page == 4 then       --request disk for restore!@#&          firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(page - 1) end),!@#&             OSLabel:new(3,2 ,\"Insert the restore disk...\"),!@#&               OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"Please insert the restore disk in a drive.\"),!@#&               OSLabel:new(3,7 ,\"If you do not have disk click 'Help'\"),!@#&             OSLabel:new(3,8 ,\"However, it may be easier to start again.\"),!@#&                OSButton:new(39,15 ,\"Help\", function() self:changePage(5) end)!@#&                !@#&            }!@#&       elseif page == 5 then       --restore help!@#&          firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(page - 1) end),!@#&             OSLabel:new(3,2 ,\"Restore Disk Help\"),!@#&                OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"Please insert the restore disk in a drive.\"),!@#&               OSLabel:new(3,7 ,\"If you do not have disk click 'Help'\"),!@#&             OSLabel:new(3,8 ,\"However, it may be easier to start again.\"),!@#&                OSButton:new(39,15 ,\"Help\", function() self:changePage(5) end)!@#&                !@#&            }!@#&           !@#&        elseif page == 6 then       --restore copy!@#&          firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(page - 1) end),!@#&             OSLabel:new(3,2 ,\"Restoring...\"),!@#&             OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"Copying your files, applications and\"),!@#&             OSLabel:new(3,6 ,\"settings to your new computer.\"),!@#&               OSLabel:new(3,8 ,\"Do not remove the disk or drive.\")!@#&              !@#&            }!@#&       elseif page == 7 then       --clean setup start!@#&         nameTextBox = OSTextField:new(13,10,21,\"\")!@#&            nameTextBox.BackgroundColour = colours.lightGrey!@#&            !@#&            firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(3) end),!@#&                OSLabel:new(3,2 ,\"What's your name?\"),!@#&                OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"Click on the grey box and enter your name.\"),!@#&               nameTextBox,!@#&                OSButton:new(39,15 ,\"Next\", function() if #nameTextBox.text > 0 then setName(nameTextBox.text) self:changePage(8) end end)!@#&                !@#&            }!@#&       elseif page == 8 then       --clean setup start!@#&         OSSelectedEntity = nil!@#&          !@#&            startX = 13!@#&         startY = 9!@#&          !@#&            local orange = OSButton:new(startX, startY,\" \", function(self) setDesktopBackground(colours.orange) end)!@#&          orange.BackgroundColour = colours.orange!@#&            orange.SelectedBackgroundColour = colours.orange!@#&            !@#&            local magenta = OSButton:new(startX + 4, startY,\" \", function() setDesktopBackground(colours.magenta) end)!@#&            magenta.BackgroundColour = colours.magenta!@#&          magenta.SelectedBackgroundColour = colours.magenta!@#&          !@#&            local lightBlue = OSButton:new(startX + 8, startY,\" \", function() setDesktopBackground(colours.lightBlue) end)!@#&            lightBlue.BackgroundColour = colours.lightBlue!@#&          lightBlue.SelectedBackgroundColour = colours.lightBlue!@#&          !@#&            local yellow = OSButton:new(startX + 12, startY,\" \", function() setDesktopBackground(colours.yellow) end)!@#&         yellow.BackgroundColour = colours.yellow!@#&            yellow.SelectedBackgroundColour = colours.yellow!@#&            !@#&            local lime = OSButton:new(startX + 16, startY,\" \", function() setDesktopBackground(colours.lime) end)!@#&         lime.BackgroundColour = colours.lime!@#&            lime.SelectedBackgroundColour = colours.lime!@#&            !@#&            local pink = OSButton:new(startX + 20, startY,\" \", function() setDesktopBackground(colours.pink) end)!@#&         pink.BackgroundColour = colours.pink!@#&            pink.SelectedBackgroundColour = colours.pink!@#&            !@#&            local grey = OSButton:new(startX, startY + 2,\" \", function() setDesktopBackground(colours.grey) end)!@#&          grey.BackgroundColour = colours.grey!@#&            grey.SelectedBackgroundColour = colours.grey!@#&            !@#&            local cyan = OSButton:new(startX + 4, startY + 2,\" \", function() setDesktopBackground(colours.cyan) end)!@#&          cyan.BackgroundColour = colours.cyan!@#&            cyan.SelectedBackgroundColour = colours.cyan!@#&            !@#&            local purple = OSButton:new(startX + 8, startY + 2,\" \", function() setDesktopBackground(colours.purple) end)!@#&          purple.BackgroundColour = colours.purple!@#&            purple.SelectedBackgroundColour = colours.purple!@#&            !@#&            local blue = OSButton:new(startX + 12, startY + 2,\" \", function() setDesktopBackground(colours.blue) end)!@#&         blue.BackgroundColour = colours.blue!@#&            blue.SelectedBackgroundColour = colours.blue!@#&            !@#&            local brown = OSButton:new(startX + 16, startY + 2,\" \", function() setDesktopBackground(colours.brown) end)!@#&           brown.BackgroundColour = colours.brown!@#&          brown.SelectedBackgroundColour = colours.brown!@#&          !@#&            local red = OSButton:new(startX + 20, startY + 2,\" \", function() setDesktopBackground(colours.red) end)!@#&           red.BackgroundColour = colours.red!@#&          red.SelectedBackgroundColour = colours.red!@#&          !@#&            !@#&            firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(2) end),!@#&                OSLabel:new(3,2 ,\"Desktop Background\"),!@#&               OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3,5 ,\"Choose a desktop background colour by\"),!@#&                OSLabel:new(3,6 ,\"clicking on a coloured box, you can\"),!@#&              OSLabel:new(3,7 ,\"change this again in System Preferences.\"),!@#&             orange,!@#&             magenta,!@#&                lightBlue,!@#&              yellow,!@#&             lime,!@#&               pink,!@#&               grey,!@#&               cyan,!@#&               purple,!@#&             blue,!@#&               brown,!@#&              green,!@#&              red,!@#&                OSButton:new(39,15 ,\"Next\", function() self:changePage(10) end)               !@#&            }!@#&           !@#&        elseif page == 9 then!@#&           firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(page - 1) end),!@#&             OSLabel:new(3,2 ,\"Automatic updates?\"),!@#&               OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3, 5 ,\"Do you want to enabled automatic updates?\"),!@#&               OSLabel:new(3, 7 ,\"If enabled, PearOS will update it self to\"),!@#&               OSLabel:new(3, 8 ,\"the latest version when ever possible.\"),!@#&              OSLabel:new(3, 10,\"However, this requires the 'http' API\"),!@#&               OSLabel:new(3, 11,\"to be enabled. (current \".. (http and \"enabled\" or \"not enabled\") ..\").\"),!@#&!@#&               OSButton:new(35,15 ,\"Yes\", function() setUpdates(true) self:changePage(10) end),!@#&              OSButton:new(41,15 ,\"No\", function() setUpdates(false) self:changePage(10) end)!@#&               !@#&            }!@#&       elseif page == 10 then!@#&          setUpdates(false)!@#&           firstRunWindow.entities = {!@#&             OSButton:new(3,15 ,\"Back\", function() self:changePage(page - 1) end),!@#&             OSLabel:new(3,2 ,\"All Done!\"),!@#&                OSHSplitter:new(1, 3, 47, true),!@#&                OSLabel:new(3, 5 ,\"PearOS setup is complete!\"),!@#&               OSLabel:new(3, 7 ,\"To begin using PearOS click 'Restart'\"),!@#&!@#&               OSButton:new(36,15 ,\"Restart\", function() saveSettings() os.reboot() end),!@#&                !@#&            }!@#&       end!@#& end!@#&     !@#&    desktopBackground = colours.grey    !@#&    setDesktopBackground = function(colour)!@#&     desktopBackground = colour!@#&!@#&      desktop.BackgroundColour = colour!@#&       desktop:Draw()!@#&  end!@#&!@#& setUpdates = function(updates)!@#&      OSSettings['updates_enabled'] = updates!@#& end!@#& !@#&    setName = function(name)!@#&        OSSettings['user_name'] = name!@#&      OSSettings['machine_name'] = name..\"'s Computer\"!@#&  end!@#& !@#&    saveSettings = function()!@#&       OSChangeSetting('desktop_bg', desktopBackground, true)!@#&      OSTableIO.save(OSSettings,\"Settings\")!@#& end",},["Documentation"]={["Your First PearOS Application"]="Your First PearOS Application!@#&",},},["clean"]="-- Lua code formatter!@#&-- Removes tabs and checks lines arent too long.!@#&-- Nick Trout!@#&-- $Header: /Tools/build/codefmt.lua 3     16/08/01 20:00 Nick $!@#&-- For Lua 5.0!@#&!@#&mytabs = 4 -- spaces (default)!@#&myindent = 4 -- spaces (default)!@#&codetabsize = 8 -- spaces!@#&codeindent = 2 -- spaces per indent!@#&codelinelength = 80 -- characters!@#&!@#&!@#&usage = !@#&[[!@#&!@#&Usage: lua -f codeformat.lua ...options...!@#&!@#&Options are:!@#&--file <lua file>!@#&--ts <spaces>, tabsize: number of spaces in your tabs!@#&--in <spaces>, indent size: number of spaces for each indentation!@#&!@#&]]!@#&!@#&!@#&function process_args()!@#&  -- get args set by user in command line!@#&  local t,i = {},1!@#&  while i<table.getn(arg) do!@#&    local a=arg[i]!@#&    if a==\"--file\" then!@#&      t.filename,i = arg[i+1],i+2!@#&    elseif a==\"--ts\" then!@#&      t.mytabsize,i = arg[i+1]+0,i+2!@#&    elseif a==\"--in\" then!@#&      t.myindent,i = arg[i+1]+0,i+2!@#&    else!@#&      print(usage..\"Bad flag: \"..a)!@#&      os.exit(-1)!@#&    end!@#&  end!@#&  return t!@#&end!@#&!@#&function readfile(f)!@#&  local fh=io.open(f,\"r\")!@#&  local t={}!@#&  for ln in fh:lines() do!@#&    if ln then table.insert(t,ln) else break end!@#&  end!@#&  fh:close()!@#&  return t!@#&end!@#&!@#&-- convert any leading tabs in a given string to spaces.!@#&-- the number of spaces to replace the tab by is given by args.mytabsize!@#&function convertTabsToSpaces(ln)!@#&  local s,e = string.find(ln,\"\\t+\",1)!@#&  if s and s==1 then!@#&    local spc = string.rep(\" \",args.mytabsize*(e-s+1))!@#&    ln = spc..string.sub(ln,e+1)!@#&  end!@#&  return ln!@#&end!@#&!@#&-- convert any indentation to use the standard indent!@#&function indent(ln)!@#&  local s,e = string.find(ln,\" +\",1)!@#&  if s==1 then!@#&    local indent = (e-s+1)/args.myindent!@#&    ln = string.rep(\" \",codeindent*indent)..string.sub(ln,e+1)!@#&  end!@#&  return ln!@#&end!@#&  !@#&function process(lines)!@#&  --local lines = {}!@#&  local f,err = io.open(\"System/Cleaned File\",\"a\")!@#&!@#&  for li=1,table.getn(lines) do!@#&    local line=lines[li]!@#&    line = convertTabsToSpaces(line)!@#&    line = indent(line)!@#&    -- warn if length too long!@#&    local len=string.len(line)!@#&    if len>codelinelength then!@#&      print(\"-- ######## Line too long (\"..len..\" chars) ######## :\")!@#&    end!@#&      print(line)!@#&      f:write(line..\"\\n\")!@#&  end!@#&end!@#&!@#&--args = process_args()!@#&--if not args.filename then error(usage..\"no Lua file given\") end!@#&args = {}!@#&args.mytabsize = mytabs!@#&args.myindent = myindent!@#&process( readfile(\"System/PearOS.lua\") )",["Applications"]={["System Preferences.app"]={["System Preferences"]="!@#&   name = \"System Preferences\"!@#&   menus = {}!@#&  windows = {}!@#&    version = \"0.9\"!@#&   showHidden = false!@#&  id = 0  !@#&    !@#&    init = function()!@#&           menus = {}!@#&          systemPreferences()!@#& end!@#& !@#&    about = function()!@#&      local licenceLabel = OSLabel:new(6, 10, \"(c) 2013\")!@#&       local secondLicenceLabel = OSLabel:new(1,11, \"Oliver'oeed'Cooper\")!@#&        licenceLabel.TextColour = colors.lightGray!@#&      secondLicenceLabel.TextColour = colors.lightGray!@#&    !@#&        local aboutWindow = OSWindow:new(\"\", {!@#&        OSImageView:new(7, 1, path..\"/icon_l\"),!@#&       OSLabel:new(1, 6, \"System Preferences\"),!@#&      licenceLabel,!@#&       secondLicenceLabel!@#&      }, 20,12, environment)!@#&      !@#&        windows['about'] = aboutWindow!@#&  end!@#&!@#& systemPreferences = function()!@#&      !@#&        local settingsListView = OSListView:new(1, 2, 17, 14, {!@#&         OSListItem:new(\"General\", function()switchCategory('General')end),!@#&            OSListItem:new(\"Startup\", function()switchCategory('Startup')end),!@#&            OSListItem:new(\"Appearance\", function()switchCategory('Appearance')end),!@#&          OSListItem:new(\"Sound\", function()switchCategory('Sound')end),!@#&            OSListItem:new(\"Date and Time\", function()switchCategory('Date and Time')end),!@#&            OSListItem:new(\"File Extentions\", function()switchCategory('File Extentions')end),!@#&            OSListItem:new(\"Software Update\", function()switchCategory('Software Update')end),!@#&        })!@#&              !@#&        categoryLabel = OSLabel:new(20,2 ,\"General\")!@#&      settingsContainer = OSContainer:new(19,5, 27, 11, {})!@#&       switchCategory('Appearance')--start category!@#&        local systemPreferencesWindow = OSWindow:new(name, {!@#&            settingsListView,!@#&           OSVSplitter:new(18, 1, 14, false),!@#&          OSHSplitter:new(19, 3, 27, true),!@#&           categoryLabel,!@#&          settingsContainer!@#&           !@#&        }, 45,14, environment)!@#&      !@#&        environment.windows['systemPreferences'] = systemPreferencesWindow!@#&  end!@#& !@#&    setDesktopBackground = function(colour)!@#&     OSChangeSetting('desktop_bg', colour, true)!@#& end!@#& !@#&    switchCategory = function(category)!@#&     categoryLabel.title = category!@#&      if category == 'Appearance' then!@#&            !@#&            startX = 2!@#&          startY = 3!@#&          !@#&            local orange = OSButton:new(startX, startY,\" \", function(self) setDesktopBackground(colours.orange) end)!@#&          orange.BackgroundColour = colours.orange!@#&            orange.SelectedBackgroundColour = colours.orange!@#&            !@#&            local magenta = OSButton:new(startX + 4, startY,\" \", function()setDesktopBackground(colours.magenta) end)!@#&         magenta.BackgroundColour = colours.magenta!@#&          magenta.SelectedBackgroundColour = colours.magenta!@#&          !@#&            local lightBlue = OSButton:new(startX + 8, startY,\" \", function() setDesktopBackground(colours.lightBlue) end)!@#&            lightBlue.BackgroundColour = colours.lightBlue!@#&          lightBlue.SelectedBackgroundColour = colours.lightBlue!@#&          !@#&            local yellow = OSButton:new(startX + 12, startY,\" \", function() setDesktopBackground(colours.yellow) end)!@#&         yellow.BackgroundColour = colours.yellow!@#&            yellow.SelectedBackgroundColour = colours.yellow!@#&            !@#&            local lime = OSButton:new(startX + 16, startY,\" \", function() setDesktopBackground(colours.lime) end)!@#&         lime.BackgroundColour = colours.lime!@#&            lime.SelectedBackgroundColour = colours.lime!@#&            !@#&            local pink = OSButton:new(startX + 20, startY,\" \", function() setDesktopBackground(colours.pink) end)!@#&         pink.BackgroundColour = colours.pink!@#&            pink.SelectedBackgroundColour = colours.pink!@#&            !@#&            local grey = OSButton:new(startX, startY + 2,\" \", function() setDesktopBackground(colours.grey) end)!@#&          grey.BackgroundColour = colours.grey!@#&            grey.SelectedBackgroundColour = colours.grey!@#&            !@#&            local cyan = OSButton:new(startX + 4, startY + 2,\" \", function() setDesktopBackground(colours.cyan) end)!@#&          cyan.BackgroundColour = colours.cyan!@#&            cyan.SelectedBackgroundColour = colours.cyan!@#&            !@#&            local purple = OSButton:new(startX + 8, startY + 2,\" \", function() setDesktopBackground(colours.purple) end)!@#&          purple.BackgroundColour = colours.purple!@#&            purple.SelectedBackgroundColour = colours.purple!@#&            !@#&            local blue = OSButton:new(startX + 12, startY + 2,\" \", function() setDesktopBackground(colours.blue) end)!@#&         blue.BackgroundColour = colours.blue!@#&            blue.SelectedBackgroundColour = colours.blue!@#&            !@#&            local brown = OSButton:new(startX + 16, startY + 2,\" \", function() setDesktopBackground(colours.brown) end)!@#&           brown.BackgroundColour = colours.brown!@#&          brown.SelectedBackgroundColour = colours.brown!@#&          !@#&            local red = OSButton:new(startX + 20, startY + 2,\" \", function() setDesktopBackground(colours.red) end)!@#&           red.BackgroundColour = colours.red!@#&          red.SelectedBackgroundColour = colours.red!@#&          !@#&            !@#&            settingsContainer.entities = {!@#&              OSLabel:new(2, 1, \"Desktop Background\"),!@#&              orange,!@#&             magenta,!@#&                lightBlue,!@#&              backButton,!@#&             yellow,!@#&             lime,!@#&               pink,!@#&               grey,!@#&               cyan,!@#&               purple,!@#&             blue,!@#&               brown,!@#&              green,!@#&              red!@#&         }!@#&           else settingsContainer.entities = {!@#&             OSLabel:new(3, 4, \"This Will Be Added Soon\"),!@#&         }!@#&       end!@#& end!@#&!@#& function windowDidClose(self)!@#&       print(\"quit\")!@#&     environment:quit()!@#&  end!@#&     ",["icon_l"]="bb3333!@#&bb3333!@#&bbbb33!@#&bbbb33",["icon"]="777!@#&787",},["Finder.app"]={["icon"]="b33!@#&bb3",["icon_s"]="3",["icon_l"]="bb3333!@#&bb3333!@#&bbbb33!@#&bbbb33",["Finder"]="!@#& name = \"Finder\"!@#&   menus = {}!@#&  windows = {}!@#&    version = \"0.9\"!@#&   showHidden = false!@#&  id = 0!@#&  author = \"Oliver'oeed'Cooper\"!@#& !@#&    init = function()!@#&       local filemenuItems = {!@#&             OSMenuItem:new(\"New Finder Window\", function() !@#&               newFinderWindow(OSFileSystem.HomePath) end,\"N\"),!@#&              OSMenuItem:new(\"Open\", nil, \"O\")!@#&            }!@#&       local filemenu = OSMenu:new(1, 1, \"File\", filemenuItems)!@#&      !@#&            local editmenuItems = {!@#&             OSMenuItem:new(\"Copy\", nil, \"C\")!@#&            }!@#&       local editmenu = OSMenu:new(1, 1, \"Edit\", editmenuItems)!@#&      !@#&            menus = {filemenu, editmenu}!@#&            newFinderWindow(OSFileSystem.HomePath)!@#&  end!@#& !@#&    about = function()!@#&      windows['about'] = OSAboutWindow:new(name, version, author, path, environment)!@#&  end!@#& !@#&    aboutSystem = function()!@#&        windows['aboutSystem'] = OSAboutWindow:new(\"PearOS\", OSVersionLong, author, \"System/Library/Interface\", environment)!@#&    end!@#& !@#&    !@#&    newFinderWindow = function(path)!@#&        local width = 48!@#&        local height = 13!@#&       local finderWindow = nil!@#&        !@#&        !@#&            local placesLabel = OSListItem:new(\"Places\", nil)!@#&         placesLabel.TextColour = colours.lightGrey!@#&      local placesListView = OSListView:new(1, 4, 15, 11, {!@#&           placesLabel,!@#&            OSListItem:new(\" Applications\", function() handleItem(\"/System/Applications/\", finderWindow) end),!@#&          OSListItem:new(\" Desktop\", function() handleItem(OSFileSystem.HomePath..\"Desktop/\", finderWindow) end),!@#&         OSListItem:new(\" \".. string.sub(OSFileSystem.getName(OSFileSystem.HomePath),1, 12), function() handleItem(OSFileSystem.HomePath, finderWindow) end),!@#&          OSListItem:new(\" Documents\", function() handleItem(OSFileSystem.HomePath..\"Documents/\", finderWindow) end),!@#&     })!@#&      local splitter = OSVSplitter:new(16, 3, height-2)!@#&       !@#&        local toolbar = OSBox:new(1,1, width, 2, colours.lightGrey)!@#&     local backButton = OSButton:new(3,1, \"<\", function() goBack(finderWindow) end)!@#&        local buttonsSplitter = OSVSplitter:new(6, 1, 1)!@#&        !@#&        local forwardButton = OSButton:new(7,1, \">\", nil)!@#&     backButton.BackgroundColour = colours.white!@#&     backButton.DisabledTextColour = colours.lightGrey!@#&       backButton.DisabledBackgroundColour = colours.white!@#&     !@#&        forwardButton.BackgroundColour = colours.white!@#&      forwardButton.DisabledTextColour = colours.lightGrey!@#&        forwardButton.DisabledBackgroundColour = colours.white!@#&!@#&      local pathbar = OSTextField:new(11,1,31, path, function() openDirectory( finderWindow.pathbar.text, finderWindow) end)!@#&      local pathGo = OSButton:new(43,1, \"Go\", function() pathbar:submit() end)!@#&      pathGo.BackgroundColour = colours.white!@#&     pathGo.DisabledTextColour = colours.lightGrey!@#&       pathGo.DisabledBackgroundColour = colours.white!@#&!@#&     !@#&        filesList = OSListView:new(17, 4, 32, 11, {})!@#&       !@#&        !@#&        finderWindow = OSWindow:new(OSFileSystem.getName(path), {!@#&           toolbar,!@#&            backButton,!@#&         buttonsSplitter,!@#&            forwardButton,!@#&          pathbar,!@#&            pathGo,!@#&         placesListView,!@#&         filesList,!@#&          splitter!@#&            !@#&        }, width, height, environment)!@#&      !@#&        finderWindow.minHeight = 10!@#&     finderWindow.minWidth = 25!@#&      finderWindow.toolbar = toolbar!@#&      finderWindow.pathbar = pathbar!@#&      finderWindow.pathGo = pathGo!@#&        finderWindow.splitter = splitter!@#&        finderWindow.backButton = backButton!@#&        finderWindow.fileList = filesList!@#&       finderWindow.placesListView = placesListView!@#&        finderWindow.backHistory = {}!@#&       finderWindow.forwardHistory = {}!@#&        !@#&        !@#&        id = id + 1!@#&     windows['finder'..id] = finderWindow!@#&        openDirectory(path, finderWindow, false, false)!@#& end!@#& !@#&    !@#&    !@#&    handleItem = function(path, window)!@#&     if OSFileSystem.isDirectory(path) then!@#&          -- add a slash if missing!@#&           if string.sub(path, #path) ~= \"/\" then!@#&                path = path .. \"/\"!@#&            end!@#&         openDirectory(path, window)!@#&     else!@#&            openFile(path)!@#&      end!@#& end!@#& !@#&    openFile = function(path)!@#&       OSFileSystem.openFile(path)!@#& end!@#& !@#&    openDirectory = function(path, window, addToHistory, update)!@#&        --[[if addToHistory == nil then!@#&         addToHistory = true!@#&     end]]--!@#&     if update == nil then!@#&           update = true!@#&       end!@#&     addToHistory = addToHistory or true!@#&     if OSFileSystem.exists(path) then!@#&           window.title = OSFileSystem.getName(path)!@#&           if addToHistory then!@#&                --add the old path to history!@#&               table.insert(window.backHistory, window.pathbar.text)!@#&           end!@#&         updateHistoryButtons(window)!@#&            window.pathbar.text = path!@#&          !@#&            !@#&            !@#&            window.fileList.items = {}!@#&          for _,file in  pairs(OSFileSystem.list(path)) do!@#&                --check if the file has a full stop in front (hide it if showhidden is false)!@#&               if string.sub(file,1,1) == \".\" then!@#&               else!@#&                    table.insert(window.fileList.items, !@#&                        OSListItem:new(file, function() handleItem(path..file, window) end)!@#&                 )!@#&               end!@#&         end!@#&         !@#&            if update then!@#&              OSUpdate()!@#&          end!@#&     end!@#& end !@#&    !@#&    updateHistoryButtons = function(window)!@#&     window.backButton.enabled = #window.backHistory > 0!@#& end!@#& !@#&    !@#&    goBack = function(window)!@#&       openDirectory(window.backHistory[#window.backHistory], window, false)!@#&       table.remove(window.backHistory, # window.backHistory)!@#&      updateHistoryButtons(window)!@#&    end !@#&    !@#&    windowShouldClose = function(window)!@#&        return true!@#& end!@#& !@#&    windowDidResize = function(window, _width, _height)!@#&     if window == windows['about'] or window == windows['aboutSystem'] then!@#&          return!@#&      end!@#&     window.toolbar.width = _width!@#&       !@#&        window.pathbar.width = _width - 17!@#&      !@#&        window.pathGo.x = window.pathbar.x + window.pathbar.width + 1!@#&       window.splitter.height = _height-2!@#&      window.fileList.height = _height-2!@#&      window.fileList.width = _width - 17!@#&     window.placesListView.height = _height - 2!@#&  end!@#& !@#&    !@#&    ",},["TextEdit.app"]={["icon_l"]="c44444                                           !@#&c47774                                           !@#&c44444                                           !@#&c44444                                           !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 ",["icon"]="c44                                              !@#&c44                                              !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 ",["TextEdit"]="  menus = {}!@#&  windows = {}!@#&    version = \"1\"!@#& id = 0!@#&  !@#&    init = function()!@#&       local filemenuItems = {!@#&             OSMenuItem:new(\"New\", function() newWindow(\"\") end,  \"N\"),!@#&                OSMenuItem:new(\"Open\", nil)!@#&           }!@#&       local filemenu = OSMenu:new(1, 1, \"File\", filemenuItems)!@#&      !@#&            local editmenuItems = {!@#&             OSMenuItem:new(\"Copy\", nil)!@#&           }!@#&       local editmenu = OSMenu:new(1, 1, \"Edit\", editmenuItems)!@#&      !@#&            menus = {filemenu, editmenu}!@#&            OSExtensionAssociations.register(\"txt\", path)!@#&         OSExtensionAssociations.register(\"\", path)!@#&            OSExtensionAssociations.register(\"lua\", path)!@#&         newWindow(\"Home/Documents/Test.txt\")!@#&  end!@#& !@#&    about = function()!@#&      local aboutWindow = OSWindow:new(\"About \"..name, {!@#&        OSImageView:new(7, 1, path..\"/icon_l\"),!@#&       OSLabel:new(7, 6, name),!@#&        !@#&        OSLabel:new(5, 11, \"Version \"..version)!@#&       }, 20,12, environment)!@#&      windows['about'] = aboutWindow!@#&  end !@#&    !@#&    newWindow = function(_path)!@#&     local window = nil!@#&      local name = \"Untitled\"!@#&       local text = \"\"!@#&       if path then!@#&            name = OSFileSystem.getName(_path)!@#&          if OSFileSystem.exists(_path) then!@#&              text = readFile(_path)!@#&          end!@#&     end!@#&     !@#&        local textView = OSTextView:new(2,1, 29, 14, text)!@#&      !@#&        window = OSWindow:new(name, {!@#&           textView!@#&        }, 30, 14, environment)!@#&     !@#&        id = id + 1!@#&     window.textView = textView!@#&      window.text = textView.text!@#&     window.path = _path!@#&     windows['window'..id] = window!@#&  end!@#& !@#&    readFile = function(_path)!@#&      local file = fs.open(_path, \"r\")!@#&      if file then!@#&            local content = file.readAll()!@#&          file.close()    !@#&            return content!@#&      else!@#&            return \"\"!@#&     end!@#& end!@#& !@#&    saveFile = function(_path, _content)!@#&        local file = fs.open( _path, \"w\" )!@#&        if file then!@#&            file.write(_content)!@#&            file.close()!@#&        else!@#&            error( \"Failed to open \".._path )!@#&     end!@#&     return true!@#& end!@#& !@#&    openFile = function(_path)!@#&      newWindow(_path)!@#&    end!@#& !@#&    windowShouldClose = function(window)!@#&        saveFile(window.path, window.textView.text)!@#&     return true!@#& end!@#& !@#&    windowDidResize = function(window, _width, _height)!@#&     window.textView.width = _width - 1!@#&      window.textView.height = _height!@#&        window.textView:calculateWrapping()!@#& end",},},},["Home"]={["Documents"]={["Test.txt"]="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras consectetur consectetur lacus in mattis. Curabitur ultrices aliquet massa. Suspendisse tortor tellus, pellentesque et sollicitudin vitae, vestibulum eget lectus. Mauris in odio sit amet massa ultricies pellentesque.",},["Desktop"]={["Open Me.txt"]="The desktop is something I will add, but I haven't had the time to do so.!@#&Just be patient.!@#&!@#&- oeed",},["Pictures"]={},},["Startup"]="sides = {!@#&\"front\",!@#&\"back\",!@#&\"left\",!@#&\"right\",!@#&\"top\",!@#&\"bottom\"!@#&}!@#&!@#&function recieveStartupKey(delay)!@#&  os.startTimer(delay)!@#&    while true do!@#&     local event, arg = os.pullEvent()!@#&   if event=='timer' then !@#&       return nil!@#&    elseif event == \"key\" or event == \"char\" then!@#&     return arg !@#&   end!@#&     !@#&  end!@#&end!@#&!@#&function redstonePulse(side, time)!@#&        redstone.setOutput( side, true )!@#&        sleep(time)!@#&        redstone.setOutput( side, false )!@#&end!@#&!@#&!@#&!@#&function PrintCentered(text, y)!@#&    local w, h = term.getSize()!@#&    x = math.ceil(math.ceil((w / 2) - (#text / 2)), 0)+1!@#&    term.setCursorPos(x, y)!@#&    print(text)!@#&end!@#&!@#&function verbosePrint(message)!@#&    if verbose then!@#&     print(message)!@#&      sleep(0.1)!@#&  end!@#&end!@#&!@#&function displaySystemNoSupport()!@#& --add a message saying that the display has been moved to monitor!@#&   screensizex, screensizey = term.getSize()!@#&   line = screensizey/2-2!@#&  PrintCentered(\"This computer is not supported.\",line)!@#& line = line + 1!@#& PrintCentered(\"------------------------------\",line)!@#&  line = line + 2!@#& PrintCentered(\"PearOS requires an 'Advanced Computer' to run.\",line)!@#&  line = line + 1!@#& PrintCentered(\"Use an Advanced Computer and try again.\",line)!@#& line = line + 3!@#&!@#& PrintCentered(\"Press any key to restore CraftOS\", line)!@#&   os.pullEventRaw()!@#&   term.setBackgroundColor(colours.black)!@#&  term.setTextColor(colours.white)!@#&    term.clear()!@#&    term.setCursorPos(1,1)!@#&  print(os.version())!@#&end!@#&!@#&function displayMovedMessage()!@#&--add a message saying that the display has been moved to monitor!@#&term.setBackgroundColor(colors.lightGray)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&local line = 7!@#&PrintCentered(\"To use this screen (not the monitor)\",line)!@#&line = line + 1!@#&PrintCentered(\"------------------------------\",line)!@#&line = line + 2!@#&PrintCentered(\"1. Reboot (Hold Ctrl + R)\",line)!@#&line = line + 1!@#&PrintCentered(\"2. Hold 'M' while the computer starts.\",line)!@#&line = line + 1!@#&PrintCentered(\"OR\",line)!@#&line = line + 1!@#&PrintCentered(\"Open the P Menu and click 'Switch Screen'\", line)!@#&end!@#&!@#&!@#&term.setBackgroundColor(colors.white)!@#&term.setTextColor(colors.black)!@#&term.clear()!@#&!@#&--check if the computer is supported!@#&if not term.isColor() then!@#&    displaySystemNoSupport()!@#&    return nil!@#&end!@#&!@#&--detect if any boot modifier keys are pressed or the system should has a boot argument!@#&verbose = false!@#&craftos = false!@#&useMonitor = true!@#&!@#&os.loadAPI('System/Library/Frameworks/Services/OSTableIO')!@#&!@#&local key = nil!@#&if fs.exists(\"Settings\") then!@#&local settings = OSTableIO.load(\"Settings\")!@#&if #settings['boot_arg'] > 0 then!@#&   key = settings['boot_arg']!@#&  settings['boot_arg'] = \"\"!@#& OSTableIO.save(settings, \"Settings\")!@#&else!@#&  key = recieveStartupKey(1)!@#&end!@#&end!@#&!@#&if(key == 47) then -- the v key!@#& verbose = true --boot in verbose mode!@#&elseif(key == 46 or key == \"craftos\") then -- the c key!@#&  craftos = true --boot in craftos mode!@#&elseif(key == 50) then -- the m key!@#&    useMonitor = false --boot in resume (craftos) mode!@#&end!@#&!@#&if craftos then!@#&term.setBackgroundColor(colors.black)!@#&term.setTextColor(colors.yellow)!@#&term.clear()!@#&term.setCursorPos(1,1)!@#&print(os.version() .. \" (Opened via PearOS)\")!@#&return nil!@#&end!@#&!@#&if verbose then!@#&    term.setCursorPos(1, 1)!@#&   term.setBackgroundColor(colors.black)!@#&   term.setTextColor(colors.white)!@#& term.clear()!@#&    print(\"Booting in verbose mode...\")!@#&end!@#&!@#&!@#&!@#&!@#&!@#&!@#&usingMonitor = false!@#&if useMonitor then!@#&!@#&--find a monitor if there is one and use it!@#&verbosePrint(\"Searching for monitors...\")!@#&for _,side in pairs(sides) do!@#&   if peripheral.isPresent(side) and peripheral.getType(side) == \"monitor\" then!@#&      verbosePrint(\"Using monitor on \"..side..\" side.\")!@#&       displayMovedMessage()!@#&       term.redirect(peripheral.wrap(side))!@#&        usingMonitor = true!@#& else!@#&    end!@#&end!@#&!@#&end!@#&!@#&if not usingMonitor then!@#&   verbosePrint(\"No monitors found, using computer screen.\")!@#&end!@#&!@#&verbosePrint(\"Searching for peripherals...\")!@#&local peripheralsFound = 0!@#&for _,side in pairs(sides) do!@#& if peripheral.isPresent(side) then!@#&      local type = peripheral.getType(side)!@#&       verbosePrint(\"Peripheral of type '\"..type..\"' found on \"..side..\" side.\")!@#&     peripheralsFound = peripheralsFound + 1!@#& else!@#&    end!@#&end!@#&!@#&verbosePrint(peripheralsFound..\" peripherals found.\")!@#&!@#&!@#&!@#&!@#&--draw the 'pear' logo if not verbose mode!@#&verbosePrint(\"Found 0 monitors, using console.\")!@#&!@#&!@#&!@#&verbosePrint(\"Startup check complete, sending pulse to bottom redstone wire.\")!@#&!@#&redstonePulse(\"bottom\",0.1)!@#&verbosePrint(\"To continue with system boot enter 'exit', you can also enter shell commands.\")!@#&!@#&local wait = verbose!@#&!@#&while wait do!@#&  term.write(\"$ \")!@#&  local command = io.read()!@#&   if command == \"exit\" then!@#&     print(\"Starting PearOS...\")!@#&       wait = false!@#&    else!@#&--      commands = split(\"hello , \" \")!@#&       result = shell.run(command)!@#& end!@#&!@#&end!@#&!@#&!@#&!@#&  term.setBackgroundColor(colors.white)!@#&   term.setTextColor(colors.lightGray)!@#& term.clear()!@#&    logo = paintutils.loadImage(\"System/Library/Interface/PearLogo\")!@#&  local logox, logoy = term.getSize()!@#& paintutils.drawImage(logo,logox/2-3,logoy/2-3)!@#&!@#&  shell.run(\"System/PearOS.lua\")!@#&!@#&!@#&if verbose then!@#&    term.scroll(1)!@#&    term.setTextColor(colors.black)!@#&    text = \"Starting PearOS in verbose (debug) mode.\"!@#&    local screensizex, screensizey = term.getSize()!@#&    PrintCentered(text,screensizey/2+6)!@#&    sleep(1)!@#&    init()!@#&else!@#&--Crash/Error Handling!@#&!@#&!@#&local ok, err = pcall(init)!@#&!@#&if not ok then!@#&  --an error has occurred, display a warning message!@#&  !@#&    term.setBackgroundColor(colors.gray)!@#&    term.setTextColor(colors.white)!@#& term.clear()!@#&    PrintCentered(\"Oh noes!\",7)!@#&   PrintCentered(\"PearOS or a running application has crashed.\",9)!@#&   PrintCentered(\"Click anywhere or press any key to reboot.\",10)!@#&    --PrintCentered(\"For help hold 'H' while booting.\",11)!@#&    PrintCentered(\"For a more detailed error hold 'V' while booting.\",12)!@#&!@#& PrintCentered(\"The crash error message was:\",14)!@#&  term.setTextColor(colours.lightGrey)!@#&    term.setCursorPos(2,16)!@#& print(err)!@#&  os.pullEvent()!@#&  os.reboot()!@#&end!@#& !@#&end",["PkgMake"]="sPackage = \"local pkg = %@1 local function makeFile(_path, _content) local file = fs.open(_path, \\\"w\\\") _content = _content:gsub(\\\"\\!@\\\"..\\\"#&\\\", \\\"%\\\\n\\\") _content = textutils.unserialize(_content) file.write(_content) file.close() end local function makeFolder(_path, _content) fs.makeDir(_path) for k,v in pairs(_content) do if type(v) == \\\"table\\\" then makeFolder(_path .. \\\"/\\\" .. k, v) else makeFile(_path .. \\\"/\\\" .. k, v) end end end local sDest = shell.resolve( \\\"%@2\\\" ) or \\\"/\\\" if sDest == \\\"root\\\" then sDest = \\\"/\\\" end local tPackage = pkg makeFolder(sDest, tPackage) print(\\\"Package Extracted to '\\\" .. sDest .. \\\"'!\\\")\"!@#&!@#&function addFile(_package, _path)!@#& if fs.getName(_path) == \".DS_Store\" then!@#&      return _package!@#& end!@#& local file, err = fs.open(_path, \"r\")!@#& local content = file.readAll()!@#&  content = content:gsub(\"%\\n\", \"\\!@\"..\"#&\")!@#&  content = content:gsub(\"%%\", \"%%%%\")!@#&    _package[fs.getName(_path)] = content!@#&   file.close()!@#&    print(\"Added file '\".._path..\"'\")!@#&   return _package!@#&end!@#&!@#&function addFolder(_package, _path)!@#&   if string.sub(_path,1,string.len(\"rom\"))==\"rom\" or string.sub(_path,1,string.len(\"/rom\"))==\"/rom\" then!@#&      print(\"Ignored 'rom' folder. (\".._path..\")\")!@#&        return!@#&  end!@#& _package = _package or {}!@#&   for _,f in ipairs(fs.list(_path)) do!@#&        local path = _path..\"/\"..f!@#&        if fs.isDir(path) then!@#&          _package[fs.getName(f)] = addFolder(_package[fs.getName(f)], path)!@#&      else!@#&            _package =  addFile(_package, path)!@#&     end!@#& end!@#& return _package!@#&end!@#&!@#&local tArgs = { ... }!@#&if #tArgs < 2 then!@#&   print( \"Usage: PkgMake <source> <destination>\" )!@#&  return!@#&end!@#&!@#&local sSource = shell.resolve( tArgs[1] )!@#&local sDest = shell.resolve( tArgs[2] )!@#&!@#&if fs.isDir( sDest ) then!@#&  error(\"Destination must not be a folder.\")!@#&end!@#&!@#&if sSource == sDest then!@#& error(\"Source can not be equal to destination.\")!@#&end!@#&!@#&if fs.exists( sSource ) and fs.isDir( sSource ) then!@#&   tPackage = {}!@#&   tPackage = addFolder(tPackage, sSource)!@#& fPackage = fs.open(sDest,\"w\")!@#&!@#& sPackage = string.gsub(sPackage, \"%%@2\", fs.getName(sSource))!@#& sPackage = string.gsub(sPackage, \"%%@1\", textutils.serialize(tPackage))!@#&   fPackage.write(sPackage)!@#&    fPackage.close()!@#&    print(\"Package Done! ('\" .. sDest .. \"')\")!@#&  print(\"Type '\" .. sDest .. \"' to run it.\")!@#&else!@#&  error(\"Source does not exist or is not a folder.\")!@#&end",} local function makeFile(_path, _content) local file = fs.open(_path, "w") _content = _content:gsub("!@".."#&", "%\n") _content = textutils.unserialize(_content) file.write(_content) file.close() end local function makeFolder(_path, _content) fs.makeDir(_path) for k,v in pairs(_content) do if type(v) == "table" then makeFolder(_path .. "/" .. k, v) else makeFile(_path .. "/" .. k, v) end end end local sDest = shell.resolve( "root" ) or "/" if sDest == "root" then sDest = "/" end local tPackage = pkg makeFolder(sDest, tPackage) print("Package Extracted to '" .. sDest .. "'!") print("Rebooting in 1 second...") sleep(1) os.reboot()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement