// Generated by CoffeeScript 1.8.0

/*
@class Dialog
@description The Dialog object - used to invoke dialogs
 */

(function() {
  var _Dialog;

  _Dialog = (function() {
    function _Dialog() {}


    /*
    @method alert
    @description Display an alert dialog
    @param title|required|string|The main dialog title
    @param info|optional|string|Related information
    @param callback|optional|function|The function to be called, when the dialog closes
    @example $Dialog.alert("Finished!","The operation has finished")
     */

    _Dialog.prototype.alert = function(title, info, callback) {
      var event;
      if (info == null) {
        info = "";
      }
      if (callback != null) {
        event = pp.events.set("callback", null, callback);
      } else {
        event = null;
      }
      return core.dialogAlert_info_callback_(title, info, event);
    };


    /*
    @method input
    @description Show an input dialog and get user input
    @param title|required|string|The title/prompt of the dialog
    @param callback|required|function|The function to be called, with the input, when the dialog closes
    @return null|
    @example $Dialog.input("Enter a number:", (number)=>
    @example    $Terminal.echo("Got : #{ number }");    
    @example );
     */

    _Dialog.prototype.input = function(title, callback) {
      var event;
      event = pp.events.set("callback", null, callback);
      return core.dialogInput_callback_(title, event);
    };


    /*
    @method slider
    @description Show an input dialog with a slider and get user input
    @param title|required|string|The title/prompt of the dialog
    @param min|required|number|The minimum value
    @param max|required|number|The maximum value
    @param current|required|number|The current value
    @param ticks|required|number|Number of ticks to be displayed
    @param callback|required|function|The function to be called, with the input, when the dialog closes
    @return null|
    @example $Dialog.slider("Enter a value (0-20):", 0, 20, 10, 11, (number)=>
    @example    $Terminal.echo("Got : #{ number }");    
    @example );
     */

    _Dialog.prototype.slider = function(title, min, max, current, ticks, callback) {
      var event;
      event = pp.events.set("callback", null, callback);
      return core.dialogSlider_min_max_current_ticks_callback_(title, min, max, current, ticks, event);
    };


    /*
    @method radio
    @description Show an input dialog with radio buttons
    @param title|required|string|The title/prompt of the dialog
    @param values|required|array|An array with the possible values
    @param callback|required|function|The function to be called, with the input, when the dialog closes
    @return null|
    @example $Dialog.radio("Enter a value", ["one", "two", "three"], (input)=>
    @example    $Terminal.echo("Got : #{ input }");    
    @example );
     */

    _Dialog.prototype.radio = function(title, values, callback) {
      var event;
      event = pp.events.set("callback", null, callback);
      return core.dialogRadio_values_callback_(title, JSON.stringify(values), event);
    };


    /*
    @method combo
    @description Show an input dialog with a combo button/list
    @param title|required|string|The title/prompt of the dialog
    @param values|required|array|An array with the possible values for the dropdown/autocompletion list
    @param callback|required|function|The function to be called, with the input, when the dialog closes
    @return null|
    @example $Dialog.combo("Enter a value", ["one", "two", "three"], (input)=>
    @example    $Terminal.echo("Got : #{ input }");    
    @example );
     */

    _Dialog.prototype.combo = function(title, values, callback) {
      var event;
      event = pp.events.set("callback", null, callback);
      return core.dialogCombo_values_callback_(title, JSON.stringify(values), event);
    };


    /*
    @method file
    @description Show an open dialog for files
    @param multiple|required|boolean|Allows multiple selection
    @param callback|required|function|The function to be called, with the array of selected file paths
    @return null|
    @example $Dialog.file(true,(paths)=>
    @example    paths = JSON.parse(paths);
    @example    $Terminal.echo("First file : #{ paths[0] }");    
    @example );
     */

    _Dialog.prototype.file = function(multiple, callback) {
      var event;
      if (multiple == null) {
        multiple = false;
      }
      event = pp.events.set("callback", null, callback);
      return core.dialogFileMultiple_callback_(multiple, event);
    };


    /*
    @method folder
    @description Show an open dialog for folders
    @param multiple|required|boolean|Allows multiple selection
    @param callback|required|function|The function to be called, with the array of selected folder paths
    @return null|
    @example $Dialog.folder(true,(paths)=>
    @example    paths = JSON.parse(paths);
    @example    $Terminal.echo("First folder : #{ paths[0] }");    
    @example );
     */

    _Dialog.prototype.folder = function(multiple, callback) {
      var event;
      if (multiple == null) {
        multiple = false;
      }
      event = pp.events.set("callback", null, callback);
      return core.dialogFolderMultiple_callback_(multiple, event);
    };

    return _Dialog;

  })();

  if (!this._Dialog) {
    this._Dialog = _Dialog;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Document
@description The current Document object
@property label|string|The document's label as seen in Peppermint
@property path|string|The full path of the document
@property filename|string|The document's pure filename
@property folder|string|The document's pure folder name
@property extension|string|The document's file extension
 */

(function() {
  var _Document;

  _Document = (function() {
    function _Document() {
      this.content = null;
    }


    /*
    @method write
    @description Create or update document with contents
    @param path|required|string|The document's absolute path
    @param content|required|string|The document's contents
    @example $Document.write("/some/path/to/doc.js", "console.log('done');");
     */

    _Document.prototype.write = function(path, content) {
      return core.documentWriteToPath_withContents_(path, content);
    };


    /*
    @method info
    @description Get/Update Info of current document and/or create a temporary copy for processing
    @param ext|optional|string|Force a particular extension (if document is to be created)
    @return Document|A copy of the updated Document object, with all its properties populated
    @example path = $Document.info().path
     */

    _Document.prototype.info = function(extension) {
      if (extension == null) {
        extension = "tmp";
      }
      if ((this.content == null) || pp.editor.getContent() !== this.content || core.getDocumentFilename() !== this.label) {
        this.content = pp.editor.getContent();
        this.label = core.getDocumentFilename();
        this.path = core.getDocumentPath();
        if (this.path === "") {
          this.path = core.getDocumentTmpWithContent_withExtension_(this.content, extension);
        }
        this.filename = this.path.replace(/^.*[\\\/]/, '');
        this.folder = this.path.replace(this.filename, '');
        this.extension = /(?:\.([^.]+))?$/.exec(this.filename)[1];
      }
      return this;
    };


    /*
    @method temp
    @description Create temporary document instance with contents
    @param content|required|string|The document's content
    @param extension|optional|string|The document's extension
    @param filename|optional|string|The document's filename
    @return Document|A Document object, with all its properties populated
    @example temp = $Document.temp("my contents");
    @example path = temp.path;
     */

    _Document.prototype.temp = function(content, extension, filename) {
      if (extension == null) {
        extension = "tmp";
      }
      if (filename == null) {
        filename = null;
      }
      if (filename != null) {
        this.path = core.getDocumentTmpWithContent_withExtension_filename_(content, extension, filename);
      } else {
        this.path = core.getDocumentTmpWithContent_withExtension_(content, extension);
      }
      this.content = content;
      this.filename = this.path.replace(/^.*[\\\/]/, '');
      this.label = this.filename;
      this.folder = this.path.replace(this.filename, '');
      this.extension = /(?:\.([^.]+))?$/.exec(this.filename)[1];
      return this;
    };

    return _Document;

  })();

  if (!this._Document) {
    this._Document = _Document;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Editor
@description The main Event-handling object
 */

(function() {
  var _Editor;

  _Editor = (function() {
    function _Editor() {}


    /*
    @method bind
    @description Create or Destroy and editor Key Binding
    @param key|required|string|Key combination
    @param callback|optional|function|Callback on key combination (null to destroy)
    @return null|
    @example $Editor.bind("Cmd+R", ()=>
    @example    $Terminal.echo("Running");
    @example );
     */

    _Editor.prototype.bind = function(key, callback) {
      if (callback == null) {
        callback = null;
      }
      return pp.editor.commands.bindKey(key, callback);
    };


    /*
    @method content
    @description Get/Set editor content
    @param value|optional|string|New editor content
    @param undoable|optional|boolean|Set if change will be undoable (default: true)
    @return null or string|The content of the editor
    @example currentContent = $Editor.content();
    @example 
    @example # Let's change it 
    @example $Editor.content("New content");
     */

    _Editor.prototype.content = function(value, undoable) {
      if (undoable == null) {
        undoable = true;
      }
      if (value != null) {
        return pp.editor.setContent(value, undoable);
      } else {
        return pp.editor.getContent();
      }
    };


    /*
    @method selection
    @description Get/Set current editor selection
    @param value|optional|string|Replace current selection with value
    @return null or string|The currently selected text
    @example currentContent = $Editor.content();
    @example 
    @example # Let's change it 
    @example $Editor.content("New content");
     */

    _Editor.prototype.selection = function(value) {
      if (value != null) {
        return pp.editor.setSelection(value);
      } else {
        return pp.editor.getSelection();
      }
    };


    /*
    @method clipboard
    @description Get/Set current clipboard contents
    @param value|optional|string|If set, it assigns the argument to the Clipboard
    @return null or string|The current Clipboard content
    @example currentClipboard = $Editor.clipboard();
    @example
    @example # Let's re-assign it
    @example $Editor.clipboard("new content");
     */

    _Editor.prototype.clipboard = function(value) {
      if (value != null) {
        return core.setClipboard_(value);
      } else {
        return core.getClipboard();
      }
    };

    _Editor.prototype.option = {

      /*
      @method option.gutter
      @description Get/Set Gutter state
      @param onoff|optional|boolean|True/False
      @return null or boolean|
       */
      gutter: function(onoff) {
        if (onoff != null) {
          return pp.toggleGutter(onoff);
        } else {
          return pp.editor.instance.renderer.getShowGutter();
        }
      },

      /*
      @method option.printMargin
      @description Get/Set Print Margin state
      @param onoff|optional|boolean|True/False
      @return null or boolean|
       */
      printMargin: function(onoff) {
        if (onoff != null) {
          return pp.togglePrintMargin(onoff);
        } else {
          return pp.editor.instance.getShowPrintMargin();
        }
      },

      /*
      @method option.indentGuides
      @description Get/Set Indentation Guides state
      @param onoff|optional|boolean|True/False
      @return null or boolean|
       */
      indentGuides: function(onoff) {
        if (onoff != null) {
          return pp.toggleIndentationGuides(onoff);
        } else {
          return pp.editor.instance.renderer.getDisplayIndentGuides();
        }
      },

      /*
      @method option.invisibles
      @description Get/Set Invisibles state
      @param onoff|optional|boolean|True/False
      @return null or boolean|
       */
      invisibles: function(onoff) {
        if (onoff != null) {
          return pp.toggleInvisibles(onoff);
        } else {
          return pp.editor.instance.getShowInvisibles();
        }
      },

      /*
      @method option.softTabs
      @description Get/Set Soft Tabs state
      @param onoff|optional|boolean|True/False
      @return null or boolean|
       */
      softTabs: function(onoff) {
        if (onoff != null) {
          return pp.toggleSoftTabs(onoff);
        } else {
          return pp.editor.instance.getUseSoftTabs();
        }
      },

      /*
      @method option.wordWrap
      @description Get/Set Word Wrap state
      @param onoff|optional|boolean|True/False
      @return null or boolean|
       */
      wordWrap: function(onoff) {
        if (onoff != null) {
          return pp.toggleWordWrap(onoff);
        } else {
          return pp.editor.instance.getSession().getUseWrapMode();
        }
      },

      /*
      @method option.tabSize
      @description Get/Set Tab Size
      @param size|optional|number|Tab size in characters
      @return null or number|
       */
      tabSize: function(size) {
        if (size != null) {
          return pp.setTabSize(size);
        } else {
          return pp.editor.instance.getSession().getTabSize();
        }
      },

      /*
      @method option.wrapLimit
      @description Get/Set Wrap Limit
      @param size|optional|number|Wrap Limit in characters
      @return null or number|
       */
      wrapLimit: function(limit) {
        if (limit != null) {
          return pp.setWrapLimit(limit);
        } else {
          return pp.editor.instance.getSession().getWrapLimitRange().min;
        }
      }
    };


    /*
    @method annotate
    @description Set annotations
    @param annotations|optional|array|Set annotations (column,row,text,type=info|warning|error)
    @return null|
    @example $Editor.annotate([{column:0, row:3, text:"This is an error", type:"error"}]);
     */

    _Editor.prototype.annotate = function(annotations) {
      if (annotations == null) {
        annotations = null;
      }
      pp.editor.instance.getSession().clearAnnotations();
      if (annotations != null) {
        return pp.editor.instance.getSession().setAnnotations(annotations);
      }
    };

    return _Editor;

  })();

  if (!this._Editor) {
    this._Editor = _Editor;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Fs
@description The global File System object
 */

(function() {
  var _Fs;

  _Fs = (function() {
    function _Fs() {}


    /*
    @method fileExists
    @description Check if path exists
    @param path|required|string|The path to check
    @return boolean|True or False
    @example fileExists = $Fs.fileExists("/some/path/to/some/file.txt");
     */

    _Fs.prototype.fileExists = function(path) {
      return core.fsFileExists_(path);
    };


    /*
    @method isFolder
    @description Check if file at path is a folder
    @param path|required|string|The path to check
    @return boolean|True or False
    @example isFolder = $Fs.isFolder("/some/path/to/some/file");
     */

    _Fs.prototype.isFolder = function(path) {
      return core.fsIsFolder_(path);
    };


    /*
    @method fileSize
    @description Get file size for file at path
    @param path|required|string|The path to check
    @return number|Path's file size in bytes
    @example fileSize = $Fs.fileSize("/some/path/to/some/file.txt");
     */

    _Fs.prototype.fileSize = function(path) {
      return core.fsFileSize_(path);
    };


    /*
    @method pathContents
    @description Get contents for path (if folder)
    @param path|required|string|The path to check
    @return array|Array of content paths
    @example pathContents = $Fs.pathContents("/some/path/to/some/folder");
     */

    _Fs.prototype.pathContents = function(path) {
      return core.fsPathContents_(path);
    };


    /*
    @method fileContents
    @description Get contents of file at path
    @param path|required|string|The path to check
    @return string|The contents
    @example fileContents = $Fs.fileContents("/some/path/to/some/file.txt");
     */

    _Fs.prototype.fileContents = function(path) {
      return core.fsFileContents_(path);
    };


    /*
    @method createFolder
    @description Create folder at path
    @param path|required|string|The folder path to be created
    @return null|
    @example $Fs.createFolder("/some/path/to/some/folder");
     */

    _Fs.prototype.createFolder = function(path) {
      return core.fsCreateFolder_(path);
    };


    /*
    @method fileCopy
    @description Copy file at path to new path
    @param path|required|string|The original path
    @param destination|required|string|The destination path
    @return null|
    @example $Fs.fileCopy("/some/path/to/some/file.txt","/another/path/to/some/file.txt");
     */

    _Fs.prototype.fileCopy = function(path, dest) {
      return core.fsFileCopy_to_(path, dest);
    };


    /*
    @method fileMove
    @description Move file at path to new path
    @param path|required|string|The original path
    @param destination|required|string|The destination path
    @return null|
    @example $Fs.fileMove("/some/path/to/some/file.txt","/another/path/to/some/file.txt");
     */

    _Fs.prototype.fileMove = function(path, dest) {
      return core.fsFileMove_to_(path, dest);
    };


    /*
    @method fileRename
    @description Rename file at path to new path
    @param path|required|string|The original path
    @param destination|required|string|The destination path
    @return null|
    @example $Fs.fileRename("/some/path/to/some/file.txt","/another/path/to/some/file.txt");
     */

    _Fs.prototype.fileRename = function(path, dest) {
      return core.fsFileRename_to_(path, dest);
    };


    /*
    @method fileDelete
    @description Delete file at path
    @param path|required|string|The file path to be deleted
    @return null|
    @example $Fs.fileDelete("/some/path/to/some/file.txt");
     */

    _Fs.prototype.fileDelete = function(path) {
      return core.fsFileDelete_(path);
    };

    return _Fs;

  })();

  if (!this._Fs) {
    this._Fs = _Fs;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Net
@description The global Net object
 */

(function() {
  var _Net;

  _Net = (function() {
    function _Net() {}


    /*
    @method get
    @description Execute a GET request and receive results
    @param url|required|string|The url to request
    @param callback|required|function|Called when the request returns, along with the results
    @return null|
    @example $Net.get("http://www.google.com", (result)=>
    @example    $Terminal.echo("Got: #{ result }");
    @example );
     */

    _Net.prototype.get = function(url, callback) {
      $.get(url, (function(_this) {
        return function(result) {
          return callback(result);
        };
      })(this));
      return null;
    };


    /*
    @method post
    @description Execute a POST request and receive results
    @param url|required|string|The url to request
    @param data|required|object|The data to be passed as a dictionary/object
    @param callback|required|function|Called when the request returns, along with the results
    @return null|
    @example $Net.post("http://www.mywebsite.com/somescript.php", { "name":"drkameleon" }, (result)=>
    @example    $Terminal.echo("Got: #{ result }");
    @example );
     */

    _Net.prototype.post = function(url, data, callback) {
      $.post(url, data, (function(_this) {
        return function(result) {
          return callback(result);
        };
      })(this));
      return null;
    };

    return _Net;

  })();

  if (!this._Net) {
    this._Net = _Net;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class On
@description The main Event-handling object
 */

(function() {
  var _On;

  _On = (function() {
    function _On(id) {
      this.uniqueId = id;
    }


    /*
    @method documentChanged
    @description Set callback to be executed, when document changes
    @param callback|required|function|The callback to be executed, or null to remove handler
    @return null|
    @example init: ()->
    @example    $$x = 1;
    @example    $$on.documentChanged(()=>
    @example        $Terminal.echo("Document changed");
    @example        $Terminal.echo("x = " + $$x++);
    @example    );
    @example  
    @example halt: ()->
    @example    $$on.documentChanged(null);
     */

    _On.prototype.documentChanged = function(callback) {
      pp.events.set("documentChanged", this.uniqueId, callback);
      return null;
    };


    /*
    @method documentSaved
    @description Set callback to be executed, when document is saved
    @param callback|required|function|The callback to be executed, or null to remove handler
    @return null|
    @example $$on.documentSaved(()=>
    @example    # do something
    @example )
     */

    _On.prototype.documentSaved = function(callback) {
      pp.events.set("documentSaved", this.uniqueId, callback);
      return null;
    };


    /*
    @method cursorChanged
    @description Set callback to be executed, when document changes
    @param callback|required|function|The callback to be executed, or null to remove handler
    @return null|
    @example $$on.cursorChanged(()=>
    @example    # do something
    @example )
     */

    _On.prototype.cursorChanged = function(callback) {
      pp.events.set("cursorChanged", this.uniqueId, callback);
      return null;
    };

    return _On;

  })();

  if (!this._On) {
    this._On = _On;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Preview
@description The main Preview object - representing the Preview Panel on the right side of the Peppermint window
 */

(function() {
  var _Preview;

  _Preview = (function() {
    function _Preview() {}


    /*
    @method load
    @description Load html tool in the Preview View
    @param title|required|string|The new title for the Preview View
    @param source|required|string|Path to the .html file to be loaded or html source
    @param base|optional|string|Base path to be used
    @return null|
    @example $Preview.load("My great tool", "#{ @path }/index.html")
     */

    _Preview.prototype.load = function(title, source, base) {
      if (base == null) {
        base = null;
      }
      return core.previewLoadHtmlWithTitle_source_base_(title, source, base);
    };


    /*
    @method loadPage
    @description Load web page in the Preview View
    @param title|required|string|The new title for the Preview View
    @param url|required|string|The webpage URL
    @return null|
    @example $Preview.loadPage("Google Search", "http://www.google.com")
     */

    _Preview.prototype.loadPage = function(title, url) {
      return core.previewLoadPage_withUrl_(title, url);
    };


    /*
    @method loadDocument
    @description Load custom document in the Preview View
    @param title|required|string|The new title for the Preview View
    @param content|required|string|The script's contents
    @param spec|required|string|The spec to be used for highlighting
    @return null|
    @example $Preview.loadDocument("My PHP Script", "<?php echo 'done'; ?>", "php")
     */

    _Preview.prototype.loadDocument = function(title, content, spec) {
      return core.previewLoadDocumentWithTitle_content_spec_(title, content, spec);
    };

    _Preview.prototype.invoke = function(code) {
      return core.previewInvoke_(code);
    };

    return _Preview;

  })();

  if (!this._Preview) {
    this._Preview = _Preview;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Terminal
@description The main Terminal object - representing the console panel
@property verbose|boolean|Display more info <i>(Default: false)</i>
 */

(function() {
  var _Terminal,
    __slice = [].slice;

  _Terminal = (function() {
    function _Terminal() {
      this.environment = {};
      this.verbose = false;
    }


    /*
    @method show
    @description Show the terminal panel, if not already open
    @return null|
    @example $Terminal.show()
     */

    _Terminal.prototype.show = function() {
      pp.layout.toggleConsole(true);
      return null;
    };


    /*
    @method clear
    @description Clear the terminal panel
    @return null|
    @example $Terminal.clear()
     */

    _Terminal.prototype.clear = function() {
      pp.terminal.emulator.clear();
      return null;
    };


    /*
    @method echo
    @description Echoes given string to the terminal
    @param message|required|string|The message to be displayed
    @param attributes|optional|string|A style attribute string
    @return null|
    @example $Terminal.echo("Hello world!")
     */

    _Terminal.prototype.echo = function(msg, attributes) {
      var error;
      this.show();
      if (attributes != null) {
        msg = "[[" + attributes + "]" + msg + "]";
      }
      try {
        if (typeof msg === 'object') {
          msg = eval(msg);
          msg = pp.utils.inspect(msg);
        }
        pp.terminal.emulator.echo(msg);
      } catch (_error) {
        error = _error;
        $Terminal.echo("Error : " + (error.toString()));
      }
      return null;
    };

    _Terminal.prototype.execPattern = function() {
      var args, func, funcs, output, pattern, _i, _len;
      pattern = arguments[0], output = arguments[1], funcs = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
      args = pp.utils.parsePattern(pattern, output);
      for (_i = 0, _len = funcs.length; _i < _len; _i++) {
        func = funcs[_i];
        args.push(func);
      }
      return this.exec.apply(this, args);
    };


    /*
    @method exec
    @description Asynchronously execute task and print output in terminal
    @param args|required|string...|Command/Arguments to be passed
    @param completed|optional|callback|Callback to be executed when task is completed
    @return string|The execution result
    @example $Terminal.exec("php","--version")
     */

    _Terminal.prototype.exec = function() {
      var arg, args, completed, outp, _i, _len;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      if (this.verbose) {
        outp = "";
        for (_i = 0, _len = args.length; _i < _len; _i++) {
          arg = args[_i];
          if (typeof arg !== 'function') {
            outp += arg + " ";
          }
        }
        $Terminal.echo("# " + outp);
      }
      if (typeof args[args.length - 1] === 'function') {
        completed = args[args.length - 1];
        args.pop();
      } else {
        completed = null;
      }
      args.push((function(_this) {
        return function(output) {
          if (output.trim() !== "") {
            return $Terminal.echo(output);
          }
        };
      })(this));
      if (completed != null) {
        args.push(completed);
      }
      return this.execSilent.apply(this, args);
    };


    /*
    @method execSilent
    @description Execute command in terminal (either synchronously, or async)
    @param args|required|string...|Command/Arguments to be passed
    @param action|optional|callback|Callback to be executed when any data is served
    @param completed|optional|callback|Callback to be executed when task is completed
    @return string|The execution result
    @example $Terminal.execSilent("php","--version")
    @example
    @example # This is pretty much like `$Terminal.exec()`
    @example $Terminal.execSilent("php","myscript.php", (output)=>
    @example    $Terminal.echo("Got output: #{ output }");
    @example ,(result)=>
    @example    $Terminal.echo("Task terminated!");
    @example );
     */

    _Terminal.prototype.execSilent = function() {
      var action, args, completed;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      action = null;
      completed = null;
      if (typeof args[args.length - 2] === 'function') {
        action = pp.events.set("callback", null, args[args.length - 2]);
        completed = pp.events.set("callback", null, args[args.length - 1]);
        args.pop();
        args.pop();
      } else {
        if (typeof args[args.length - 1] === 'function') {
          action = pp.events.set("callback", null, args[args.length - 1]);
          args.pop();
        }
      }
      args = JSON.stringify(args);
      if (action !== null || completed !== null) {
        pp.terminal.setStdinMode(true);
      }
      if (Object.keys(this.environment).length) {
        return core.terminalExec_env_action_completed_(args, JSON.stringify(this.environment), action, completed);
      } else {
        return core.terminalExec_env_action_completed_(args, "", action, completed);
      }
    };


    /*
    @method execBg
    @description Execute command in terminal (either synchronously, or async) in the background
    @param args|required|string...|Command/Arguments to be passed
    @param action|optional|callback|Callback to be executed when any data is served
    @param completed|optional|callback|Callback to be executed when task is completed
    @return string|The execution result
    @example $Terminal.execSilent("php","--version")
    @example
    @example # This is pretty much like `$Terminal.exec()`
    @example $Terminal.execSilent("php","myscript.php", (output)=>
    @example    $Terminal.echo("Got output: #{ output }");
    @example ,(result)=>
    @example    $Terminal.echo("Task terminated!");
    @example );
     */

    _Terminal.prototype.execBg = function() {
      var action, args, completed;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      action = null;
      completed = null;
      if (typeof args[args.length - 2] === 'function') {
        action = pp.events.set("callback", null, args[args.length - 2]);
        completed = pp.events.set("callback", null, args[args.length - 1]);
        args.pop();
        args.pop();
      } else {
        if (typeof args[args.length - 1] === 'function') {
          action = pp.events.set("callback", null, args[args.length - 1]);
          args.pop();
        }
      }
      args = JSON.stringify(args);
      if (Object.keys(this.environment).length) {
        return core.terminalBgExec_env_action_completed_(args, JSON.stringify(this.environment), action, completed);
      } else {
        return core.terminalBgExec_env_action_completed_(args, "", action, completed);
      }
    };


    /*
    @method setVar
    @description Set custom environment variable
    @param variable|required|string|The name of the variable
    @param value|required|string|The value of the variable
    @return null|
    @example $Terminal.setVar("MYVAR","VALUE");
     */

    _Terminal.prototype.setVar = function(variable, value) {
      return this.environment[variable] = value;
    };

    _Terminal.prototype.write = function(msg) {
      return core.terminalWrite_(msg);
    };


    /*
    @method kill
    @description Kill existing async process being executed
    @return null|
    @example $Terminal.kill();
     */

    _Terminal.prototype.kill = function() {
      return core.terminalKill();
    };

    return _Terminal;

  })();

  if (!this._Terminal) {
    this._Terminal = _Terminal;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Utility
@description The main Utility object - with various utility functions
 */

(function() {
  var _Utility;

  _Utility = (function() {
    function _Utility() {}


    /*
    @method openLink
    @description Open a link in the browser
    @return null|
    @example $Utility.openLink("http://www.osxpeppermint.com");
     */

    _Utility.prototype.openLink = function(url) {
      return core.openLink_(url);
    };


    /*
    @method showFile
    @description Show a file in Finder
    @return null|
    @example $Utility.showFile("/some/path/to/some/file.txt");
     */

    _Utility.prototype.showFile = function(url) {
      return core.showFile_(url);
    };

    return _Utility;

  })();

  if (!this._Utility) {
    this._Utility = _Utility;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Workspace
@description The global Workspace object
@property files|array|Array of single files within the Workspace
@property projects|array|Array of projects within the Workspace
@property currentProject|string or boolean|Path to current/active project, or false
 */

(function() {
  var _Workspace;

  _Workspace = (function() {
    function _Workspace() {
      this.files = [];
      this.projects = [];
    }


    /*
    @method info
    @description Get info of current workspace
    @return Workspace|A copy of the updated Workspace object, with all its properties populated
    @example currentProjects = $Workspace.info().projects
     */

    _Workspace.prototype.info = function() {
      this.files = core.getWorkspaceFiles();
      this.projects = core.getWorkspaceProjects();
      this.currentProject = core.getWorkspaceCurrentProject();
      if (this.currentProject === "") {
        this.currentProject = false;
      }
      return this;
    };

    return _Workspace;

  })();

  if (!this._Workspace) {
    this._Workspace = _Workspace;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Builtin
@description The main Inheritable Builtin class
@property name|string|The plugin's name as defined in the <code>info.json</code>
@property path|string|The plugin's folder path
@property on|On|An associated <a href='#api-class-on'>On</a> Object for event handling
 */

(function() {
  var __Builtin;

  __Builtin = (function() {
    function __Builtin(name, path) {
      this.name = name;
      this.path = path;
      this.bin = pp.binaries;
      this.env = JSON.parse(core.getEnv());
      this.scheduler = null;
      this.on = new _On(this.name);
    }


    /*
    @method init
    @description Called automatically when plugin is initialized the first time
    @return null|
    @example class MyBuiltin extends $Builtin
    @example    init:->
    @example        $Terminal.echo("Builtin initialised!");
     */

    __Builtin.prototype.init = function() {};


    /*
    @method run
    @description Placeholder for the Run routine to be executed on every cycle
    @return null|
    @example class MyBuiltin extends $Builtin
    @example    init:->
    @example        $Terminal.echo("Builtin initialised!");
    @example    
    @example    run:->
    @example        $Terminal.echo("Plugin is running!");
     */

    __Builtin.prototype.run = function() {};


    /*
    @method halt
    @description Called automatically when plugin is terminated, or another plugin is executed
    @return null|
    @example class MyBuiltin extends $Builtin
    @example    init:->
    @example        $Terminal.echo("Builtin initialised!");
    @example    
    @example    halt:->
    @example        $Terminal.echo("Builtin is being terminated...");
     */

    __Builtin.prototype.halt = function() {};


    /*
    @method startRun
    @description Schedule Run execution every x milliseconds
    @param interval|required|number|Interval to execute Run
    @param runAtOnce|optional|boolean|Set whether it should be executed from the very beginning
    @return null|
    @example class MyBuiltin extends $Builtin
    @example    init:->
    @example        @startRun(1000); # Run every 1000ms
    @example    
    @example    run:->
    @example        $Terminal.echo("Running...");
     */

    __Builtin.prototype.startRun = function(interval, runAtOnce) {
      if (runAtOnce == null) {
        runAtOnce = false;
      }
      if (runAtOnce) {
        this.run();
      }
      return this.scheduler = window.setInterval(this.run, interval);
    };


    /*
    @method stopRun
    @description Stop Run execution - Automatically called on Halt
    @return null|
    @example class MyBuiltin extends $Builtin
    @example    init:->
    @example        @scheduleRun(1000); # Run every 1000ms
    @example    
    @example    halt:->
    @example        @stopRun();
     */

    __Builtin.prototype.stopRun = function() {
      return window.clearInterval(this.scheduler);
    };


    /*
    @method import
    @description Import a local file's contents
    @param path|required|string|The path to the file
    @param relative|option|boolean|Is the path relative to the builtin folder? (default: true)
    @return string|The file contents
     */

    __Builtin.prototype["import"] = function(path, relative) {
      if (relative == null) {
        relative = true;
      }
      if (relative) {
        path = this.path + "/" + path;
      }
      return core.import_(path);
    };


    /*
    @method include
    @description Include a local script file (JavaScript or CoffeeScript) and execute it in global scope
    @param path|required|string|The path to the file
    @param relative|option|boolean|Is the path relative to the builtin folder? (default: true)
    @return string|The file contents
     */

    __Builtin.prototype.include = function(path, relative) {
      if (relative == null) {
        relative = true;
      }
      if (relative) {
        path = this.path + "/" + path;
      }
      return core.include_(path);
    };

    __Builtin.prototype.load_ = function(name, path, source) {
      var builtin;
      if (typeof code === 'object') {
        source = eval(code)[0];
      }
      pp.utils.coffee("" + source + "\n\nwindow." + name + " = " + name + ";", false, true);
      builtin = new window[name](name, path);
      pp.builtins.push(builtin);
      return builtin.init();
    };

    __Builtin.prototype.halt_ = function() {
      this.stopRun();
      this.halt();
      pp.events.removeById(this.name);
      return window[this.name] = null;
    };

    __Builtin.prototype.run_ = function(name, path, source) {
      if (window[name] == null) {
        this.load_(name, path, source);
      }
      return this.run();
    };

    return __Builtin;

  })();

  if (!this.__Builtin) {
    this.__Builtin = __Builtin;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
  var __Editor;

  __Editor = (function() {
    function __Editor(container) {
      this.langtools = ace.require("ace/ext/language_tools");
      this.snippets = ace.require("ace/snippets").snippetManager;
      this.tokeniter = ace.require("ace/token_iterator").TokenIterator;
      this.splitter = ace.require("ace/split").Split;
      this.range = ace.require("ace/range").Range;
      this.tooltip = ace.require("ace/tooltip").Tooltip;
      this.event = ace.require("ace/lib/event");
      this.dom = ace.require("ace/lib/dom");
      this.tokenTooltip = ace.require("ace/token_tooltip").TokenTooltip;
      this.oldSnippets = {};
      this.splitViews = null;
      this.scopeMarker = null;
      this.container = container;
      this.instance = ace.edit(this.container);
      this.instance.setTheme("ace/theme/peppermint");
              this.instance.getSession().setMode("ace/mode/json");
      this.instance.setOptions({
        enableBasicAutocompletion: true,
        enableLiveAutocompletion: true,
        enableSnippets: true,
        enableEmmet: true,
        animatedScroll: true
      });
      this.instance.$blockScrolling = Infinity;
      if (window.PREVIEW == null) {
        this.setupEvents();
        this.setupKeyBindings();
      }
      this.documentStates = {};
      return this;
    }

    __Editor.prototype.setupEvents = function() {
      this.instance.session.on("change", (function(_this) {
        return function() {
          return pp.events.exec("documentChanged");
        };
      })(this));
      this.instance.selection.on("changeCursor", (function(_this) {
        return function() {
          var cursor;
          cursor = _this.instance.selection.getCursor();
          pp.events.exec("cursorChanged");
          if (typeof core === "undefined" || core === null) {
            return console.log(cursor);
          } else {
            return core.currentLocationChanged_("Line " + (cursor.row + 1) + ", Column " + (cursor.column + 1));
          }
        };
      })(this));
      this.instance.on("guttermousedown", (function(_this) {
        return function(e) {
          var row, target;
          target = e.domEvent.target;
          if (target.className.indexOf("ace_gutter-cell") === -1 || !_this.instance.isFocused() || e.clientX > 25 + target.getBoundingClientRect().left) {
            return;
          }
          row = e.getDocumentPosition().row;
          if (_this.instance.session.$breakpoints[row] !== 'ace_breakpoint') {
            _this.bookmarkLine(row);
          } else {
            _this.unbookmarkLine(row);
          }
          return e.stop();
        };
      })(this));
      this.instance.renderer.$gutter.addEventListener("mouseover", (function(_this) {
        return function(e) {
          var line, range, target;
          target = e.target;
          if (target.classList.contains("ace_fold-widget")) {
            line = parseInt($(e.target).parent().text()) - 1;
            range = _this.instance.getSession().getFoldWidgetRange(line);
          } else if ($(target).find(".ace_fold-widget").length) {
            console.log("Target has fold-widget");
            line = parseInt($(target).text()) - 1;
            range = _this.instance.getSession().getFoldWidgetRange(line);
          } else {
            range = null;
          }
          if (_this.scopeMarker) {
            _this.instance.session.removeMarker(_this.scopeMarker);
          }
          return _this.scopeMarker = range && _this.instance.session.addMarker(range, "ace_scope", "fullLine");
        };
      })(this));
      return this.instance.renderer.$gutter.addEventListener("mouseout", (function(_this) {
        return function() {
          _this.instance.session.removeMarker(_this.scopeMarker);
          return _this.scopeMarker = null;
        };
      })(this));

      /*
      $(".ace_fold-widget").hover(
          (event)=>
              line = parseInt($(this).parent().text())-1;
              console.log("Hover at line: #{ line }");
              r = pp.editor.instance.getSession().getFoldWidgetRange( parseInt($(this).parent().text())-1 );
              @marker = pp.editor.instance.session.addMarker(new pp.editor.range(r.start.row,0,r.end.row,0), ".ace_scope-highlight", "fullLine");
          ,
          (event)=>
              console.log("Clearing hover");
              pp.editor.instance.session.removeMarker(@marker);
      );
       */
    };

    __Editor.prototype.unbindKey = function(key) {
      return this.instance.commands.bindKey(key, null);
    };

    __Editor.prototype.setupKeyBindings = function() {
      this.unbindKey("Cmd-N");
      this.unbindKey("Cmd-O");
      this.unbindKey("Cmd-S");
      this.unbindKey("Cmd-Shift-S");
      this.unbindKey("Cmd-P");
      this.unbindKey("Cmd-Z");
      this.unbindKey("Cmd-Shift-Z");
      this.unbindKey("Cmd-X");
      this.unbindKey("Cmd-C");
      this.unbindKey("Cmd-V");
      this.unbindKey("Cmd-Shift-W");
      this.unbindKey("Cmd-Shift-L");
      this.unbindKey("Cmd-]");
      this.unbindKey("Cmd-[");
      this.unbindKey("Ctrl-C");
      this.unbindKey("Cmd-A");
      this.unbindKey("Cmd-Shift-A");
      this.unbindKey("Cmd-F");
      this.unbindKey("Cmd-G");
      this.unbindKey("Cmd-Shift-G");
      this.unbindKey("Alt-Shift-F");
      this.unbindKey("Ctrl-Shift-F");
      this.unbindKey("Cmd-E");
      this.unbindKey("Ctrl-Cmd-S");
      this.unbindKey("Ctrl-Cmd-T");
      this.unbindKey("Ctrl-Cmd-B");
      this.unbindKey("Ctrl-Cmd-P");
      this.unbindKey("Ctrl-Cmd-U");
      this.unbindKey("Ctrl-Cmd-G");
      this.unbindKey("Ctrl-Cmd-M");
      this.unbindKey("Ctrl-Cmd-I");
      this.unbindKey("Ctrl-Cmd-V");
      this.unbindKey("Ctrl-Cmd-W");
      this.unbindKey("Cmd-=");
      this.unbindKey("Cmd--");
      this.unbindKey("Ctrl-G");
      this.unbindKey("Ctrl-B");
      this.unbindKey("Ctrl-Shift-B");
      this.unbindKey("Cmd-R");
      this.unbindKey("Cmd-Shift-R");
      this.unbindKey("Cmd-M");
      this.unbindKey("Cmd-,");
      return this.unbindKey("Cmd-Q");
    };

    __Editor.prototype.setCSSTheme = function(name, dark, source, forceReload) {
      if (forceReload == null) {
        forceReload = true;
      }
      this.registerTheme(name, dark, source);
      if (forceReload) {
        delete ace.define.modules("ace/theme/" + name);
      }
      return this.setTheme(name);
    };

    __Editor.prototype.registerTheme = function(name, dark, source) {
      if (dark == null) {
        dark = 1;
      }
      return ace.define("ace/theme/" + name, ["require", "exports", "module", "ace/lib/dom"], (function(_this) {
        return function(e, t, n) {
          t.isDark = 1;
          t.cssClass = "ace-" + name;
          t.cssText = source;
          return _this.dom.importCssString(t.cssText, t.cssClass);
        };
      })(this));
    };

    __Editor.prototype.toggleTokenInfo = function(onoff) {
      if (onoff) {
        return this.tokenInfo = new this.tokenTooltip(this.instance);
      } else {
        if (this.tokenInfo != null) {
          this.tokenInfo.destroy();
          return delete this.tokenInfo;
        }
      }
    };

    __Editor.prototype.getSnippets = function() {};

    __Editor.prototype.splitView = function(onoff) {
      var nofSplits;
      if (onoff == null) {
        onoff = true;
      }
      if (onoff) {
        nofSplits = 2;
      } else {
        nofSplits = 1;
      }
      return this.splitViews = new this.splitter(document.getElementById("editor"), this.getMode(), nofSplits);
    };

    __Editor.prototype.currentInstance = function() {
      if (this.splitViews != null) {
        return this.splitViews.getCurrentEditor();
      } else {
        return this.instance;
      }
    };

    __Editor.prototype.tokenize = function(excludeText) {
      var iterator, result, token;
      if (excludeText == null) {
        excludeText = ["text"];
      }
      result = [];
      iterator = new this.tokeniter(this.instance.getSession(), 0, 0);
      token = iterator.getCurrentToken();
      while (token) {
        if (excludeText.length === 0 || (excludeText.length > 0 && excludeText.indexOf(token.type) === -1)) {
          result.push({
            t: token.type,
            v: token.value,
            p: iterator.getCurrentTokenRow()
          });
        }
        token = iterator.stepForward();
      }
      return result;
    };

    __Editor.prototype.setSnippets = function(snippets, mode) {
      var parsed;
      if (this.oldSnippets[mode] != null) {
        this.snippets.unregister(this.oldSnippets[mode], mode);
      }
      parsed = this.snippets.parseSnippetFile(snippets);
      this.snippets.register(parsed, mode);
      return this.oldSnippets[mode] = parsed;
    };

    __Editor.prototype.setContent = function(content, undoable) {
      if (undoable == null) {
        undoable = false;
      }
      if (typeof content === 'object') {
        content = eval(content)[0];
      }
      if (!undoable) {
        return this.instance.getSession().setValue(content);
      } else {
        return this.instance.getSession().setValueUndoable(content);
      }
    };

    __Editor.prototype.getContent = function() {
      return this.instance.getSession().getValue();
    };

    __Editor.prototype.setSelection = function(replacement) {
      return this.instance.getSession().replace(this.instance.getSelectionRange(), replacement);
    };

    __Editor.prototype.getSelection = function() {
      return this.instance.session.getTextRange(this.instance.getSelectionRange());
    };

    __Editor.prototype.setMode = function(mode) {
      if (typeof core !== "undefined" && core !== null) {
        core.modeChanged_(mode);
      }
      return this.instance.getSession().setMode("ace/mode/" + mode);
    };

    __Editor.prototype.getMode = function() {
      return this.instance.getSession().getMode().$id.replace("ace/mode/", "");
    };

    __Editor.prototype.setFont = function(name) {
      return this.instance.setOption('fontFamily', name);
    };

    __Editor.prototype.documentStateChanged = function() {
      return core.currentDocumentChanged();
    };

    __Editor.prototype.attachChangeListener = function() {
      if (window.PREVIEW == null) {
        return this.instance.session.on("change", this.documentStateChanged);
      }
    };

    __Editor.prototype.removeChangeListener = function() {
      return this.instance.getSession().removeListener('change', this.documentStateChanged);
    };

    __Editor.prototype.setDocument = function(doc, docpointer) {
      var e, i, indices, state, _i, _ref;
      try {
        this.setContent(doc.content);
        this.setMode(doc.spec);
        this.instance.setReadOnly(doc.readonly);
        this.attachChangeListener();
        if (this.documentStates[docpointer] != null) {
          state = this.documentStates[docpointer];
          this.instance.getSession().addFolds(state.folds);
          indices = [];
          for (i = _i = 0, _ref = state.breakpoints.length; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
            if (state.breakpoints[i] === 'ace_breakpoint') {
              indices.push(i);
            }
          }
          this.instance.getSession().setBreakpoints(indices);
          this.instance.getSession().setAnnotations(state.annotations);
          this.instance.getSession().getUndoManager().$undoStack = state.undo;
          this.instance.getSession().getUndoManager().$redoStack = state.redo;
          this.instance.getSession().selection.setRange(state.selection);
          this.instance.getSession().setScrollTop(state.viewport.scrollTop);
        }
        return this.instance.focus();
      } catch (_error) {
        e = _error;
        return core.catchError_(e.message);
      }
    };

    __Editor.prototype.getDocument = function(docpointer) {
      this.documentStates[docpointer] = {
        folds: this.instance.getSession().getAllFolds(),
        breakpoints: this.instance.getSession().getBreakpoints(),
        annotations: this.instance.getSession().getAnnotations(),
        undo: this.instance.getSession().getUndoManager().$undoStack,
        redo: this.instance.getSession().getUndoManager().$redoStack,
        selection: this.instance.getSession().selection.getRange(),
        viewport: {
          scrollTop: this.instance.getSession().getScrollTop(),
          firstRow: this.instance.renderer.getFirstVisibleRow(),
          position: this.instance.getCursorPosition()
        }
      };
      this.removeChangeListener();
      return JSON.stringify({
        content: this.getContent(),
        mode: this.getMode()
      });
    };

    __Editor.prototype.replaceIndexes = function(start, end, what) {
      var endRowColumn, startRowColumn;
      startRowColumn = this.getRowColumnIndices(start);
      endRowColumn = this.getRowColumnIndices(end);
      return this.instance.getSession().replace(new this.range(startRowColumn.row, startRowColumn.column, endRowColumn.row, endRowColumn.column), what);
    };

    __Editor.prototype.selectByIndexes = function(start, end, reverse) {
      var endRowColumn, startRowColumn;
      startRowColumn = this.getRowColumnIndices(start);
      endRowColumn = this.getRowColumnIndices(end);
      return this.instance.session.selection.setSelectionRange({
        start: {
          row: startRowColumn.row,
          column: startRowColumn.column
        },
        end: {
          row: endRowColumn.row,
          column: endRowColumn.column
        }
      }, reverse);
    };

    __Editor.prototype.getLastColumnIndex = function(row) {
      return this.instance.session.getDocumentLastRowColumnPosition(row, 0).column;
    };

    __Editor.prototype.getLastColumnIndices = function() {
      var i, lastColIndex, lastColumnIndices, rows, _i;
      rows = this.instance.session.getLength();
      lastColumnIndices = [];
      lastColIndex = 0;
      for (i = _i = 0; 0 <= rows ? _i <= rows : _i >= rows; i = 0 <= rows ? ++_i : --_i) {
        lastColIndex += this.getLastColumnIndex(i);
        if (i > 0) {
          lastColIndex += 1;
        }
        lastColumnIndices[i] = lastColIndex;
      }
      return lastColumnIndices;
    };

    __Editor.prototype.getRowColumnIndices = function(characterIndex) {
      var column, i, lastColumnIndices, row, _i, _ref;
      lastColumnIndices = this.getLastColumnIndices();
      if (characterIndex <= lastColumnIndices[0]) {
        return {
          row: 0,
          column: characterIndex
        };
      }
      row = 1;
      for (i = _i = 1, _ref = lastColumnIndices.length; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
        if (characterIndex > lastColumnIndices[i]) {
          row = i + 1;
        }
      }
      column = characterIndex - lastColumnIndices[row - 1] - 1;
      return {
        row: row,
        column: column
      };
    };

    __Editor.prototype.scrollToIndex = function(index) {
      return this.goToLine(this.getRowColumnIndices(index).row);
    };

    __Editor.prototype.getCursorLocation = function() {
      var col, index, lastColumnIndices, row, selRange;
      selRange = this.instance.selection.getRange().start;
      col = selRange.column;
      row = selRange.row;
      lastColumnIndices = this.getLastColumnIndices();
      index = col;
      if (row - 1 >= 0) {
        index += lastColumnIndices[row - 1] + 1;
      }
      return index;
    };

    __Editor.prototype.undo = function() {
      return this.instance.undo();
    };

    __Editor.prototype.redo = function() {
      return this.instance.redo();
    };

    __Editor.prototype.canUndo = function() {
      return this.instance.getSession().getUndoManager().$undoStack.length > 0;
    };

    __Editor.prototype.canRedo = function() {
      return this.instance.getSession().getUndoManager().$redoStack.length > 0;
    };

    __Editor.prototype.selectWord = function() {
      return this.instance.selection.selectWord();
    };

    __Editor.prototype.selectLine = function() {
      return this.instance.selection.selectLine();
    };

    __Editor.prototype.selectLineEnd = function() {
      return this.instance.selection.selectLineEnd();
    };

    __Editor.prototype.selectLineStart = function() {
      return this.instance.selection.selectLineStart();
    };

    __Editor.prototype.selectFileEnd = function() {
      return this.instance.selection.selectFileEnd();
    };

    __Editor.prototype.selectFileStart = function() {
      return this.instance.selection.selectFileStart();
    };

    __Editor.prototype.selectAll = function() {
      return this.instance.selectAll();
    };

    __Editor.prototype.deselectAll = function() {
      return this.instance.clearSelection();
    };

    __Editor.prototype.indent = function() {
      return this.instance.blockIndent();
    };

    __Editor.prototype.outdent = function() {
      return this.instance.blockOutdent();
    };

    __Editor.prototype.moveUp = function() {
      return this.instance.moveLinesUp();
    };

    __Editor.prototype.moveDown = function() {
      return this.instance.moveLinesDown();
    };

    __Editor.prototype.toggleComment = function() {
      return this.instance.toggleCommentLines();
    };

    __Editor.prototype.find = function(what, regex, incase, whole) {
      var initialPos, ret, total;
      initialPos = this.instance.selection.getCursor();
      total = this.instance.findAll(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
      this.instance.moveCursorToPosition({
        column: initialPos.column,
        row: initialPos.row
      });
      this.instance.find(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
      ret = total > 0 ? "" + total + " matches found" : "No matches found";
      return ret;
    };

    __Editor.prototype.findNext = function() {
      return this.instance.findNext();
    };

    __Editor.prototype.findPrevious = function() {
      return this.instance.findPrevious();
    };

    __Editor.prototype.replace = function(what, regex, incase, whole) {
      return this.instance.replace(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
    };

    __Editor.prototype.replaceAll = function(what, regex, incase, whole) {
      return this.instance.replaceAll(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
    };

    __Editor.prototype.toggleGutter = function(onoff) {
      return this.instance.renderer.setShowGutter(onoff);
    };

    __Editor.prototype.togglePrintMargin = function(onoff) {
      return this.instance.setShowPrintMargin(onoff);
    };

    __Editor.prototype.toggleIndentationGuides = function(onoff) {
      return this.instance.renderer.setDisplayIndentGuides(onoff);
    };

    __Editor.prototype.toggleInvisibles = function(onoff) {
      return this.instance.setShowInvisibles(onoff);
    };

    __Editor.prototype.toggleSoftTabs = function(onoff) {
      return this.instance.getSession().setUseSoftTabs(onoff);
    };

    __Editor.prototype.toggleWordWrap = function(onoff) {
      return this.instance.getSession().setUseWrapMode(onoff);
    };

    __Editor.prototype.setTabSize = function(n) {
      return this.instance.getSession().setTabSize(n);
    };

    __Editor.prototype.setWrapLimit = function(n) {
      return this.instance.getSession().setWrapLimitRange(n, n);
    };

    __Editor.prototype.setNewLines = function(str) {
      return this.instance.getSession().setNewLineMode(str);
    };

    __Editor.prototype.setFontSize = function(n) {
      return $("#editor").css("font-size", "" + n + "px");
    };

    __Editor.prototype.setTheme = function(theme) {
      return this.instance.setTheme("ace/theme/" + theme);
    };

    __Editor.prototype.goToLine = function(line) {
      return this.instance.gotoLine(line);
    };

    __Editor.prototype.scrollPageUp = function() {
      return this.instance.scrollPageUp();
    };

    __Editor.prototype.scrollPageDown = function() {
      return this.instance.scrollPageDown();
    };

    __Editor.prototype.scrollToSelection = function() {
      return this.instance.renderer.scrollSelectionIntoView();
    };

    __Editor.prototype.bookmarkLine = function(line) {
      return this.instance.session.setBreakpoint(line, 'ace_breakpoint');
    };

    __Editor.prototype.bookmarkCurrent = function() {
      return this.bookmarkLine(this.instance.selection.getCursor().row);
    };

    __Editor.prototype.unbookmarkLine = function(line) {
      return this.instance.session.clearBreakpoint(line);
    };

    __Editor.prototype.unbookmarkCurrent = function() {
      return this.unbookmarkLine(this.instance.selection.getCursor().row);
    };

    __Editor.prototype.unbookmarkAll = function() {
      return this.instance.session.clearBreakpoints();
    };

    __Editor.prototype.foldAll = function() {
      return this.instance.getSession().foldAll();
    };

    __Editor.prototype.unfoldAll = function() {
      return this.instance.getSession().expandFolds(this.instance.getSession().getAllFolds());
    };

    __Editor.prototype.foldCurrent = function() {
      return this.instance.getSession().toggleFold(false);
    };

    __Editor.prototype.unfoldCurrent = function() {
      return this.instance.getSession().toggleFold(true);
    };

    return __Editor;

  })();

  if (!this.__Editor) {
    this.__Editor = __Editor;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
  var __Events;

  __Events = (function() {
    function __Events() {
      this.list = {
        documentChanged: {},
        documentSaved: {},
        cursorChanged: {},
        callback: {}
      };
    }

    __Events.prototype.exec = function(event, id, args) {
      var callback, eventId, _ref, _results;
      _ref = this.list[event];
      _results = [];
      for (eventId in _ref) {
        callback = _ref[eventId];
        if (id == null) {
          _results.push(callback(args));
        } else {
          if (id === eventId) {
            _results.push(callback(args));
          } else {
            _results.push(void 0);
          }
        }
      }
      return _results;
    };

    __Events.prototype.add = function(event, id, callback) {
      if (id == null) {
        id = pp.utils.uuid();
      }
      this.list[event][id] = callback;
      return "pp.events.exec('callback','" + id + "','%@')";
    };

    __Events.prototype.remove = function(event, id) {
      return delete this.list[event][id];
    };

    __Events.prototype.removeById = function(id) {
      var callback, content, event, eventId, _ref, _results;
      _ref = this.list;
      _results = [];
      for (event in _ref) {
        content = _ref[event];
        _results.push((function() {
          var _ref1, _results1;
          _ref1 = this.list[event];
          _results1 = [];
          for (eventId in _ref1) {
            callback = _ref1[eventId];
            if (id === eventId) {
              _results1.push(this.remove(event, id));
            } else {
              _results1.push(void 0);
            }
          }
          return _results1;
        }).call(this));
      }
      return _results;
    };

    __Events.prototype.set = function(event, id, callback) {
      if (callback != null) {
        return this.add(event, id, callback);
      } else {
        return this.remove(event, id, callback);
      }
    };

    return __Events;

  })();

  if (!this.__Events) {
    this.__Events = __Events;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
  var __Layout,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  __Layout = (function() {
    function __Layout() {
      this.resizeOnChange = __bind(this.resizeOnChange, this);
      this.options = {
        fxName: "none",
        fxSpeed: "fast",
        slidable: false,
        togglerLength_closed: 0,
        spacing_open: 6,
        spacing_closed: 0,
        onresize_start: this.resizeOnChange,
        onresize_end: this.resizeOnChange,
        "default": {
          onresize_start: this.resizeOnChange,
          onresize_end: this.resizeOnChange
        },
        panes: {
          liveContentResizing: true,
          livePaneResizing: true
        },
        east: {
          initClosed: false,
          initHidden: false,
          closable: false,
          resizable: true,
          spacing_open: 1,
          spacing_closed: 0
        },
        south: {
          initClosed: true,
          initHidden: true,
          closable: true,
          resizable: true,
          onresize_start: this.resizeOnChange,
          onresize_end: (function(_this) {
            return function() {
              _this.resizeOnChange();
              return $("#console-output").css("width", $("#console-input-group").css("width"));
            };
          })(this),
          onclose_end: (function(_this) {
            return function() {
              $("#console-trigger").removeClass("tactive");
              $("#console-trigger").css("background", "#777777");
              pp.terminal.emulator.resize();
              return core.consoleToggled_(false);
            };
          })(this),
          onopen_end: (function(_this) {
            return function() {
              $("#console-trigger").addClass("tactive");
              $("#console-trigger").css("background", "#007CF7");
              pp.terminal.emulator.resize();
              pp.editor.instance.blur();
              pp.terminal.emulator.focus();
              return core.consoleToggled_(true);
            };
          })(this),
          onhide_end: this.resizeOnChange,
          size: 110,
          minSize: 110,
          maxSize: $(window).height() - 150
        }
      };
      this.manager = $("body").layout(this.options);
      $(window).resize((function(_this) {
        return function() {
          _this.manager.south.options.maxSize = $(window).height() - 150;
          return _this.manager.resizeAll();
        };
      })(this));
      $("#console-trigger,[href='#console-tab']").click((function(_this) {
        return function() {
          if (!$("#console-trigger").hasClass("tactive")) {
            return _this.manager.open("south");
          } else {
            return _this.manager.close("south");
          }
        };
      })(this));
    }

    __Layout.prototype.resizeOnChange = function() {
      pp.editor.instance.resize();
      return pp.split.instance.resize();
    };

    __Layout.prototype.toggleConsole = function(onoff) {
      if (onoff) {
        return this.manager.show("south");
      } else {
        return this.manager.hide("south");
      }
    };

    return __Layout;

  })();

  if (!this.__Layout) {
    this.__Layout = __Layout;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
  var __Minimap;

  __Minimap = (function() {
    function __Minimap() {
      this.instance = ace.edit("mmeditor");
      this.instance.setTheme("ace/theme/peppermint");
      this.instance.renderer.setShowGutter(false);
      this.instance.setReadOnly(true);
      this.documentStates = {};
      return this;
    }

    __Minimap.prototype.setupEvents = function() {
      this.instance.session.on("change", (function(_this) {
        return function() {
          return pp.events.exec("documentChanged");
        };
      })(this));
      this.instance.selection.on("changeCursor", (function(_this) {
        return function() {
          var cursor;
          cursor = _this.instance.selection.getCursor();
          pp.events.exec("cursorChanged");
          if (typeof core === "undefined" || core === null) {
            return console.log(cursor);
          } else {
            return core.currentLocationChanged_("Line " + (cursor.row + 1) + ", Column " + (cursor.column + 1));
          }
        };
      })(this));
      return this.instance.on("guttermousedown", (function(_this) {
        return function(e) {
          var row, target;
          target = e.domEvent.target;
          if (target.className.indexOf("ace_gutter-cell") === -1 || !_this.instance.isFocused() || e.clientX > 25 + target.getBoundingClientRect().left) {
            return;
          }
          row = e.getDocumentPosition().row;
          if (_this.instance.session.$breakpoints[row] === 'ace_breakpoint') {
            $Actions.bookmarkLine(row);
          } else {
            $Actions.unbookmarkLine(row);
          }
          return e.stop();
        };
      })(this));
    };

    __Minimap.prototype.unbindKey = function(key) {
      return this.instance.commands.bindKey(key, null);
    };

    __Minimap.prototype.setupKeyBindings = function() {
      this.unbindKey("Cmd-N");
      this.unbindKey("Cmd-O");
      this.unbindKey("Cmd-S");
      this.unbindKey("Cmd-Shift-S");
      this.unbindKey("Cmd-P");
      this.unbindKey("Cmd-Z");
      this.unbindKey("Cmd-Shift-Z");
      this.unbindKey("Cmd-X");
      this.unbindKey("Cmd-C");
      this.unbindKey("Cmd-V");
      this.unbindKey("Cmd-Shift-W");
      this.unbindKey("Cmd-Shift-L");
      this.unbindKey("Cmd-]");
      this.unbindKey("Cmd-[");
      this.unbindKey("Ctrl-C");
      this.unbindKey("Cmd-A");
      this.unbindKey("Cmd-Shift-A");
      this.unbindKey("Cmd-F");
      this.unbindKey("Cmd-G");
      this.unbindKey("Cmd-Shift-G");
      this.unbindKey("Alt-Shift-F");
      this.unbindKey("Ctrl-Shift-F");
      this.unbindKey("Cmd-E");
      this.unbindKey("Ctrl-Cmd-S");
      this.unbindKey("Ctrl-Cmd-T");
      this.unbindKey("Ctrl-Cmd-B");
      this.unbindKey("Ctrl-Cmd-P");
      this.unbindKey("Ctrl-Cmd-U");
      this.unbindKey("Ctrl-Cmd-G");
      this.unbindKey("Ctrl-Cmd-M");
      this.unbindKey("Ctrl-Cmd-I");
      this.unbindKey("Ctrl-Cmd-V");
      this.unbindKey("Ctrl-Cmd-W");
      this.unbindKey("Cmd-=");
      this.unbindKey("Cmd--");
      this.unbindKey("Ctrl-G");
      this.unbindKey("Ctrl-B");
      this.unbindKey("Ctrl-Shift-B");
      this.unbindKey("Cmd-R");
      this.unbindKey("Cmd-Shift-R");
      this.unbindKey("Cmd-M");
      this.unbindKey("Cmd-,");
      return this.unbindKey("Cmd-Q");
    };

    __Minimap.prototype.setContent = function(content, undoable) {
      if (undoable == null) {
        undoable = false;
      }
      if (typeof content === 'object') {
        content = eval(content)[0];
      }
      if (!undoable) {
        return this.instance.getSession().setValue(content);
      } else {
        return this.instance.getSession().setValueUndoable(content);
      }
    };

    __Minimap.prototype.getContent = function() {
      return this.instance.getSession().getValue();
    };

    __Minimap.prototype.setSelection = function(replacement) {
      return this.instance.getSession().replace(this.instance.getSelectionRange(), replacement);
    };

    __Minimap.prototype.getSelection = function() {
      return this.instance.session.getTextRange(this.instance.getSelectionRange());
    };

    __Minimap.prototype.setMode = function(mode) {
      return this.instance.getSession().setMode("ace/mode/" + mode);
    };

    __Minimap.prototype.getMode = function() {
      return this.instance.getSession().getMode().$id.replace("ace/mode/", "");
    };

    __Minimap.prototype.setFont = function(name) {
      return this.instance.setOption('fontFamily', name);
    };

    __Minimap.prototype.documentStateChanged = function() {
      return core.currentDocumentChanged();
    };

    __Minimap.prototype.attachChangeListener = function() {
      if (window.PREVIEW == null) {
        return this.instance.session.on("change", this.documentStateChanged);
      }
    };

    __Minimap.prototype.removeChangeListener = function() {
      return this.instance.getSession().removeListener('change', this.documentStateChanged);
    };

    __Minimap.prototype.setDocument = function(doc, docpointer) {
      var e, i, indices, state, _i, _ref;
      try {
        this.setContent(doc.content);
        this.setMode(doc.spec);
        this.instance.setReadOnly(doc.readonly);
        this.attachChangeListener();
        if (this.documentStates[docpointer] != null) {
          state = this.documentStates[docpointer];
          this.instance.getSession().addFolds(state.folds);
          this.instance.getSession().selection.setRange(state.selection);
          indices = [];
          for (i = _i = 0, _ref = state.breakpoints.length; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
            if (state.breakpoints[i] === 'ace_breakpoint') {
              indices.push(i);
            }
          }
          this.instance.getSession().setBreakpoints(indices);
          this.instance.getSession().setAnnotations(state.annotations);
          this.instance.getSession().getUndoManager().$undoStack = state.undo;
          return this.instance.getSession().getUndoManager().$redoStack = state.redo;
        }
      } catch (_error) {
        e = _error;
        return core.catchError_(e.message);
      }
    };

    __Minimap.prototype.getDocument = function(docpointer) {
      this.documentStates[docpointer] = {
        folds: this.instance.getSession().getAllFolds(),
        selection: this.instance.getSession().selection.getRange(),
        breakpoints: this.instance.getSession().getBreakpoints(),
        annotations: this.instance.getSession().getAnnotations(),
        undo: this.instance.getSession().getUndoManager().$undoStack,
        redo: this.instance.getSession().getUndoManager().$redoStack
      };
      this.removeChangeListener();
      return JSON.stringify({
        content: this.getContent(),
        mode: this.getMode()
      });
    };

    __Minimap.prototype.undo = function() {
      return this.instance.undo();
    };

    __Minimap.prototype.redo = function() {
      return this.instance.redo();
    };

    __Minimap.prototype.canUndo = function() {
      return this.instance.getSession().getUndoManager().$undoStack.length > 0;
    };

    __Minimap.prototype.canRedo = function() {
      return this.instance.getSession().getUndoManager().$redoStack.length > 0;
    };

    __Minimap.prototype.selectWord = function() {
      return this.instance.selection.selectWord();
    };

    __Minimap.prototype.selectLine = function() {
      return this.instance.selection.selectLine();
    };

    __Minimap.prototype.selectLineEnd = function() {
      return this.instance.selection.selectLineEnd();
    };

    __Minimap.prototype.selectLineStart = function() {
      return this.instance.selection.selectLineStart();
    };

    __Minimap.prototype.selectFileEnd = function() {
      return this.instance.selection.selectFileEnd();
    };

    __Minimap.prototype.selectFileStart = function() {
      return this.instance.selection.selectFileStart();
    };

    __Minimap.prototype.selectAll = function() {
      return this.instance.selectAll();
    };

    __Minimap.prototype.deselectAll = function() {
      return this.instance.clearSelection();
    };

    __Minimap.prototype.indent = function() {
      return this.instance.blockIndent();
    };

    __Minimap.prototype.outdent = function() {
      return this.instance.blockOutdent();
    };

    __Minimap.prototype.moveUp = function() {
      return this.instance.moveLinesUp();
    };

    __Minimap.prototype.moveDown = function() {
      return this.instance.moveLinesDown();
    };

    __Minimap.prototype.toggleComment = function() {
      return this.instance.toggleCommentLines();
    };

    __Minimap.prototype.find = function(what, regex, incase, whole) {
      var initialPos, ret, total;
      initialPos = this.instance.selection.getCursor();
      total = this.instance.findAll(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
      this.instance.moveCursorToPosition({
        column: initialPos.column,
        row: initialPos.row
      });
      this.instance.find(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
      ret = total > 0 ? "" + total + " matches found" : "No matches found";
      return ret;
    };

    __Minimap.prototype.findNext = function() {
      return this.instance.findNext();
    };

    __Minimap.prototype.findPrevious = function() {
      return this.instance.findPrevious();
    };

    __Minimap.prototype.replace = function(what, regex, incase, whole) {
      return this.instance.replace(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
    };

    __Minimap.prototype.replaceAll = function(what, regex, incase, whole) {
      return this.instance.replaceAll(what, {
        backwards: false,
        wrap: true,
        regExp: regex,
        caseSensitive: incase,
        wholeWord: whole
      });
    };

    __Minimap.prototype.toggleGutter = function(onoff) {
      return this.instance.renderer.setShowGutter(onoff);
    };

    __Minimap.prototype.togglePrintMargin = function(onoff) {
      return this.instance.setShowPrintMargin(onoff);
    };

    __Minimap.prototype.toggleIndentationGuides = function(onoff) {
      return this.instance.renderer.setDisplayIndentGuides(onoff);
    };

    __Minimap.prototype.toggleInvisibles = function(onoff) {
      return this.instance.setShowInvisibles(onoff);
    };

    __Minimap.prototype.toggleSoftTabs = function(onoff) {
      return this.instance.getSession().setUseSoftTabs(onoff);
    };

    __Minimap.prototype.toggleWordWrap = function(onoff) {
      return this.instance.getSession().setUseWrapMode(onoff);
    };

    __Minimap.prototype.setTabSize = function(n) {
      return this.instance.getSession().setTabSize(n);
    };

    __Minimap.prototype.setWrapLimit = function(n) {
      return this.instance.getSession().setWrapLimitRange(n, n);
    };

    __Minimap.prototype.setFontSize = function(n) {
      return $("#mmeditor").css("font-size", "" + n + "px");
    };

    __Minimap.prototype.setTheme = function(theme) {
      return this.instance.setTheme("ace/theme/" + theme);
    };

    __Minimap.prototype.goToLine = function(line) {
      return this.instance.gotoLine(line);
    };

    __Minimap.prototype.scrollPageUp = function() {
      return this.instance.scrollPageUp();
    };

    __Minimap.prototype.scrollPageDown = function() {
      return this.instance.scrollPageDown();
    };

    __Minimap.prototype.scrollToSelection = function() {
      return this.instance.renderer.scrollSelectionIntoView();
    };

    __Minimap.prototype.bookmarkLine = function(line) {
      return this.instance.session.setBreakpoint(line, 'ace_breakpoint');
    };

    __Minimap.prototype.bookmarkCurrent = function() {
      return this.bookmarkLine(this.instance.selection.getCursor().row);
    };

    __Minimap.prototype.unbookmarkLine = function(line) {
      return this.instance.session.clearBreakpoint(line);
    };

    __Minimap.prototype.unbookmarkCurrent = function() {
      return this.unbookmarkLine(this.instance.selection.getCursor().row);
    };

    __Minimap.prototype.unbookmarkAll = function() {
      return this.instance.session.clearBreakpoint();
    };

    __Minimap.prototype.foldAll = function() {
      return this.instance.getSession().foldAll();
    };

    __Minimap.prototype.unfoldAll = function() {
      return this.instance.getSession().expandFolds(this.instance.getSession().getAllFolds());
    };

    __Minimap.prototype.foldCurrent = function() {
      return this.instance.getSession().toggleFold(false);
    };

    __Minimap.prototype.unfoldCurrent = function() {
      return this.instance.getSession().toggleFold(true);
    };

    return __Minimap;

  })();

  if (!this.__Minimap) {
    this.__Minimap = __Minimap;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0

/*
@class Plugin
@description The main Inheritable Plugin class
@property name|string|The plugin's name as defined in the <code>info.json</code>
@property path|string|The plugin's folder path
@property on|On|An associated <a href='#api-class-on'>On</a> Object for event handling
 */

(function() {
  var __Plugin;

  __Plugin = (function() {
    function __Plugin(name, path) {
      this.name = name;
      this.path = path;
      this.bin = pp.binaries;
      this.env = JSON.parse(core.getEnv());
      this.on = new _On(this.name);
    }


    /*
    @method init
    @description Called automatically when plugin is initialized the first time
    @return null|
    @example class MyPlugin extends $Plugin
    @example    init:->
    @example        $Terminal.echo("Plugin initialised!");
     */

    __Plugin.prototype.init = function() {};


    /*
    @method run
    @description Called every time the plugin is executed
    @return null|
    @example class MyPlugin extends $Plugin
    @example    init:->
    @example        $Terminal.echo("Plugin initialised!");
    @example    
    @example    run:->
    @example        $Terminal.echo("Plugin is running!");
     */

    __Plugin.prototype.run = function() {};


    /*
    @method menu
    @description Called automatically when plugin is initialized the first time
    @return object|A dictionary of menu items associated with the plugin (Menu Item =&gt; callback)
    @example class MyPlugin extends $Plugin
    @example    init:->
    @example        $Terminal.echo("Plugin initialised!");
    @example    
    @example    doSomething:(arg)->
    @example        $Terminal.echo("Doing something with #{ arg }");
    @example
    @example    menu:-> {
    @example        "First menu item"   :=> @doSomething("first")
    @example        "Second menu item"  :=> @doSomething("second")
    @example        "Third menu item"   :=> @doSomething("third")
    @example    }
     */

    __Plugin.prototype.menu = function() {
      return {};
    };


    /*
    @method halt
    @description Called automatically when plugin is terminated, or another plugin is executed
    @return null|
    @example class MyPlugin extends $Plugin
    @example    init:->
    @example        $Terminal.echo("Plugin initialised!");
    @example    
    @example    halt:->
    @example        $Terminal.echo("Plugin is being terminated...");
     */

    __Plugin.prototype.halt = function() {};


    /*
    @method import
    @description Import a local file's contents
    @param path|required|string|The path to the file
    @param relative|option|boolean|Is the path relative to the plugin folder? (default: true)
    @return string|The file contents
     */

    __Plugin.prototype["import"] = function(path, relative) {
      if (relative == null) {
        relative = true;
      }
      if (relative) {
        path = this.path + "/" + path;
      }
      return core.import_(path);
    };


    /*
    @method include
    @description Include a local script file (JavaScript or CoffeeScript) and execute it in global scope
    @param path|required|string|The path to the file
    @param relative|option|boolean|Is the path relative to the plugin folder? (default: true)
    @return string|The file contents
     */

    __Plugin.prototype.include = function(path, relative) {
      if (relative == null) {
        relative = true;
      }
      if (relative) {
        path = this.path + "/" + path;
      }
      return core.include_(path);
    };

    __Plugin.prototype.load_ = function(name, path, source, anyway, type) {
      var k, pl, v;
      if (anyway == null) {
        anyway = false;
      }
      if (type == null) {
        type = "coffee";
      }
      if (typeof code === 'object') {
        source = eval(code)[0];
      }
      if (type === "coffee") {
        if (!anyway) {
          pp.utils.coffee("" + source + "\n\nwindow." + name + " = " + name + " unless window." + name + ";", false, true);
        } else {
          pp.utils.coffee("" + source + "\n\nwindow." + name + " = " + name + ";", false, true);
        }
      } else if (type === "js") {
        eval("" + source + "\n\nwindow." + name + " = " + name + ";");
      } else if (type === "babel") {
        eval(babel.transform("" + source + "\n\nwindow." + name + " = " + name + ";").code);
      }
      if (type === "js") {
        pl = new $Plugin(name, path);
        for (k in pl) {
          v = pl[k];
          window[name].prototype[k] = v;
        }
        pp.currentPlugin = new window[name];
      } else {
        pp.currentPlugin = new window[name](name, path);
      }
      core.registerPluginMenu_(JSON.stringify(Object.keys(pp.currentPlugin.menu())));
      return pp.currentPlugin.init();
    };

    __Plugin.prototype.halt_ = function() {
      if (pp.currentPlugin != null) {
        pp.currentPlugin.halt();
        pp.events.removeById(pp.currentPlugin.name);
        window[pp.currentPlugin.name] = null;
        return pp.currentPlugin = null;
      }
    };

    __Plugin.prototype.run_ = function(name, path, source, anyway, type) {
      if (anyway == null) {
        anyway = false;
      }
      if (type == null) {
        type = "coffee";
      }
      if ((pp.currentPlugin != null) && pp.currentPlugin.name !== name) {
        this.halt_();
      }
      if ((pp.currentPlugin == null) || pp.currentPlugin.name !== name || anyway) {
        this.load_(name, path, source, anyway, type);
      }
      return pp.currentPlugin.run();
    };

    __Plugin.prototype.test_ = function(refresh) {
      var pluginContent, pluginName, pluginPath;
      if (refresh == null) {
        refresh = false;
      }
      pluginName = $Document.info().filename.replace($Document.info().extension, "").replace(".", "");
      pluginPath = $Document.info().folder;
      pluginContent = $Document.info().content;
      if (refresh) {
        this.halt_();
      }
      return this.run_(pluginName, pluginPath, pluginContent);
    };

    return __Plugin;

  })();

  if (!this.__Plugin) {
    this.__Plugin = __Plugin;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
  var __Terminal,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  __Terminal = (function() {
    function __Terminal(pp) {
      this.interpreter = __bind(this.interpreter, this);
      this.mode = this.oldMode = "coffee";
      this.prompt = this.oldPrompt = "[[b;orange;]coffee>] ";
      this.intro = "[[b;#A5E12C;]Peppermint][[b;#65A10C;]/" + pp.version + "]\n[[;gray;]Type 'help' for a list of available commands]\n\n";
      this.emulator = $("#console").terminal(this.interpreter, {
        prompt: this.prompt,
        greetings: this.intro,
        tabcompletion: true,
        completion: (function(_this) {
          return function(terminal, command, callback) {
            return callback(["clear", "help", "version", "bash", "js", "coffee", "run", "$Dialog.alert", "$Dialog.input", "$Document.info().label", "$Document.info().path", "$Document.info().filename", "$Document.info().folder", "$Document.info().extension", "$Editor.bind", "$Editor.content", "$Editor.selection", "$Editor.option.gutter", "$Editor.option.printMargin", "$Editor.option.indentGuides", "$Editor.option.invisibles", "$Editor.option.softTabs", "$Editor.option.wordWrap", "$Editor.option.tabSize", "$Editor.option.wrapLimit", "$Preview.load", "$Preview.loadDocument", "$Terminal.show", "$Terminal.clear", "$Terminal.echo", "$Terminal.exec", "$Terminal.execSilent", "$Terminal.setVar", "$Terminal.write", "$Terminal.kill"]);
          };
        })(this)
      });
    }

    __Terminal.prototype.echoError = function(error) {
      return this.emulator.echo("[[;red;] ! ]" + error + "\n");
    };

    __Terminal.prototype.setStdinMode = function(onoff) {
      if (onoff) {
        this.oldMode = this.mode;
        this.oldPrompt = this.prompt;
        this.mode = "stdin";
        this.prompt = "";
        return this.emulator.set_prompt(this.prompt);
      } else {
        this.mode = this.oldMode;
        this.prompt = this.oldPrompt;
        return this.emulator.set_prompt(this.prompt);
      }
    };

    __Terminal.prototype.setMode = function(mode, color) {
      if (this.mode !== mode) {
        this.mode = this.oldMode = mode;
        this.prompt = this.oldPrompt = "[[b;" + color + ";]" + mode + ">] ";
        return this.emulator.set_prompt(this.prompt);
      } else {
        return this.emulator.echo("You're already in " + mode + " mode.");
      }
    };

    __Terminal.prototype.parseCommandLine = function(str) {
      var args, i, part, readingPart, _i, _ref;
      args = [];
      readingPart = false;
      part = '';
      for (i = _i = 0, _ref = str.length; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
        if (str[i] === ' ' && !readingPart) {
          args.push(part);
          part = '';
        } else {
          if (str[i] === '\"') {
            readingPart = !readingPart;
          } else {
            if (str[i] != null) {
              part += str[i];
            }
          }
        }
      }
      args.push(part);
      return args;
    };

    __Terminal.prototype.interpreter = function(cmd, term) {
      switch (cmd) {
        case 'help':
          this.emulator.echo("coffee     - Enable CoffeeScript mode (default)");
          this.emulator.echo("js         - Enable JavaScript mode");
          this.emulator.echo("bash       - Enable Bash mode\n");
          this.emulator.echo("run        - Run current script (if available)\n");
          this.emulator.echo("quit       - Quit current mode and return to default");
          this.emulator.echo("clear      - Clear terminal window\n");
          this.emulator.echo("version    - Show current version");
          return this.emulator.echo("help       - Show this help listing\n");
        case 'version':
          return this.emulator.echo("[[;#A5E12C;]Peppermint][[b;#65A10C;]/" + pp.version + "\n\n");
        case 'quit':
          if (this.mode === 'bash' || this.mode === 'js') {
            return this.setMode("coffee", "orange");
          }
          break;
        case 'bash':
          return this.setMode("bash", "white");
        case 'coffee':
          return this.setMode("coffee", "orange");
        case 'js':
          return this.setMode("js", "cyan");
        case 'run':
          if (core.execRun() != null) {
            return this.emulator.echo("Run: command not available for current spec");
          }
          break;
        default:
          switch (this.mode) {
            case 'bash':
              return this.execBash(cmd, term);
            case 'coffee':
              return this.execCoffee(cmd, term);
            case 'js':
              return this.execJs(cmd, term);
            case 'stdin':
              return this.execStdin(cmd, term);
          }
      }
    };

    __Terminal.prototype.execBash = function(cmd) {
      var params;
      params = this.parseCommandLine(cmd);
      return $Terminal.exec.apply($Terminal, params);
    };

    __Terminal.prototype.execCoffee = function(cmd) {
      var decaf, e, result;
      try {
        decaf = pp.utils.coffee(cmd, true, false);
        result = eval(decaf);
        if (result != null) {
          return this.emulator.echo(" = " + (pp.utils.inspect(result)) + "\n");
        }
      } catch (_error) {
        e = _error;
        return this.echoError(e);
      }
    };

    __Terminal.prototype.execJs = function(cmd) {
      var e, result;
      try {
        result = eval(cmd);
        if (result != null) {
          return this.emulator.echo(" = " + (pp.utils.inspect(result)) + "\n");
        }
      } catch (_error) {
        e = _error;
        return this.echoError(e);
      }
    };

    __Terminal.prototype.execStdin = function(cmd) {
      return $Terminal.write(cmd);
    };

    return __Terminal;

  })();

  if (!this.__Terminal) {
    this.__Terminal = __Terminal;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
  var __Utils;

  __Utils = (function() {
    function __Utils() {}

    __Utils.prototype.coffee = function(code, bare, exec) {
      var error, result;
      if (bare == null) {
        bare = false;
      }
      if (exec == null) {
        exec = false;
      }
      try {
        if (typeof code === 'object') {
          code = eval(code)[0];
        }
        result = CoffeeScript.compile(code, {
          bare: bare
        });
        if (exec) {
          return eval.apply(window, [result]);
        } else {
          return result;
        }
      } catch (_error) {
        error = _error;
        return $Terminal.echo("Coffee:: Error : " + (error.toString()));
      }
    };

    __Utils.prototype.less = function(code, name) {
      var error, parser;
      try {
        if (typeof code === 'object') {
          code = eval(code)[0];
        }
        if (name != null) {
          code = code.replace(new RegExp("(\.[a-z]+)", "gm"), ".ace_$1");
          code = code.replace(new RegExp("(#" + name + ")", "gm"), ".ace-" + name);
        }
        parser = window.less.Parser();
        parser.parse(code, (function(_this) {
          return function(error, result) {
            if (!error) {
              return result.toCSS();
            }
          };
        })(this));
      } catch (_error) {
        error = _error;
        $Terminal.echo("LESS:: Error : " + (error.toString()));
      }
      return "";
    };

    __Utils.prototype.mustache = function(template, obj) {
      return window.Mustache.render(template, obj);
    };

    __Utils.prototype.parsePattern = function(pattern, output) {
      var part, parts, result, toAdd, _i, _len;
      parts = pattern.split(" ");
      result = [];
      for (_i = 0, _len = parts.length; _i < _len; _i++) {
        part = parts[_i];
        if ((part != null) && (part.trim() != null)) {
          toAdd = part;
          toAdd = toAdd.replace("%filename_no_ext", $Document.info().filename.replace("." + ($Document.info().extension), ""));
          toAdd = toAdd.replace("%file", $Document.info().path);
          toAdd = toAdd.replace("%folder", $Document.info().folder);
          toAdd = toAdd.replace("%output", output);
          toAdd = toAdd.replace("@clojure", pp.currentPlugin.bin["clojure"]);
          toAdd = toAdd.replace("@lua", pp.currentPlugin.bin["lua"]);
          result.push(toAdd);
        }
      }
      return result;
    };

    __Utils.prototype.uuid = function() {
      return genuuid();
    };

    __Utils.prototype.inspect = function(object) {
      return window.Node.inspect(object, {
        depth: 1
      });
    };

    __Utils.prototype.parseElemTokens = function(elem, tokens, dict) {
      var endT, endTokenType, endTokenValue, foundEnd, foundStart, k, newElem, next, okieDokie, startT, startTokenType, startTokenValue, starts, t, token, tokenType, tokenValue, v, _results;
      t = 0;
      _results = [];
      while (t < tokens.length) {
        token = tokens[t];
        next = null;
        if (t + 1 < tokens.length - 1) {
          next = tokens[t + 1];
        }
        for (k in dict) {
          v = dict[k];
          okieDokie = false;
          tokenType = "keyword";
          tokenValue = v.pattern;
          if (v.pattern != null) {
            if (v.pattern.indexOf(":") > -1) {
              tokenType = v.pattern.split(":")[0];
              tokenValue = v.pattern.split(":")[1];
            }
          }
          if (token.t === tokenType && token.v === tokenValue && next) {
            newElem = {
              type: k,
              value: next.v.trim(),
              position: next.p + 1,
              symbols: []
            };
            okieDokie = true;
          } else if (token.t === v.match) {
            newElem = {
              type: k,
              value: token.v.trim(),
              position: token.p + 1,
              symbols: []
            };
            okieDokie = true;
          }
          if (okieDokie) {
            if ((v.start != null) && (v.end != null)) {
              startTokenType = "$$$$$";
              startTokenValue = v.start;
              endTokenType = "$$$$$";
              endTokenValue = v.end;
              if (v.start.indexOf(":") > -1) {
                startTokenType = v.start.split(":")[0];
                startTokenValue = v.start.split(":")[1];
              }
              if (v.end.indexOf(":") > -1) {
                endTokenType = v.end.split(":")[0];
                endTokenValue = v.end.split(":")[1];
              }
              startT = endT = 0;
              foundStart = false;
              foundEnd = false;
              while (!foundStart && t < tokens.length) {
                if ((tokens[t].t === "paren.lparen" || tokens[t].t === "lparen" || tokens[t].t === startTokenType) && tokens[t].v.trim() === startTokenValue) {
                  foundStart = true;
                  startT = t;
                }
                t += 1;
              }
              if (foundStart) {
                starts = 1;
                while (!foundEnd && t < tokens.length) {
                  if ((tokens[t].t === "paren.lparen" || tokens[t].t === "lparen" || tokens[t].t === startTokenType) && tokens[t].v.trim() === startTokenValue) {
                    starts += 1;
                  }
                  if ((tokens[t].t === "paren.rparen" || tokens[t].t === "rparen" || tokens[t].t === endTokenType) && tokens[t].v.trim() === endTokenValue) {
                    starts -= 1;
                  }
                  if (starts === 0) {
                    foundEnd = true;
                    endT = t;
                    this.parseElemTokens(newElem, tokens.slice(startT, +endT + 1 || 9e9), dict);
                  }
                  t += 1;
                }
                t -= 1;
              }
            }
            elem.symbols.push(newElem);
          }
        }
        _results.push(t += 1);
      }
      return _results;
    };

    __Utils.prototype.parseSymbolTable = function(dictionary, excludeText) {
      var root, tokens;
      if (excludeText == null) {
        excludeText = ["text"];
      }
      tokens = pp.editor.tokenize(excludeText);
      root = {
        type: "root",
        value: 0,
        position: 0,
        symbols: []
      };
      this.parseElemTokens(root, tokens, dictionary);
      return core.setElemSymbolTable_(JSON.stringify(root));
    };

    __Utils.prototype.parseXMLElemTokens = function(elem, tokens) {
      var counter, newElem, startT, t, val, _results;
      t = 0;
      _results = [];
      while (t < tokens.length) {
        if (tokens[t].t === "meta.tag.punctuation.tag-open.xml" && t + 1 < tokens.length) {
          if (tokens[t + 1].t === "meta.tag.tag-name.xml") {
            val = tokens[t + 1].v;
            startT = t + 1;
            counter = 1;
            newElem = {
              type: "tag",
              value: val,
              position: tokens[t + 1].p,
              symbols: []
            };
            t += 1;
            while (t < tokens.length) {
              $Terminal.echo("Searching token: " + t + " --> " + tokens[t]);
              if (tokens[t].t === "meta.tag.punctuation.tag-open.xml" && t + 1 < tokens.length - 1) {
                if (tokens[t + 1].t === "meta.tag.tag-name.xml" && tokens[t + 1].v === val) {
                  counter += 1;
                }
              }
              if (tokens[t].t === "meta.tag.punctuation.end-tag-open.xml" && t + 1 < tokens.length - 1) {
                if (tokens[t + 1].t === "meta.tag.tag-name.xml" && tokens[t + 1].v === val) {
                  counter -= 1;
                }
              }
              if (counter === 0) {
                this.parseXMLElemTokens(newElem, tokens.slice(startT, +(t + 1) + 1 || 9e9));
              }
              t += 1;
            }
            elem.symbols.push(newElem);
          }
        }
        _results.push(t += 1);
      }
      return _results;
    };

    __Utils.prototype.parseXMLSymbolTable = function() {
      var root, tokens;
      tokens = pp.editor.tokenize(["text"]);
      root = {
        type: "root",
        value: 0,
        position: 0,
        symbols: []
      };
      this.parseXMLElemTokens(root, tokens);
      return core.setElemSymbolTable_(JSON.stringify(root));
    };

    return __Utils;

  })();

  if (!this.__Utils) {
    this.__Utils = __Utils;
  }

}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
  var __PP;

  __PP = (function() {
    function __PP() {
      if (typeof core !== "undefined" && core !== null) {
        this.version = core.getVersion();
      } else {
        this.version = "1.4 (Build X)";
      }
      if (typeof core !== "undefined" && core !== null) {
        this.binaries = JSON.parse(core.getBinariesIndex());
      }
      this.editor = new __Editor("editor");
      this.events = new __Events;
      this.builtins = [];
      if (window.PREVIEW == null) {
        this.layout = new __Layout();
        //this.terminal = new __Terminal(this);
        this.utils = new __Utils();
        this.currentPlugin = null;
      }
      return this;
    }

    __PP.prototype.clearBuiltins = function() {
      var builtin, _i, _len, _ref;
      _ref = this.builtins;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        builtin = _ref[_i];
        builtin.halt_();
      }
      return this.builtins = [];
    };

    return __PP;

  })();

  $((function(_this) {
    return function() {
      if (!_this.pp) {
        _this.pp = new __PP;
      }
      if (!_this.$Builtin) {
        _this.$Builtin = __Builtin;
      }
      if (!_this.$Plugin) {
        _this.$Plugin = __Plugin;
      }
      if (!_this.$Dialog) {
        _this.$Dialog = new _Dialog;
      }
      if (!_this.$Document) {
        _this.$Document = new _Document;
      }
      if (!_this.$Editor) {
        _this.$Editor = new _Editor;
      }
      if (!_this.$Fs) {
        _this.$Fs = new _Fs;
      }
      if (!_this.$Net) {
        _this.$Net = new _Net;
      }
      if (!_this.$On) {
        _this.$On = new _On("Global");
      }
      if (!_this.$Preview) {
        _this.$Preview = new _Preview;
      }
      if (!_this.$Terminal) {
        _this.$Terminal = new _Terminal;
      }
      if (!_this.$Utility) {
        _this.$Utility = new _Utility;
      }
      if (!_this.$Workspace) {
        return _this.$Workspace = new _Workspace;
      }
    };
  })(this));

}).call(this);
