text: var Bebop = (function () {
    'use strict';
  
    // src/client/event-emitter.coffee
    var EventEmitter;
  
    EventEmitter = class EventEmitter {
      constructor(opts = {}) {
        this._listeners = {};
        this._allListeners = [];
      }
  
      on(event, callback) {
        var base;
        if (event) {
          if ((base = this._listeners)[event] == null) {
            base[event] = [];
          }
          this._listeners[event].push(callback);
          // return the index of the newly added listener
          return this._listeners[event].length - 1;
        } else {
          this._allListeners.push(callback);
          return this._allListeners.length - 1;
        }
      }
  
      off(event, index) {
        if (!event) {
          // remove all if no event is specified
          return this._listeners = {};
        }
        if (index != null) {
          // Remove listener at index
          this._listeners[event][index] = null;
        } else {
          // Remove all listeners for event
          this._listeners[event] = {};
        }
      }
  
      emit(event, ...args) {
        var i, j, len, len1, listener, listeners, ref, results;
        listeners = this._listeners[event] || [];
        for (i = 0, len = listeners.length; i < len; i++) {
          listener = listeners[i];
          if (listener != null) {
            listener.apply(this, args);
          }
        }
        args.unshift(event);
        ref = this._allListeners;
        results = [];
        for (j = 0, len1 = ref.length; j < len1; j++) {
          listener = ref[j];
          results.push(listener.apply(this, args));
        }
        return results;
      }
  
    };
  
    var EventEmitter$1 = EventEmitter;
  
    // node_modules/@zeekay/rollup-plugin-node-builtins/src/es6/qs.js
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  
    // If obj.hasOwnProperty has been overridden, then calling
    // obj.hasOwnProperty(prop) will break.
    // See: https://github.com/joyent/node/issues/1707
    function hasOwnProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }
    var isArray = Array.isArray || function (xs) {
      return Object.prototype.toString.call(xs) === '[object Array]';
    };
    function stringifyPrimitive(v) {
      switch (typeof v) {
        case 'string':
          return v;
  
        case 'boolean':
          return v ? 'true' : 'false';
  
        case 'number':
          return isFinite(v) ? v : '';
  
        default:
          return '';
      }
    }
  
    function stringify (obj, sep, eq, name) {
      sep = sep || '&';
      eq = eq || '=';
      if (obj === null) {
        obj = undefined;
      }
  
      if (typeof obj === 'object') {
        return map(objectKeys(obj), function(k) {
          var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
          if (isArray(obj[k])) {
            return map(obj[k], function(v) {
              return ks + encodeURIComponent(stringifyPrimitive(v));
            }).join(sep);
          } else {
            return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
          }
        }).join(sep);
  
      }
  
      if (!name) return '';
      return encodeURIComponent(stringifyPrimitive(name)) + eq +
             encodeURIComponent(stringifyPrimitive(obj));
    }
    function map (xs, f) {
      if (xs.map) return xs.map(f);
      var res = [];
      for (var i = 0; i < xs.length; i++) {
        res.push(f(xs[i], i));
      }
      return res;
    }
  
    var objectKeys = Object.keys || function (obj) {
      var res = [];
      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
      }
      return res;
    };
  
    function parse(qs, sep, eq, options) {
      sep = sep || '&';
      eq = eq || '=';
      var obj = {};
  
      if (typeof qs !== 'string' || qs.length === 0) {
        return obj;
      }
  
      var regexp = /\+/g;
      qs = qs.split(sep);
  
      var maxKeys = 1000;
      if (options && typeof options.maxKeys === 'number') {
        maxKeys = options.maxKeys;
      }
  
      var len = qs.length;
      // maxKeys <= 0 means that we should not limit keys count
      if (maxKeys > 0 && len > maxKeys) {
        len = maxKeys;
      }
  
      for (var i = 0; i < len; ++i) {
        var x = qs[i].replace(regexp, '%20'),
            idx = x.indexOf(eq),
            kstr, vstr, k, v;
  
        if (idx >= 0) {
          kstr = x.substr(0, idx);
          vstr = x.substr(idx + 1);
        } else {
          kstr = x;
          vstr = '';
        }
  
        k = decodeURIComponent(kstr);
        v = decodeURIComponent(vstr);
  
        if (!hasOwnProperty(obj, k)) {
          obj[k] = v;
        } else if (isArray(obj[k])) {
          obj[k].push(v);
        } else {
          obj[k] = [obj[k], v];
        }
      }
  
      return obj;
    }var querystring = {
      encode: stringify,
      stringify: stringify,
      decode: parse,
      parse: parse
    };
  
    // src/client/utils.coffee
    var random;
  
    var isBrowser = (function() {
      return typeof window !== "undefined" && window !== null;
    })();
  
    var location$1 = (function() {
      if (isBrowser) {
        return window.location;
      } else {
        return {
          protocol: 'http:',
          hostname: 'localhost',
          port: '3333'
        };
      }
    })();
  
    var root = (function() {
      if (isBrowser) {
        return window;
      } else {
        return global;
      }
    })();
  
    random = function() {
      return (((1 + Math.random()) * 0x100000) | 0).toString(16);
    };
  
    var urlRandomize = function(url) {
      var path, query;
      [path, query] = url.split('?');
      if (query == null) {
        return path + '?bop=' + random();
      }
      query = querystring.parse(query);
      query.bop = random();
      return path + '?' + querystring.stringify(query);
    };
  
    // src/client/tags.coffee
    var tags;
  
    var tags$1 = tags = {
      js: {
        link: 'src',
        name: 'script',
        type: 'text/javascript'
      },
      css: {
        link: 'href',
        name: 'link',
        type: 'text/css'
      }
    };
  
    // src/client/log.coffee
    var Logger;
  
    Logger = class Logger {
      constructor(opts = {}) {
        var ref;
        this.verbose((ref = opts.debug) != null ? ref : false);
      }
  
      debug(...args) {
        if (!this.verbose()) {
          return;
        }
        return this.log('debug', ...args);
      }
  
      info(...args) {
        if (!this.verbose()) {
          return;
        }
        return this.log('info', ...args);
      }
  
      warn(...args) {
        return this.log('warn', ...args);
      }
  
      error(...args) {
        return this.log('error', ...args);
      }
  
      log(level, ...args) {
        args.unshift('bebop:' + level);
        return typeof console !== "undefined" && console !== null ? console.log.apply(console, args) : void 0;
      }
  
      verbose(bool) {
        if (bool == null) {
          return this._verbose;
        }
        return this._verbose = bool;
      }
  
    };
  
    var log = new Logger();
  
    // src/client/node.coffee
    var parseFilename;
  
    parseFilename = function(filename) {
      var ext, path, resource;
      // Determine path, filename and extension
      // Not terribly robust, might want to use *gasp* regex
      path = filename.split('/');
      filename = path.pop();
      ext = filename.split('.')[1];
      resource = {
        ext: ext,
        filename: filename,
        path: path,
        tag: tags$1[ext]
      };
      return resource;
    };
  
    var findNode = function(filename) {
      var i, len, node, re, ref, resource;
      if (filename === '') {
        return;
      }
      if ((resource = parseFilename(filename)).tag == null) {
        return;
      }
      re = new RegExp(filename + '$');
      ref = document.getElementsByTagName(resource.tag.name);
      for (i = 0, len = ref.length; i < len; i++) {
        node = ref[i];
        if (re.test((node[resource.tag.link].split('?'))[0])) {
          resource.url = node[resource.tag.link];
          node._resource = resource;
          return node;
        }
      }
      return null;
    };
  
    // reloading
    var reloadNode = function(node) {
      var link;
      if (node._resource.ext === 'js') {
        node.parentNode.removeChild(node);
        return load(node._resource);
      }
      link = node._resource.tag.link;
      // hack to get chrome to reload css
      if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
        node[link] = '#break-the-url';
      }
      // update url of resource
      node[link] = urlRandomize(node._resource.url);
      return log.info('resource-reloaded', node[link]);
    };
  
    var load = function(resource) {
      var node;
      node = document.createElement(resource.tag.name);
      node[resource.tag.link] = resource.url;
      node.type = resource.tag.type;
      document.getElementsByTagName('head')[0].appendChild(node);
      return log.info('resource-loaded', node[resource.tag.link]);
    };
  
    // src/client/websocket.coffee
    var WebSocket, fallback, ref, ref1, urls;
  
    root.WEB_SOCKET_SWF_LOCATION = 'https://cdnjs.cloudflare.com/ajax/libs/web-socket-js/1.0.0/WebSocketMain.swf';
  
    urls = ['https://cdnjs.cloudflare.com/ajax/libs/web-socket-js/1.0.0/web_socket.js', 'https://cdnjs.cloudflare.com/ajax/libs/web-socket-js/1.0.0/web_socket.min.js'];
  
    fallback = function() {
      var i, len, url;
      for (i = 0, len = urls.length; i < len; i++) {
        url = urls[i];
        load(url);
      }
      return root.WebSocket;
    };
  
    WebSocket = (ref = (ref1 = root.WebSocket) != null ? ref1 : root.MozWebSocket) != null ? ref : fallback();
  
    if (isBrowser) {
      WebSocket.identifier = location.href + ' - ' + navigator.userAgent;
    } else {
      WebSocket.identifier = process.argv[1] + ' - node';
    }
  
    var WebSocket$1 = WebSocket;
  
    // src/client/dir.coffee
    // introspection
    function dir(object) {
      var i, properties, property, seen, valid;
      valid = function(name) {
        var i, invalid;
        invalid = ['arguments', 'caller', 'name', 'length', 'prototype'];
        for (i in invalid) {
          if (invalid[i] === name) {
            return false;
          }
        }
        return true;
      };
      properties = [];
      seen = {};
      if (Object.getOwnPropertyNames !== 'undefined') {
        properties = Object.getOwnPropertyNames(object);
        for (property in object) {
          properties.push(property);
        }
        properties = properties.filter(function(name) {
          return valid(name);
        });
        i = 0;
        while (i < properties.length) {
          seen[properties[i]] = '';
          i++;
        }
        return Object.keys(seen);
      } else {
        for (property in object) {
          properties.push(property);
        }
      }
      return properties;
    }
  
    // src/client/dump.coffee
  
    // src/client/stacktrace.coffee
  
    // Stacktrace, borrowed from https://github.com/eriwen/javascript-stacktrace
    function stacktrace(e) {
      if (e['arguments'] && e.stack) {
        return method.chrome(e);
      }
      if (e.stack) {
        return method.firefox(e);
      }
      return method.other(e);
    }
  
    // src/client/bebop.coffee
    var Bebop;
  
    Bebop = (function() {
      class Bebop extends EventEmitter$1 {
        constructor(opts = {}) {
          var hostname, port, protocol, ref, ref1, ref2, ref3, ref4, ref5;
          super();
          protocol = (ref = opts.protocol) != null ? ref : location$1.protocol === 'http:' ? 'ws://' : 'wss://';
          hostname = (ref1 = opts.hostname) != null ? ref1 : location$1.hostname;
          port = (ref2 = opts.port) != null ? ref2 : location$1.port;
          this.address = (ref3 = opts.address) != null ? ref3 : protocol + hostname + ':' + port + '/_bebop';
          this.timeout = (ref4 = opts.timeout) != null ? ref4 : 1000;
          this.tries = 0;
          this.limit = -1;
          this.logger = log;
          this._debug = (ref5 = opts.debug) != null ? ref5 : false;
          this._failed = false;
          this._retries = [];
          this._once = {
            error: false,
            closed: false
          };
          this.init(opts);
        }
  
        // Initialize Bebop
        init(opts = {}) {
          var handlers, k, ref, v;
          // Allow user to override default handlers
          handlers = {
            connected: opts.onconnected,
            closed: opts.onclosed,
            error: opts.onerror,
            message: opts.onmessage,
            reconnecting: opts.reconnecting
          };
          ref = this.defaultHandlers;
          // Setup default handlers
          for (k in ref) {
            v = ref[k];
            if (handlers[k] == null) {
              handlers[k] = v;
            }
          }
          // Bind handlers WebSocket events
          this.on('connect', () => {
            if ((this.limit != null) && this.limit >= 0) {
              if (this.tries > this.limit) {
                log.error('Bebop.connect', 'connection-failed: giving up!');
                return this._failed = true;
              } else {
                return this.tries = this.tries + 1;
              }
            }
          });
          this.on('connected', (...args) => {
            this.tries = 0;
            return handlers.connected.apply(this, args);
          });
          this.on('closed', (...args) => {
            return handlers.closed.apply(this, args);
          });
          this.on('error', (...args) => {
            return handlers.error.apply(this, args);
          });
          this.on('message', (...args) => {
            return handlers.message.apply(this, args);
          });
          this.on('reconnecting', () => {
            return handlers.reconnecting.apply(this, args);
          });
          Object.defineProperty(this, 'debug', {
            get: function() {
              return this._debug;
            },
            set: function(bool = false) {
              this._debug = bool;
              return log.verbose(bool);
            }
          });
          // Set log level
          return log.verbose(this.debug);
        }
  
        // Create new WebSocket connection and connect to it
        connect() {
          var err;
          if (this._failed) {
            return;
          }
          this.emit('connecting');
          try {
            this.ws = new WebSocket$1(this.address);
          } catch (error1) {
            err = error1;
            log.warn('Failed to create WebSocket', err);
            return this.reconnect();
          }
          this.ws.onopen = (...args) => {
            this.stopRetrying();
            args.unshift('connected');
            return this.emit.apply(this, args);
          };
          this.ws.onclose = (...args) => {
            args.unshift('closed');
            return this.emit.apply(this, args);
          };
          this.ws.onerror = (...args) => {
            args.unshift('error');
            return this.emit.apply(this, args);
          };
          this.ws.onmessage = (e) => {
            return this.emit('message', JSON.parse(e.data));
          };
          if (isBrowser) {
            return root.addEventListener('beforeunload', () => {
              return this.ws.close();
            });
          }
        }
  
        // Retry connection on failure/timeout
        reconnect() {
          if (this._failed) {
            return;
          }
          this.emit('reconnecting');
          return this._retries.push(root.setTimeout(() => {
            return this.connect();
          }, this.timeout));
        }
  
        stopRetrying() {
          var i, len, ref, t;
          this.tries = 0;
          ref = this._retries;
          for (i = 0, len = ref.length; i < len; i++) {
            t = ref[i];
            clearTimeout(t);
          }
          return this._retries = [];
        }
  
        // Close WebSocket connection
        close() {
          return this.ws.close();
        }
  
        // Send WebSocket message
        send(msg) {
          this.emit('send', msg);
          return this.ws.send(JSON.stringify(msg));
        }
  
        // Return completions for code fragment
        complete(code) {
          this.emit('complete', code);
          try {
            return dir(eval_.call(root, code));
          } catch (error1) {
            return [];
          }
        }
  
        // Called when eval requested.
        eval(code) {
          var e, error, res;
          this.emit('eval', code);
          try {
            return res = eval_.call(root, msg);
          } catch (error1) {
            e = error1;
            return error = {
              error: e.message,
              stack: stacktrace(e)
            };
          }
        }
  
        modified(filename) {
          var node;
          this.emit('modified', filename);
          if (isBrowser) {
            node = findNode(filename);
            if (node && node._resource.tag.name !== 'script') {
              return reloadNode(node);
            } else {
              return this.reload(true);
            }
          }
        }
  
        // Close connection and reload current page
        reload() {
          var ref;
          this.emit('reload');
          this.close();
          return (ref = root.location) != null ? ref.reload() : void 0;
        }
  
        // Client responses to server RPC calls
        sendConnected() {
          return this.send({
            type: 'connected',
            identifier: this.ws.identifier
          });
        }
  
        // Return completions
        sendComplete(code) {
          return this.send({
            type: 'complete',
            result: this.complete(code)
          });
        }
  
        // Called when eval requested.
        sendEval(code) {
          return this.send({
            type: 'eval',
            result: this.eval(code)
          });
        }
  
      }
      // Default event handlers
      Bebop.prototype.defaultHandlers = {
        connected: function() {
          log.info('connected');
          this._once = {
            error: false,
            closed: false
          };
          return this.sendConnected();
        },
        reconnecting: function() {
          return log.info('reconnecting');
        },
        closed: function() {
          if (!this._once.closed) {
            log.info('closed');
          }
          return this._once.closed = true;
        },
        error: function() {
          if (!this._once.error) {
            log.error('error');
          }
          return this._once.error = true;
        },
        message: function(message) {
          log.debug('message', message);
          switch (message.type) {
            case 'complete':
              return this.sendComplete(message.name);
            case 'eval':
              return this.sendEval(message.code);
            case 'modified':
              return this.modified(message.filename);
            case 'reload':
              return this.reload();
            default:
              return log.warn(`Unknown message type '${message.type}'`, message);
          }
        }
      };
  
      return Bebop;
  
    }).call(undefined);
  
    var Bebop$1 = Bebop;
  
    // src/client/index.coffee
  
    if (typeof window !== "undefined" && window !== null) {
      window.Bebop = Bebop$1;
    }
  
    return Bebop$1;
  
  }());
  //# sourceMappingURL=bebop.min.js.map
  