<commit_before>/**
 * @author shaozilee
 *
 * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp
 *
 */

function BmpDecoder(buffer) {
  this.pos = 0;
  this.buffer = buffer;
  this.flag = this.buffer.toString("utf-8", 0, this.pos += 2);
  if (this.flag != "BM") throw new Error("Invalid BMP File");
  this.parseHeader();
  this.parseBGR();
}

BmpDecoder.prototype.parseHeader = function() {
  this.fileSize = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.reserved = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.offset = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.headerSize = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.width = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.height = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.planes = this.buffer.readUInt16LE(this.pos);
  this.pos += 2;
  this.bitPP = this.buffer.readUInt16LE(this.pos);
  this.pos += 2;
  this.compress = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.rawSize = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.hr = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.vr = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.colors = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.importantColors = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;

  if (this.bitPP < 24) {
    var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
    this.palette = new Array(len);
    for (var i = 0; i < len; i++) {
      var blue = this.buffer.readUInt8(this.pos++);
      var green = this.buffer.readUInt8(this.pos++);
      var red = this.buffer.readUInt8(this.pos++);
      var quad = this.buffer.readUInt8(this.pos++);
      this.palette[i] = {
        red: red,
        green: green,
        blue: blue,
        quad: quad
      };
    }
  }

}

BmpDecoder.prototype.parseBGR = function() {
  this.pos = this.offset;
  try {
    var bitn = "bit" + this.bitPP;
    var len = this.width * this.height * 4;
    this.data = new Buffer(len);

    this[bitn]();
  } catch (e) {
    console.log("bit decode error:" + e);
  }

};

BmpDecoder.prototype.bit1 = function() {
  var xlen = Math.ceil(this.width / 8);
  var mode = xlen%4;
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < xlen; x++) {
      var b = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x*8*4;
      for (var i = 0; i < 8; i++) {
        if(x*8+i<this.width){
          var rgb = this.palette[((b>>(7-i))&0x1)];
          this.data[location+i*4] = rgb.blue;
          this.data[location+i*4 + 1] = rgb.green;
          this.data[location+i*4 + 2] = rgb.red;
          this.data[location+i*4 + 3] = 0xFF;
        }else{
          break;
        }
      }
    }

    if (mode != 0){
      this.pos+=(4 - mode);
    }
  }
};

BmpDecoder.prototype.bit4 = function() {
  var xlen = Math.ceil(this.width/2);
  var mode = xlen%4;
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < xlen; x++) {
      var b = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x*2*4;

      var before = b>>4;
      var after = b&0x0F;

      var rgb = this.palette[before];
      this.data[location] = rgb.blue;
      this.data[location + 1] = rgb.green;
      this.data[location + 2] = rgb.red;
      this.data[location + 3] = 0xFF;

      if(x*2+1>=this.width)break;

      rgb = this.palette[after];
      this.data[location+4] = rgb.blue;
      this.data[location+4 + 1] = rgb.green;
      this.data[location+4 + 2] = rgb.red;
      this.data[location+4 + 3] = 0xFF;
    }

    if (mode != 0){
      this.pos+=(4 - mode);
    }
  }

};

BmpDecoder.prototype.bit8 = function() {
  var mode = this.width%4;
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < this.width; x++) {
      var b = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x*4;
      if(this.palette.length >= b) {
        var rgb = this.palette[b];
        this.data[location] = rgb.blue;
        this.data[location + 1] = rgb.green;
        this.data[location + 2] = rgb.red;
        this.data[location + 3] = 0xFF;
      } else {
        this.data[location] = 0xFF;
        this.data[location + 1] = 0xFF;
        this.data[location + 2] = 0xFF;
        this.data[location + 3] = 0xFF;
      }
    }
    if (mode != 0){
      this.pos+=(4 - mode);
    }
  }
};

BmpDecoder.prototype.bit24 = function() {
  //when height > 0
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < this.width; x++) {
      var blue = this.buffer.readUInt8(this.pos++);
      var green = this.buffer.readUInt8(this.pos++);
      var red = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x * 4;
      this.data[location] = red;
      this.data[location + 1] = green;
      this.data[location + 2] = blue;
      this.data[location + 3] = 0xFF;
    }
    //skip extra bytes
    this.pos += (this.width % 4);
  }

};

BmpDecoder.prototype.getData = function() {
  return this.data;
};

module.exports = decode = function(bmpData) {
  var decoder = new BmpDecoder(bmpData);
  return {
    data: decoder.getData(),
    width: decoder.width,
    height: decoder.height
  };
}
<commit_msg>bmp file may use color indexes that are not in it's own palette (small fix)<commit_after>/**
 * @author shaozilee
 *
 * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp
 *
 */

function BmpDecoder(buffer) {
  this.pos = 0;
  this.buffer = buffer;
  this.flag = this.buffer.toString("utf-8", 0, this.pos += 2);
  if (this.flag != "BM") throw new Error("Invalid BMP File");
  this.parseHeader();
  this.parseBGR();
}

BmpDecoder.prototype.parseHeader = function() {
  this.fileSize = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.reserved = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.offset = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.headerSize = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.width = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.height = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.planes = this.buffer.readUInt16LE(this.pos);
  this.pos += 2;
  this.bitPP = this.buffer.readUInt16LE(this.pos);
  this.pos += 2;
  this.compress = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.rawSize = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.hr = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.vr = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.colors = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;
  this.importantColors = this.buffer.readUInt32LE(this.pos);
  this.pos += 4;

  if (this.bitPP < 24) {
    var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
    this.palette = new Array(len);
    for (var i = 0; i < len; i++) {
      var blue = this.buffer.readUInt8(this.pos++);
      var green = this.buffer.readUInt8(this.pos++);
      var red = this.buffer.readUInt8(this.pos++);
      var quad = this.buffer.readUInt8(this.pos++);
      this.palette[i] = {
        red: red,
        green: green,
        blue: blue,
        quad: quad
      };
    }
  }

}

BmpDecoder.prototype.parseBGR = function() {
  this.pos = this.offset;
  try {
    var bitn = "bit" + this.bitPP;
    var len = this.width * this.height * 4;
    this.data = new Buffer(len);

    this[bitn]();
  } catch (e) {
    console.log("bit decode error:" + e);
  }

};

BmpDecoder.prototype.bit1 = function() {
  var xlen = Math.ceil(this.width / 8);
  var mode = xlen%4;
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < xlen; x++) {
      var b = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x*8*4;
      for (var i = 0; i < 8; i++) {
        if(x*8+i<this.width){
          var rgb = this.palette[((b>>(7-i))&0x1)];
          this.data[location+i*4] = rgb.blue;
          this.data[location+i*4 + 1] = rgb.green;
          this.data[location+i*4 + 2] = rgb.red;
          this.data[location+i*4 + 3] = 0xFF;
        }else{
          break;
        }
      }
    }

    if (mode != 0){
      this.pos+=(4 - mode);
    }
  }
};

BmpDecoder.prototype.bit4 = function() {
  var xlen = Math.ceil(this.width/2);
  var mode = xlen%4;
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < xlen; x++) {
      var b = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x*2*4;

      var before = b>>4;
      var after = b&0x0F;

      var rgb = this.palette[before];
      this.data[location] = rgb.blue;
      this.data[location + 1] = rgb.green;
      this.data[location + 2] = rgb.red;
      this.data[location + 3] = 0xFF;

      if(x*2+1>=this.width)break;

      rgb = this.palette[after];
      this.data[location+4] = rgb.blue;
      this.data[location+4 + 1] = rgb.green;
      this.data[location+4 + 2] = rgb.red;
      this.data[location+4 + 3] = 0xFF;
    }

    if (mode != 0){
      this.pos+=(4 - mode);
    }
  }

};

BmpDecoder.prototype.bit8 = function() {
  var mode = this.width%4;
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < this.width; x++) {
      var b = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x*4;
      if(b < this.palette.length) {
        var rgb = this.palette[b];
        this.data[location] = rgb.blue;
        this.data[location + 1] = rgb.green;
        this.data[location + 2] = rgb.red;
        this.data[location + 3] = 0xFF;
      } else {
        this.data[location] = 0xFF;
        this.data[location + 1] = 0xFF;
        this.data[location + 2] = 0xFF;
        this.data[location + 3] = 0xFF;
      }
    }
    if (mode != 0){
      this.pos+=(4 - mode);
    }
  }
};

BmpDecoder.prototype.bit24 = function() {
  //when height > 0
  for (var y = this.height - 1; y >= 0; y--) {
    for (var x = 0; x < this.width; x++) {
      var blue = this.buffer.readUInt8(this.pos++);
      var green = this.buffer.readUInt8(this.pos++);
      var red = this.buffer.readUInt8(this.pos++);
      var location = y * this.width * 4 + x * 4;
      this.data[location] = red;
      this.data[location + 1] = green;
      this.data[location + 2] = blue;
      this.data[location + 3] = 0xFF;
    }
    //skip extra bytes
    this.pos += (this.width % 4);
  }

};

BmpDecoder.prototype.getData = function() {
  return this.data;
};

module.exports = decode = function(bmpData) {
  var decoder = new BmpDecoder(bmpData);
  return {
    data: decoder.getData(),
    width: decoder.width,
    height: decoder.height
  };
}
<|endoftext|>


<commit_before>'use strict';   // dont touch
const Cpacket = require('../../packet').ClientPacket;
const fs = require('fs');
var plugin = []; // dont touch
this.command = []; // dont touch
this.commandName = []; // dont touch
this.gamemodeId = []; // dont touch
this.gamemode = []; // dont touch
this.addToHelp = []; // dont touch
this.timer = 0;
this.adindex = 0;
// [General]
this.name = "Ads plugin"; // Name of plugin REQUIRED
this.author = "Andrews54757"; // author REQUIRED
this.description = 'Host your own ads!'; // Desciprtion
this.compatVersion = '7.2.3'; // compatable with (optional)
this.version = '1.0.0'; // version REQUIRED

// [Extra Commands]
this.commandName[0] = "ads"; // plugin add-on command names
this.addToHelp[0] = "ads     | Ads plugin command"; // help command add-on (adds this string to the help command)
this.command[0] = function(gameServer,split) {
if (split[1] == "reload") {
  console.log("[Console] Reloading ads...")
   try {
  gameServer.ads = JSON.parse(fs.readFileSync(__dirname + "/ads.json"));
  console.log("[Console] Loaded ads");
   } catch (e) {
     console.log("[Console] Failed to load ads, Reason: " + e);

   }

} else if (split[1] == "power") {
  gameServer.adson = !gameServer.adson;
  var text = (gameServer.adson) ? " turned on " : " turned off ";
  console.log("[Console]" + text + "advertisements")
} else {
  console.log("[Console] Available commands");
  console.log("[Console] Reload - Reload ads");
  console.log("[Console] Power  - Turn on/off ads");
}

}; // extra command location

// [Extra Gamemodes]
this.gamemodeId[0] = ''; // gamemodeids of extra plugin gamemodes
this.gamemode[0] = ''; // gamemode location

// [Configs]
this.config = {
// config1: 0,

}

// [Functions]
this.init = function (gameServer, config) {
  this.timer = 0;
  this.adindex = 0;
  gameServer.adson = true;
  this.config = config;
   console.log("[Console] Loading ads...")
   try {
  gameServer.ads = JSON.parse(fs.readFileSync(__dirname + "/ads.json"));
  console.log("[Console] Loaded ads");
   } catch (e) {
     console.log("[Console] Failed to load ads, Reason: " + e);

   }
  // init, Used to do stuff such as overriding things

};
this.genHTML = function(ad) {
  var result = '';
   if (!ad.data) return '';
  var click = (ad.link) ? "" : "";
  var end = (ad.link) ? "" : "";
  if (ad.type == "image") {

    if (ad.dimx && ad.dimy) {
      result = "" + click + ""+ end + "";
    } else {
        result = "" + click + ""+ end + "";
    }

  } else if (ad.type == "text") {

    result =  "" + click + "
" + ad.data + "
"+ end + "";

  } else if (ad.type == "custom") {
    result = ad.data;
  }
  return result;
};
this.sendpacket = function(html, gameServer) {
  var data = {
    customHTML: html,
  };
  for (var i in gameServer.clients) {
    var client = gameServer.clients[i];
    if (client) client.sendPacket(new Cpacket(gameServer,data));

  }

};
this.onSecond = function (gameServer) {
  if (!gameServer.adson) return;
this.timer++;
var ads = gameServer.ads
if (gameServer.ads) {
var ad = gameServer.ads[this.adindex];
  if (this.timer >= ad.duration) {
    if (ads[this.adindex + 1]) {
      this.adindex ++;
    } else {
      this.adindex = 0;
    }

   var ht = this.genHTML(ads[this.adindex]);
    this.sendpacket(ht,gameServer);
    this.timer = 0;
  }

}

  // called every second
};

module.exports = this; // dont touch
<commit_msg>Update index.js<commit_after>'use strict';   // dont touch
const Cpacket = require('../../packet').ClientPacket;
const fs = require('fs');
var plugin = []; // dont touch
this.command = []; // dont touch
this.commandName = []; // dont touch
this.gamemodeId = []; // dont touch
this.gamemode = []; // dont touch
this.addToHelp = []; // dont touch
this.timer = 0;
this.adindex = 0;
// [General]
this.name = "Ads plugin"; // Name of plugin REQUIRED
this.author = "Andrews54757"; // author REQUIRED
this.description = 'Host your own ads!'; // Desciprtion
this.compatVersion = '17.2.3'; // compatable with (optional)
this.version = '1.0.0'; // version REQUIRED

// [Extra Commands]
this.commandName[0] = "ads"; // plugin add-on command names
this.addToHelp[0] = "ads     | Ads plugin command"; // help command add-on (adds this string to the help command)
this.command[0] = function(gameServer,split) {
if (split[1] == "reload") {
  console.log("[Console] Reloading ads...")
   try {
  gameServer.ads = JSON.parse(fs.readFileSync(__dirname + "/ads.json"));
  console.log("[Console] Loaded ads");
   } catch (e) {
     console.log("[Console] Failed to load ads, Reason: " + e);

   }

} else if (split[1] == "power") {
  gameServer.adson = !gameServer.adson;
  var text = (gameServer.adson) ? " turned on " : " turned off ";
  console.log("[Console]" + text + "advertisements")
} else {
  console.log("[Console] Available commands");
  console.log("[Console] Reload - Reload ads");
  console.log("[Console] Power  - Turn on/off ads");
}

}; // extra command location

// [Extra Gamemodes]
this.gamemodeId[0] = ''; // gamemodeids of extra plugin gamemodes
this.gamemode[0] = ''; // gamemode location

// [Configs]
this.config = {
// config1: 0,

}

// [Functions]
this.init = function (gameServer, config) {
  this.timer = 0;
  this.adindex = 0;
  gameServer.adson = true;
  this.config = config;
   console.log("[Console] Loading ads...")
   try {
  gameServer.ads = JSON.parse(fs.readFileSync(__dirname + "/ads.json"));
  console.log("[Console] Loaded ads");
   } catch (e) {
     console.log("[Console] Failed to load ads, Reason: " + e);

   }
  // init, Used to do stuff such as overriding things

};
this.genHTML = function(ad) {
  var result = '';
   if (!ad.data) return '';
  var click = (ad.link) ? "" : "";
  var end = (ad.link) ? "" : "";
  if (ad.type == "image") {

    if (ad.dimx && ad.dimy) {
      result = "" + click + ""+ end + "";
    } else {
        result = "" + click + ""+ end + "";
    }

  } else if (ad.type == "text") {

    result =  "" + click + "
" + ad.data + "
"+ end + "";

  } else if (ad.type == "custom") {
    result = ad.data;
  }
  return result;
};
this.sendpacket = function(html, gameServer) {
  var data = {
    customHTML: html,
  };
  for (var i in gameServer.clients) {
    var client = gameServer.clients[i];
    if (client) client.sendPacket(new Cpacket(gameServer,data));

  }

};
this.onSecond = function (gameServer) {
  if (!gameServer.adson) return;
this.timer++;
var ads = gameServer.ads
if (gameServer.ads) {
var ad = gameServer.ads[this.adindex];
  if (this.timer >= ad.duration) {
    if (ads[this.adindex + 1]) {
      this.adindex ++;
    } else {
      this.adindex = 0;
    }

   var ht = this.genHTML(ads[this.adindex]);
    this.sendpacket(ht,gameServer);
    this.timer = 0;
  }

}

  // called every second
};

module.exports = this; // dont touch
<|endoftext|>


<commit_before>// Node.js API.
var http = require('http')

// Control-flow utilities.
var cadence = require('cadence')
var delta = require('delta')

// Route Sencha Connect middleware based on request method and URL patterns.
var dispatch = require('dispatch')

// Exceptions that you can catch by type.
var interrupt = require('interrupt').createInterrupter('reactor')

// Contextualized callbacks and event handlers.
var Operation = require('operation/variadic')

// Evented work queue.
var Turnstile = require('turnstile')
Turnstile.Queue = require('turnstile/queue')

// Catch exceptions based on a regex match of an error message or property.
var rescue = require('rescue')

// Return the first not null-like value.
var coalesce = require('extant')

// Do nothing.
var nop = require('nop')

function Constructor (object, dispatch) {
    this._object = object
    this._dispatch = dispatch
    this._use = []
    this._defaultUse = true
}

Constructor.prototype.useDefault = function () {
    this.use(require('express-auth-parser'))
    this.use(require('body-parser').urlencoded({ extended: false, limit: '64mb' }))
    this.use(require('body-parser').json({ limit: '64mb' }))
}

Constructor.prototype.use = function () {
    var vargs = Array.prototype.slice.call(arguments)
    this._defaultUse = false
    while (vargs.length) {
        var varg = vargs.shift()
        if (Array.isArray(varg)) {
            vargs.unshift(varg)
        } else {
            this._use.push(varg)
        }
    }
}

Constructor.prototype.dispatch = function () {
    var vargs = Array.prototype.slice.call(arguments)
    this._dispatch[vargs.shift()] = Operation(vargs, { object: this._object })
}

function handler (queue, before, operation) {
    return function (request, response, next) {
        var vargs = Array.prototype.slice.call(arguments, 3)
        request.entry = {
            when: {
                push: Date.now(),
                start: null,
                headers: null,
                finish: null
            },
            health: {
                push: JSON.parse(JSON.stringify(queue.turnstile.health)),
                start: null,
                finish: null
            },
            duration: {
                start: null,
                headers: null,
                finish: null,
            },
            request: {
                method: request.method,
                header: request.headers,
                url: request.url,
                vargs: vargs
            }
        }
        before(request, response, function (error) {
            queue.push({
                error: coalesce(error),
                operation: operation,
                request: request,
                response: response,
                vargs: vargs
            })
        })
    }
}

function Reactor (object, configurator) {
    var constructor = new Constructor(object, this._dispatch = {})
    configurator(constructor)
    this.turnstile = new Turnstile({
        Date: coalesce(constructor.Date, Date),
        turnstiles: coalesce(constructor.turnstiles, 24),
        timeout: coalesce(constructor.timeout)
    })
    this._queue = new Turnstile.Queue(this, '_respond', this.turnstile)
    this._logger = coalesce(constructor.logger, nop)
    this._completed = coalesce(constructor.completed, nop)
    this._object = object
    if (constructor._defaultUse) {
        constructor.useDefault()
    }
    var before = require('connect')()
    constructor._use.forEach(function (middleware) {
        before.use(middleware)
    })
    var dispatcher = {}
    for (var pattern in this._dispatch) {
        dispatcher[pattern] = handler(this._queue, before, this._dispatch[pattern])
    }
    this.middleware = require('connect')().use(dispatch(dispatcher))
}

Reactor.prototype._timeout = cadence(function () { throw 503 })

function createProperties (properties) {
    return {
        statusCode: properties.statusCode,
        headers: coalesce(properties.headers, {}),
        description: coalesce(properties.description)
    }
}

function raise (statusCode, description, headers) {
    throw interrupt('http', createProperties({
        statusCode: statusCode,
        description: description,
        headers: headers
    }))
}

Reactor.prototype._respond = cadence(function (async, envelope) {
    var work = envelope.body
    var next = work.next

    var entry = work.request.entry

    entry.when.start = Date.now()
    entry.health.start = JSON.parse(JSON.stringify(this.turnstile.health))

    work.request.entry = entry
    work.request.raise = raise

    if (envelope.timedout) {
        work.operation = Operation([ this, '_timeout' ])
    }

    var finish

    async(function () {
        async(function () {
            async([function () {
                async(function () {
                    if (work.error) {
                        throw work.error
                    }
                    work.operation.apply(null, [ work.request ].concat(work.vargs, async()))
                }, function () {
                    var vargs = Array.prototype.slice.call(arguments)

                    var result = vargs.shift()
                    var statusCode = (typeof vargs[0] == 'number') ? vargs.shift() : 200
                    var description = coalesce(http.STATUS_CODES[statusCode])
                    if (typeof vargs[0] == 'string') {
                        description = vargs.shift()
                    }
                    if (vargs[0] == null) {
                        vargs.shift()
                    }
                    var headers = coalesce(vargs.shift(), {})

                    interrupt.assert(description != null, 'unknown.http.status', { statusCode: statusCode })

                    return [ result, statusCode, description, headers ]
                })
            }, function (caught) {
                for (;;) {
                    try {
                        return rescue(/^reactor#http$/m, function (error) {
                            var statusCode = error.statusCode
                            var description = coalesce(error.description, http.STATUS_CODES[statusCode])
                            var headers = coalesce(error.headers, {})

                            interrupt.assert(description != null, 'unknown.http.status', { statusCode: statusCode })

                            headers['content-type'] = 'application/json'

                            return [ description, statusCode, description, headers ]
                        })(caught)
                    } catch (error) {
                        if (
                            typeof error == 'number' &&
                            !isNaN(error) &&
                            (error | 0) === error &&
                            Math.floor(error / 100) <= 5 &&
                            Math.floor(error / 100) >= 3
                        ) {
                            error = { statusCode: error }
                        } else if (typeof error == 'string') {
                            error = { statusCode: 307, location: error }
                        }
                        if (
                            typeof error == 'object' &&
                            typeof error.statusCode == 'number' &&
                            !isNaN(error.statusCode) &&
                            (error.statusCode | 0) === error.statusCode &&
                            Math.floor(error.statusCode / 100) <= 5 &&
                            Math.floor(error.statusCode / 100) >= 3
                        ) {
                            var properties = createProperties(error)
                            if (error.location) {
                                properties.headers.location = error.location
                            }
                            error = interrupt('http', properties)
                        } else {
                            entry.error = error
                            error = { statusCode: 500 }
                        }
                        caught = error
                    }
                }
            }])
        }, function (result, statusCode, description, headers) {
            var body, f
            if (typeof result == 'function') {
                f = result
            } else {
                if (typeof result == 'string') {
                    if (!('content-type' in headers)) {
                        headers['content-type'] = 'text/plain'
                        result = new Buffer(result)
                    } else if (headers['content-type'] == 'application/json') {
                        result = new Buffer(JSON.stringify(result) + '\n')
                    }
                } else if (!('content-type' in headers)) {
                    headers['content-type'] = 'application/json'
                    result = new Buffer(JSON.stringify(result) + '\n')
                }
                f = function (response) {
                    response.end(result)
                }
            }

            work.response.writeHead(statusCode, description, headers)

            entry.statusCode = statusCode
            entry.description = description
            entry.headers = headers

            var finish = delta(async()).ee(work.response).on('finish')

            async([function () {
                async(function () {
                    if (result.length == 2) {
                        f.call(work.operation.object, work.response, async())
                    } else {
                        return [ f.call(work.operation.object, work.response) ]
                    }
                }, function () {
                    return []
                })
            }, function (error) {
                entry.error = error
                work.response.end()
                finish.cancel()
            }])
        })
    }, function () {
        entry.health.done = JSON.parse(JSON.stringify(this.turnstile.health))
        entry.when.finish = Date.now()
        entry.duration = {
            start: entry.when.start - entry.when.push,
            headers: entry.when.headers - entry.when.push,
            finish: entry.when.finish - entry.when.push
        }
        this._logger.call(null, 'info', 'request', entry)
        this._completed.call(null, entry)
    })
})

Reactor.resend = function (statusCode, headers, body) {
    return Reactor.send({ statusCode: statusCode, headers: headers }, body)
}

Reactor.send = function (properties, buffer) {
    var headers = JSON.parse(JSON.stringify(properties.headers))
    delete headers['content-length']
    delete headers['transfer-encoding']
    return [ buffer, properties.statusCode, properties.statusMessage, headers ]
}

Reactor.string = function (statusCode, contentType, text) {
    return [ new Buffer(text), statusCode, { 'content-type': contentType } ]
}

Reactor.stream = function (properties, stream) {
    var headers = JSON.parse(JSON.stringify(properties.headers))
    delete headers['content-length']
    headers['transfer-encoding'] = 'chunked'
    return [ function (response) {
        stream.pipe(response)
    }, properties.statusCode, properties.statusMessage, headers ]
}

module.exports = Reactor
<commit_msg>Calculate headers duration.<commit_after>// Node.js API.
var http = require('http')

// Control-flow utilities.
var cadence = require('cadence')
var delta = require('delta')

// Route Sencha Connect middleware based on request method and URL patterns.
var dispatch = require('dispatch')

// Exceptions that you can catch by type.
var interrupt = require('interrupt').createInterrupter('reactor')

// Contextualized callbacks and event handlers.
var Operation = require('operation/variadic')

// Evented work queue.
var Turnstile = require('turnstile')
Turnstile.Queue = require('turnstile/queue')

// Catch exceptions based on a regex match of an error message or property.
var rescue = require('rescue')

// Return the first not null-like value.
var coalesce = require('extant')

// Do nothing.
var nop = require('nop')

function Constructor (object, dispatch) {
    this._object = object
    this._dispatch = dispatch
    this._use = []
    this._defaultUse = true
}

Constructor.prototype.useDefault = function () {
    this.use(require('express-auth-parser'))
    this.use(require('body-parser').urlencoded({ extended: false, limit: '64mb' }))
    this.use(require('body-parser').json({ limit: '64mb' }))
}

Constructor.prototype.use = function () {
    var vargs = Array.prototype.slice.call(arguments)
    this._defaultUse = false
    while (vargs.length) {
        var varg = vargs.shift()
        if (Array.isArray(varg)) {
            vargs.unshift(varg)
        } else {
            this._use.push(varg)
        }
    }
}

Constructor.prototype.dispatch = function () {
    var vargs = Array.prototype.slice.call(arguments)
    this._dispatch[vargs.shift()] = Operation(vargs, { object: this._object })
}

function handler (queue, before, operation) {
    return function (request, response, next) {
        var vargs = Array.prototype.slice.call(arguments, 3)
        request.entry = {
            when: {
                push: Date.now(),
                start: null,
                headers: null,
                finish: null
            },
            health: {
                push: JSON.parse(JSON.stringify(queue.turnstile.health)),
                start: null,
                finish: null
            },
            duration: {
                start: null,
                headers: null,
                finish: null,
            },
            request: {
                method: request.method,
                header: request.headers,
                url: request.url,
                vargs: vargs
            }
        }
        before(request, response, function (error) {
            queue.push({
                error: coalesce(error),
                operation: operation,
                request: request,
                response: response,
                vargs: vargs
            })
        })
    }
}

function Reactor (object, configurator) {
    var constructor = new Constructor(object, this._dispatch = {})
    configurator(constructor)
    this.turnstile = new Turnstile({
        Date: coalesce(constructor.Date, Date),
        turnstiles: coalesce(constructor.turnstiles, 24),
        timeout: coalesce(constructor.timeout)
    })
    this._queue = new Turnstile.Queue(this, '_respond', this.turnstile)
    this._logger = coalesce(constructor.logger, nop)
    this._completed = coalesce(constructor.completed, nop)
    this._object = object
    if (constructor._defaultUse) {
        constructor.useDefault()
    }
    var before = require('connect')()
    constructor._use.forEach(function (middleware) {
        before.use(middleware)
    })
    var dispatcher = {}
    for (var pattern in this._dispatch) {
        dispatcher[pattern] = handler(this._queue, before, this._dispatch[pattern])
    }
    this.middleware = require('connect')().use(dispatch(dispatcher))
}

Reactor.prototype._timeout = cadence(function () { throw 503 })

function createProperties (properties) {
    return {
        statusCode: properties.statusCode,
        headers: coalesce(properties.headers, {}),
        description: coalesce(properties.description)
    }
}

function raise (statusCode, description, headers) {
    throw interrupt('http', createProperties({
        statusCode: statusCode,
        description: description,
        headers: headers
    }))
}

Reactor.prototype._respond = cadence(function (async, envelope) {
    var work = envelope.body
    var next = work.next

    var entry = work.request.entry

    entry.when.start = Date.now()
    entry.health.start = JSON.parse(JSON.stringify(this.turnstile.health))

    work.request.entry = entry
    work.request.raise = raise

    if (envelope.timedout) {
        work.operation = Operation([ this, '_timeout' ])
    }

    var finish

    async(function () {
        async(function () {
            async([function () {
                async(function () {
                    if (work.error) {
                        throw work.error
                    }
                    work.operation.apply(null, [ work.request ].concat(work.vargs, async()))
                }, function () {
                    var vargs = Array.prototype.slice.call(arguments)

                    var result = vargs.shift()
                    var statusCode = (typeof vargs[0] == 'number') ? vargs.shift() : 200
                    var description = coalesce(http.STATUS_CODES[statusCode])
                    if (typeof vargs[0] == 'string') {
                        description = vargs.shift()
                    }
                    if (vargs[0] == null) {
                        vargs.shift()
                    }
                    var headers = coalesce(vargs.shift(), {})

                    interrupt.assert(description != null, 'unknown.http.status', { statusCode: statusCode })

                    return [ result, statusCode, description, headers ]
                })
            }, function (caught) {
                for (;;) {
                    try {
                        return rescue(/^reactor#http$/m, function (error) {
                            var statusCode = error.statusCode
                            var description = coalesce(error.description, http.STATUS_CODES[statusCode])
                            var headers = coalesce(error.headers, {})

                            interrupt.assert(description != null, 'unknown.http.status', { statusCode: statusCode })

                            headers['content-type'] = 'application/json'

                            return [ description, statusCode, description, headers ]
                        })(caught)
                    } catch (error) {
                        if (
                            typeof error == 'number' &&
                            !isNaN(error) &&
                            (error | 0) === error &&
                            Math.floor(error / 100) <= 5 &&
                            Math.floor(error / 100) >= 3
                        ) {
                            error = { statusCode: error }
                        } else if (typeof error == 'string') {
                            error = { statusCode: 307, location: error }
                        }
                        if (
                            typeof error == 'object' &&
                            typeof error.statusCode == 'number' &&
                            !isNaN(error.statusCode) &&
                            (error.statusCode | 0) === error.statusCode &&
                            Math.floor(error.statusCode / 100) <= 5 &&
                            Math.floor(error.statusCode / 100) >= 3
                        ) {
                            var properties = createProperties(error)
                            if (error.location) {
                                properties.headers.location = error.location
                            }
                            error = interrupt('http', properties)
                        } else {
                            entry.error = error
                            error = { statusCode: 500 }
                        }
                        caught = error
                    }
                }
            }])
        }, function (result, statusCode, description, headers) {
            var body, f
            if (typeof result == 'function') {
                f = result
            } else {
                if (typeof result == 'string') {
                    if (!('content-type' in headers)) {
                        headers['content-type'] = 'text/plain'
                        result = new Buffer(result)
                    } else if (headers['content-type'] == 'application/json') {
                        result = new Buffer(JSON.stringify(result) + '\n')
                    }
                } else if (!('content-type' in headers)) {
                    headers['content-type'] = 'application/json'
                    result = new Buffer(JSON.stringify(result) + '\n')
                }
                f = function (response) {
                    response.end(result)
                }
            }

            work.response.writeHead(statusCode, description, headers)

            entry.when.headers = Date.now()

            entry.statusCode = statusCode
            entry.description = description
            entry.headers = headers

            var finish = delta(async()).ee(work.response).on('finish')

            async([function () {
                async(function () {
                    if (result.length == 2) {
                        f.call(work.operation.object, work.response, async())
                    } else {
                        return [ f.call(work.operation.object, work.response) ]
                    }
                }, function () {
                    return []
                })
            }, function (error) {
                entry.error = error
                work.response.end()
                finish.cancel()
            }])
        })
    }, function () {
        entry.health.done = JSON.parse(JSON.stringify(this.turnstile.health))
        entry.when.finish = Date.now()
        entry.duration = {
            start: entry.when.start - entry.when.push,
            headers: entry.when.headers - entry.when.push,
            finish: entry.when.finish - entry.when.push
        }
        this._logger.call(null, 'info', 'request', entry)
        this._completed.call(null, entry)
    })
})

Reactor.resend = function (statusCode, headers, body) {
    return Reactor.send({ statusCode: statusCode, headers: headers }, body)
}

Reactor.send = function (properties, buffer) {
    var headers = JSON.parse(JSON.stringify(properties.headers))
    delete headers['content-length']
    delete headers['transfer-encoding']
    return [ buffer, properties.statusCode, properties.statusMessage, headers ]
}

Reactor.string = function (statusCode, contentType, text) {
    return [ new Buffer(text), statusCode, { 'content-type': contentType } ]
}

Reactor.stream = function (properties, stream) {
    var headers = JSON.parse(JSON.stringify(properties.headers))
    delete headers['content-length']
    headers['transfer-encoding'] = 'chunked'
    return [ function (response) {
        stream.pipe(response)
    }, properties.statusCode, properties.statusMessage, headers ]
}

module.exports = Reactor
<|endoftext|>


<commit_before>/* global describe, it, before, afterEach */

'use strict';

var should  = require( 'should' ),
	sinon   = require( 'sinon' ),
	gutil   = require( 'gulp-util' ),
	request = require( 'supertest' ),
	app     = require( '../' );

var URL  = 'http://localhost:1337',
	stub = null;

describe( 'gulp-develop-server', function() {

	before( function() {
		stub = sinon.stub( gutil, 'log' );
	});

	afterEach( function( done ) {
		var end = function() {
			stub.reset();
			done();
		};

		if( app.child && app.child.connected ) {
			return app.reset( end );
		}

		end();
	});

	it( 'should listen the server', function( done ) {
		var opt = {
			path: 'test/apps/app-no-message'
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should listen the server by checking message', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should listen the server by only checking message', function( done ) {
		var opt = {
			path: 'test/apps/app',
			delay: 0
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should listen the express server', function( done ) {
		var opt = {
			path: 'test/apps/app-express',
			delay: 1200
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should set `options.execArgv`', function( done ) {
		var opt = {
			path: 'test/apps/app',
			execArgv: [ '--harmony' ]
		};

		app.listen( opt, function() {
			should( app.options.execArgv ).eql( opt.execArgv );
			done();
		});
	});

	it( 'should set `options.env`', function( done ) {
		var opt = {
			path: 'test/apps/app',
			env: { NODE_ENV: 'production', PORT: 1338 }
		};

		app.listen( opt, function() {
			should( app.options.env ).eql( opt.env );
			done();
		});
	});

	it( 'should listen the server with `options.delay`', function( done ) {
		var opt = {
			path: 'test/apps/app-no-message',
			delay: 50
		};
		var now = Date.now();

		app.listen( opt, function() {
			var delay = Date.now() - now;

			should( delay ).within( 50, 80 );
			should( app.options.delay ).eql( opt.delay );
			done();
		});
	});

	it( 'should throw an error when options.path is empty', function() {
		should( function() {
			app.listen( {} );
		}).throw();
	});

	it( 'should throw an error if the server is broken', function( done ) {
		var opt = {
			path: 'test/apps/app-broken'
		};

		app.listen( opt, function( error ) {
			should.exist( error );
			should( gutil.log.lastCall.args[ 0 ] ).match( /server has error/ );
			done();
		});
	});

	it( 'should restart the server', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			var pid = app.child.pid;

			app.restart( function( error ) {
				should.not.exist( error );
				should( app.child.connected ).be.true;
				should( gutil.log.args.length ).eql( 4 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was restarted/ );
				should( app.child.pid ).not.eql( pid );
				request( URL ).get( '/' ).expect( 200 ).end( done );
			});
		});
	});

	it( 'should restart the server by Stream', function( done ) {
		var opt = {
			path: 'test/apps/app',
		};
		var file = new gutil.File({
			base: __dirname + '/test/apps/',
			cwd:  __dirname,
			path: __dirname + '/test/apps/app.js'
		});
		var stream = app();

		app.listen( opt, function() {
			var pid = app.child.pid;

			stream.write( file );

			stream.once( 'data', function() {
				should( app.child.connected ).be.true;
				should( gutil.log.args.length ).eql( 4 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was restarted/ );
				should( app.child.pid ).not.eql( pid );
				request( URL ).get( '/' ).expect( 200 ).end( done );
			});
		});
	});

	it( 'should restart the server properly when `server.restart` called twice.', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			var pid = app.child.pid;

			app.restart( function() {
				should( app.child.connected ).be.true;
				should( app.child.pid ).not.eql( pid );
				done();
			});

			app.restart( function( error ) {
				should( error ).match( /already received restart requests/ );
			});
		});
	});

	it( 'should throw an error if call `server.restart` before `server.listen`', function() {
		should( function() {
			app.restart();
		}).throw();
	});

	it( 'should kill the server', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			app.kill( function( error ) {
				should.not.exist( error );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});

	it( 'should kill the server by signal: `SIGTERM`', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			app.kill( 'SIGTERM', function( error ) {
				should.not.exist( error );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});

	it( 'should kill the server by options.signal: `SIGTERM`', function( done ) {
		var opt = {
			path: 'test/apps/app',
			killSignal: 'SIGTERM'
		};

		app.listen( opt, function() {
			should( app.options.killSignal ).eql( opt.killSignal );

			app.kill( function( error ) {
				should.not.exist( error );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});

	it( 'should reset the server', function( done ) {
		var opt = {
			path: 'test/apps/app',
			testKey: true
		};

		app.listen( opt, function() {
			should( opt ).have.ownProperty( 'testKey' );

			app.reset( function( error ) {
				should.not.exist( error );
				should( app.options ).not.have.ownProperty( 'testKey' );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});
});
<commit_msg>Add test for including current environment values #5<commit_after>/* global describe, it, before, afterEach */

'use strict';

var _       = require( 'lodash' ),
	should  = require( 'should' ),
	sinon   = require( 'sinon' ),
	gutil   = require( 'gulp-util' ),
	request = require( 'supertest' ),
	app     = require( '../' );

var URL  = 'http://localhost:1337',
	stub = null;

describe( 'gulp-develop-server', function() {

	before( function() {
		stub = sinon.stub( gutil, 'log' );
	});

	afterEach( function( done ) {
		var end = function() {
			stub.reset();
			done();
		};

		if( app.child && app.child.connected ) {
			return app.reset( end );
		}

		end();
	});

	it( 'should listen the server', function( done ) {
		var opt = {
			path: 'test/apps/app-no-message'
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should listen the server by checking message', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should listen the server by only checking message', function( done ) {
		var opt = {
			path: 'test/apps/app',
			delay: 0
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should listen the express server', function( done ) {
		var opt = {
			path: 'test/apps/app-express',
			delay: 1200
		};

		app.listen( opt, function( error ) {
			should.not.exist( error );
			should( app.child.connected ).be.true;
			should( gutil.log.lastCall.args[ 0 ] ).match( /server listening/ );
			request( URL ).get( '/' ).expect( 200 ).end( done );
		});
	});

	it( 'should set `options.execArgv`', function( done ) {
		var opt = {
			path: 'test/apps/app',
			execArgv: [ '--harmony' ]
		};

		app.listen( opt, function() {
			should( app.options.execArgv ).eql( opt.execArgv );
			done();
		});
	});

	it( 'should set `options.env`', function( done ) {
		var opt = {
			path: 'test/apps/app',
			env: { NODE_ENV: 'production', PORT: 1338 }
		};

		app.listen( opt, function() {
			should( app.options.env.NODE_ENV ).eql( opt.env.NODE_ENV );
			should( app.options.env.PORT ).eql( opt.env.PORT );
			done();
		});
	});

	it( 'should include current environmental variables by default', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};
		var envExtended = _.extend( app.defaultOptions.env, process.env );

		app.listen( opt, function() {
			should( app.options.env ).eql( envExtended );
			done();
		});
	});

	it( 'should listen the server with `options.delay`', function( done ) {
		var opt = {
			path: 'test/apps/app-no-message',
			delay: 50
		};
		var now = Date.now();

		app.listen( opt, function() {
			var delay = Date.now() - now;

			should( delay ).within( 50, 80 );
			should( app.options.delay ).eql( opt.delay );
			done();
		});
	});

	it( 'should throw an error when options.path is empty', function() {
		should( function() {
			app.listen( {} );
		}).throw();
	});

	it( 'should throw an error if the server is broken', function( done ) {
		var opt = {
			path: 'test/apps/app-broken'
		};

		app.listen( opt, function( error ) {
			should.exist( error );
			should( gutil.log.lastCall.args[ 0 ] ).match( /server has error/ );
			done();
		});
	});

	it( 'should restart the server', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			var pid = app.child.pid;

			app.restart( function( error ) {
				should.not.exist( error );
				should( app.child.connected ).be.true;
				should( gutil.log.args.length ).eql( 4 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was restarted/ );
				should( app.child.pid ).not.eql( pid );
				request( URL ).get( '/' ).expect( 200 ).end( done );
			});
		});
	});

	it( 'should restart the server by Stream', function( done ) {
		var opt = {
			path: 'test/apps/app',
		};
		var file = new gutil.File({
			base: __dirname + '/test/apps/',
			cwd:  __dirname,
			path: __dirname + '/test/apps/app.js'
		});
		var stream = app();

		app.listen( opt, function() {
			var pid = app.child.pid;

			stream.write( file );

			stream.once( 'data', function() {
				should( app.child.connected ).be.true;
				should( gutil.log.args.length ).eql( 4 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was restarted/ );
				should( app.child.pid ).not.eql( pid );
				request( URL ).get( '/' ).expect( 200 ).end( done );
			});
		});
	});

	it( 'should restart the server properly when `server.restart` called twice.', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			var pid = app.child.pid;

			app.restart( function() {
				should( app.child.connected ).be.true;
				should( app.child.pid ).not.eql( pid );
				done();
			});

			app.restart( function( error ) {
				should( error ).match( /already received restart requests/ );
			});
		});
	});

	it( 'should throw an error if call `server.restart` before `server.listen`', function() {
		should( function() {
			app.restart();
		}).throw();
	});

	it( 'should kill the server', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			app.kill( function( error ) {
				should.not.exist( error );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});

	it( 'should kill the server by signal: `SIGTERM`', function( done ) {
		var opt = {
			path: 'test/apps/app'
		};

		app.listen( opt, function() {
			app.kill( 'SIGTERM', function( error ) {
				should.not.exist( error );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});

	it( 'should kill the server by options.signal: `SIGTERM`', function( done ) {
		var opt = {
			path: 'test/apps/app',
			killSignal: 'SIGTERM'
		};

		app.listen( opt, function() {
			should( app.options.killSignal ).eql( opt.killSignal );

			app.kill( function( error ) {
				should.not.exist( error );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});

	it( 'should reset the server', function( done ) {
		var opt = {
			path: 'test/apps/app',
			testKey: true
		};

		app.listen( opt, function() {
			should( opt ).have.ownProperty( 'testKey' );

			app.reset( function( error ) {
				should.not.exist( error );
				should( app.options ).not.have.ownProperty( 'testKey' );
				should( app.child ).eql( null );
				should( gutil.log.args.length ).eql( 2 );
				should( gutil.log.lastCall.args[ 0 ] ).match( /server was stopped/ );
				done();
			});
		});
	});
});
<|endoftext|>


<commit_before>/*jshint globalstrict:true, es5:true, node:true, sub:true*/
'use strict';

var Game = require('./game.js');
var events = require('../shared/events.js');
var config = require('../shared/config.js');

/**
 * @param {Server} server
 * @param {number} id
 * @param {Object} filter
 * @constructor
 */
function Room(server, id, filter) {
    this.server = server;

    this.id = id;
    this.clients = [];
    this.points = [];
    this.inProgress = false;

    this.pub      = !!filter['public'];
    this.friendly = !!filter['friendly'];
    this.capacity = config.ROOM_CAPACITY;

    this.level = 0;
    this.game = new Game(this, this.level);

    this._disconnected = [];
    this._buffer = [];
}

module.exports = Room;

/**
 * @enum {number}
 */
Room.RANK = {
    LEADING: 0,
    NEUTRAL: 1,
    LOSING : 2
};

Room.prototype = {

    destruct: function() {
        this.game.destruct();
        this.game = null;
        this.clients = null;
    },

    emitState: function() {
        var names = this.names();
        for (var i = 0, m = this.clients.length; i < m; i++) {
            var data = [i, this.level, names, this.points];
            this.clients[i].emit(events.CLIENT_ROOM_INDEX, data);
        }
    },

    /**
     * @param {Client} client
     * @return {Room}
     */
    join: function(client) {
        var index = this.clients.push(client) - 1;
        client.socket.join(this.id);
        client.roomid = this.id;
        this.points[index] = 0;

        this.emitState();
        this.broadcast(events.CLIENT_CHAT_NOTICE, '{' + index + '} joined', client);

        if (this.isFull()) {
            this.game.countdown();
        }

        return this;
    },

    /**
     * @param {Client} client
     */
    disconnect: function(client) {
        var index = this.clients.indexOf(client);

        // Leave during game, clean up after round ends
        if (this.inProgress) {
            this.game.clientDisconnect(client);
            this._disconnected.push(client);
        }

        // Leave before game, clean up immediately
        else {
            this.clients.splice(index, 1);
            this.emitState();
            if (!this.clients.length) {
                this.server.roomManager.remove(this);
            }
        }

        this.emit(events.CLIENT_CHAT_NOTICE, '{' + index + '} left');
    },

    /**
     * @return {Game}
     */
    newRound: function() {
        // Before round starts
        this.game.destruct();
        this._removeDisconnectedClients(this._disconnected);

        // Check if Room was destructed
        if (!this.clients.length) {
            this.server.roomManager.remove(this);
            return null;
        }

        // Round start
        this.game = new Game(this, this.level);
        this.emitState();
        this.game.countdown();
        return this.game;
    },

    /**
     * @return {boolean}
     */
    isFull: function() {
        return (this.clients.length === this.capacity);
    },

    /**
     * @return {Array.<string>}
     */
    names: function() {
        var names = [];
        for (var i = 0, m = this.clients.length; i < m; i++) {
            names.push(this.clients[i].name);
        }
        return names;
    },

    /**
     * Send data to everyone in the room.
     * @param {string} name
     * @param {*} data
     */
    emit: function(name, data) {
        this.server.io.sockets.in(this.id).emit(name, data);
    },

    /**
     * Buffer events to be sent later using flush()
     * @param {string} name
     * @param {*} data
     * @return {Room}
     */
    buffer: function(name, data) {
        this._buffer.push([name, data]);
        return this;
    },

    /**
     * Send buffer
     * @return {Room}
     */
    flush: function() {
        this.emit(events.CLIENT_COMBI_EVENTS, this._buffer);
        this._buffer = [];
        return this;
    },

    /**
     * Send data to everyone else in the room.
     * @param {string} name
     * @param {*} data
     * @param {Client} exclude
     */
    broadcast: function(name, data, exclude) {
        exclude.socket.broadcast.to(this.id).emit(name, data);
    },

    /**
     * @param client
     * @param {*} losing
     * @param {*} leading
     * @param {*} neutral
     * @return {*}
     */
    rank: function(client, leading, neutral, losing) {
        var clientPoints, rankTmp = 0;
        if (this.clients.length === 1) {
            return neutral;
        } else {
            clientPoints = this.points[this.clients.indexOf(client)];
            for (var i = 0, m = this.points.length; i < m; i++) {
                if (clientPoints > this.points[i]) {
                    rankTmp++;
                } else if (clientPoints < this.points[i]) {
                    rankTmp--;
                }
            }
            if (rankTmp > 0) {
                return leading;
            } else if (rankTmp === 0) {
                return neutral;
            } else {
                return losing;
            }
        }
    },

    /**
     * @param {Array.<Client>} clients
     * @private
     */
    _removeDisconnectedClients: function(clients) {
        if (clients) {
            for (var i = 0, m = clients.length; i < m; i++) {
                this.clients.splice(this.clients.indexOf(clients[i]), 1);
                this.server.removeClient(clients[i]);
            }
        }
        this._disconnected = [];
    }

};<commit_msg>Switch levels<commit_after>/*jshint globalstrict:true, es5:true, node:true, sub:true*/
'use strict';

var Game = require('./game.js');
var events = require('../shared/events.js');
var config = require('../shared/config.js');
var levels = require('../shared/levels.js');

/**
 * @param {Server} server
 * @param {number} id
 * @param {Object} filter
 * @constructor
 */
function Room(server, id, filter) {
    this.server = server;

    this.id = id;
    this.clients = [];
    this.points = [];
    this.inProgress = false;

    this.pub      = !!filter['public'];
    this.friendly = !!filter['friendly'];
    this.capacity = config.ROOM_CAPACITY;

    this.level = 0;
    this.game = new Game(this, this.level);

    this._disconnected = [];
    this._buffer = [];
}

module.exports = Room;

/**
 * @enum {number}
 */
Room.RANK = {
    LEADING: 0,
    NEUTRAL: 1,
    LOSING : 2
};

Room.prototype = {

    destruct: function() {
        this.game.destruct();
        this.game = null;
        this.clients = null;
    },

    emitState: function() {
        var names = this.names();
        for (var i = 0, m = this.clients.length; i < m; i++) {
            var data = [i, this.level, names, this.points];
            this.clients[i].emit(events.CLIENT_ROOM_INDEX, data);
        }
    },

    /**
     * @param {Client} client
     * @return {Room}
     */
    join: function(client) {
        var index = this.clients.push(client) - 1;
        client.socket.join(this.id);
        client.roomid = this.id;
        this.points[index] = 0;

        this.emitState();
        this.broadcast(events.CLIENT_CHAT_NOTICE, '{' + index + '} joined', client);

        if (this.isFull()) {
            this.game.countdown();
        }

        return this;
    },

    /**
     * @param {Client} client
     */
    disconnect: function(client) {
        var index = this.clients.indexOf(client);

        // Leave during game, clean up after round ends
        if (this.inProgress) {
            this.game.clientDisconnect(client);
            this._disconnected.push(client);
        }

        // Leave before game, clean up immediately
        else {
            this.clients.splice(index, 1);
            this.emitState();
            if (!this.clients.length) {
                this.server.roomManager.remove(this);
            }
        }

        this.emit(events.CLIENT_CHAT_NOTICE, '{' + index + '} left');
    },

    /**
     * @return {Game}
     */
    newRound: function() {
        // Before round starts
        this.game.destruct();
        this._removeDisconnectedClients(this._disconnected);

        // Check if Room was destructed
        if (!this.clients.length) {
            this.server.roomManager.remove(this);
            return null;
        }

        // Next level
        var level = ++this.level;
        if (typeof levels[level] === 'undefined') {
            level = 0;
        }

        // Round start
        this.game = new Game(this, level);
        this.emitState();
        this.game.countdown();
        return this.game;
    },

    /**
     * @return {boolean}
     */
    isFull: function() {
        return (this.clients.length === this.capacity);
    },

    /**
     * @return {Array.<string>}
     */
    names: function() {
        var names = [];
        for (var i = 0, m = this.clients.length; i < m; i++) {
            names.push(this.clients[i].name);
        }
        return names;
    },

    /**
     * Send data to everyone in the room.
     * @param {string} name
     * @param {*} data
     */
    emit: function(name, data) {
        this.server.io.sockets.in(this.id).emit(name, data);
    },

    /**
     * Buffer events to be sent later using flush()
     * @param {string} name
     * @param {*} data
     * @return {Room}
     */
    buffer: function(name, data) {
        this._buffer.push([name, data]);
        return this;
    },

    /**
     * Send buffer
     * @return {Room}
     */
    flush: function() {
        this.emit(events.CLIENT_COMBI_EVENTS, this._buffer);
        this._buffer = [];
        return this;
    },

    /**
     * Send data to everyone else in the room.
     * @param {string} name
     * @param {*} data
     * @param {Client} exclude
     */
    broadcast: function(name, data, exclude) {
        exclude.socket.broadcast.to(this.id).emit(name, data);
    },

    /**
     * @param client
     * @param {*} losing
     * @param {*} leading
     * @param {*} neutral
     * @return {*}
     */
    rank: function(client, leading, neutral, losing) {
        var clientPoints, rankTmp = 0;
        if (this.clients.length === 1) {
            return neutral;
        } else {
            clientPoints = this.points[this.clients.indexOf(client)];
            for (var i = 0, m = this.points.length; i < m; i++) {
                if (clientPoints > this.points[i]) {
                    rankTmp++;
                } else if (clientPoints < this.points[i]) {
                    rankTmp--;
                }
            }
            if (rankTmp > 0) {
                return leading;
            } else if (rankTmp === 0) {
                return neutral;
            } else {
                return losing;
            }
        }
    },

    /**
     * @param {Array.<Client>} clients
     * @private
     */
    _removeDisconnectedClients: function(clients) {
        if (clients) {
            for (var i = 0, m = clients.length; i < m; i++) {
                this.clients.splice(this.clients.indexOf(clients[i]), 1);
                this.server.removeClient(clients[i]);
            }
        }
        this._disconnected = [];
    }

};<|endoftext|>


<commit_before>module("Canvas");

/**
 * Test to make sure the canvas was created
 */
test("Canvas Creation", function()
{
	notEqual(canvas, undefined, "Test if canvas is undefined");
	notEqual(canvas, null, "Test if canvas is null");
});

/**
 * Test adding a process then removing it
 */
test("Add Process", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addProcess(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.remove(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding a multi-process then removing it
 */
test("Add Multi-process", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addMultiProcess(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.remove(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding a datastore then removing it
 */
test("Add Datastore", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addDatastore(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.remove(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding an external interactor then removing it
 */
test("Add External Interactor", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addExtInteractor(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.remove(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding and removing multiple elements
 */
test("Num Elements", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with 0 elements");

	var e1 = canvas.addExtInteractor(100, 100);
	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	var e2 = canvas.addDatastore(100, 100);
	equal(canvas.getNumberOfElements(), 2, "Test with 2 elements");

	var e3 = canvas.addMultiProcess(100, 100);
	equal(canvas.getNumberOfElements(), 3, "Test with 3 elements");

	var e4 = canvas.addProcess(100, 100);
	equal(canvas.getNumberOfElements(), 4, "Test with 4 elements");

	canvas.remove(e4);
	equal(canvas.getNumberOfElements(), 3, "Test with 3 elements");

	canvas.remove(e3);
	equal(canvas.getNumberOfElements(), 2, "Test with 2 elements");

	canvas.remove(e2);
	equal(canvas.getNumberOfElements(), 1, "Test with 1 elements");

	canvas.remove(e1);
	equal(canvas.getNumberOfElements(), 0, "Test with 0 elements");

});<commit_msg>Updated tests to reflect Element changes<commit_after>module("Canvas");

/**
 * Test to make sure the canvas was created
 */
test("Canvas Creation", function()
{
	notEqual(canvas, undefined, "Test if canvas is undefined");
	notEqual(canvas, null, "Test if canvas is null");
});

/**
 * Test adding a process then removing it
 */
test("Add Process", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addProcess(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.removeElement(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding a multi-process then removing it
 */
test("Add Multi-process", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addMultiProcess(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.removeElement(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding a datastore then removing it
 */
test("Add Datastore", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addDatastore(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.removeElement(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding an external interactor then removing it
 */
test("Add External Interactor", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with no elements");

	var p = canvas.addExtInteractor(100, 100);

	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	notEqual(p, undefined, "Test if element is undefined");
	notEqual(p, null, "Test if element is null")

	canvas.removeElement(p);
	equal(canvas.getNumberOfElements(), 0, "Test after remove");
});

/**
 * Test adding and removing multiple elements
 */
test("Num Elements", function()
{
	equal(canvas.getNumberOfElements(), 0, "Test with 0 elements");

	var e1 = canvas.addExtInteractor(100, 100);
	equal(canvas.getNumberOfElements(), 1, "Test with 1 element");

	var e2 = canvas.addDatastore(100, 100);
	equal(canvas.getNumberOfElements(), 2, "Test with 2 elements");

	var e3 = canvas.addMultiProcess(100, 100);
	equal(canvas.getNumberOfElements(), 3, "Test with 3 elements");

	var e4 = canvas.addProcess(100, 100);
	equal(canvas.getNumberOfElements(), 4, "Test with 4 elements");

	canvas.removeElement(e4);
	equal(canvas.getNumberOfElements(), 3, "Test with 3 elements");

	canvas.removeElement(e3);
	equal(canvas.getNumberOfElements(), 2, "Test with 2 elements");

	canvas.removeElement(e2);
	equal(canvas.getNumberOfElements(), 1, "Test with 1 elements");

	canvas.removeElement(e1);
	equal(canvas.getNumberOfElements(), 0, "Test with 0 elements");
});<|endoftext|>


<commit_before>

(function () {
  "use strict";

  this.Skeletor = this.Skeletor || {};
  this.Skeletor.Smartboard = this.Skeletor.Smartboard || {};
  var Smartboard = this.Skeletor.Smartboard;

  Smartboard.Router = new (Backbone.Router.extend({
    routes: {
      '' : 'index',
      'ben': 'initClassBen',
      'michael': 'initClassMichael'
    },
    initialize: function() {

    },
    index: function() {
      console.log("routing on");
    },
    initClassBen: function () {
      Skeletor.Smartboard.init('ben');
    },
    initClassMichael: function () {
      Skeletor.Smartboard.init('michael');
    },
    start: function() {
      // to allow single page app with various routes
      Backbone.history.start();
      // Skeletor.Smartboard.init();
    }
  }))();

  this.Skeletor.Smartboard = Smartboard;
  return this.Skeletor.Smartboard;

}).call(this);<commit_msg>Allowing test board to work<commit_after>

(function () {
  "use strict";

  this.Skeletor = this.Skeletor || {};
  this.Skeletor.Smartboard = this.Skeletor.Smartboard || {};
  var Smartboard = this.Skeletor.Smartboard;

  Smartboard.Router = new (Backbone.Router.extend({
    routes: {
      '' : 'index',
      'ben': 'initClassBen',
      'michael': 'initClassMichael',
      'test': 'initClassTest'
    },
    initialize: function() {

    },
    index: function() {
      console.log("routing on");
    },
    initClassBen: function () {
      Skeletor.Smartboard.init('ben');
    },
    initClassMichael: function () {
      Skeletor.Smartboard.init('michael');
    },
    initClassTest: function () {
      Skeletor.Smartboard.init('test');
    },
    start: function() {
      // to allow single page app with various routes
      Backbone.history.start();
      // Skeletor.Smartboard.init();
    }
  }))();

  this.Skeletor.Smartboard = Smartboard;
  return this.Skeletor.Smartboard;

}).call(this);<|endoftext|>


<commit_before>// create new array
// const array = [];

// const array2 = [1, 2, 3, 4];
// array2.length; // get array lenght
// const item1 = array2[3]; // get single array item
// array2[3] = 10; // set array item

const array3 = [10, 20, 30];

let sum = 0;

// for cycle
// sum = array3[0] + array3[1] + array3[2]

console.log(sum, sum === 60);
<commit_msg>arrays<commit_after>// create new array
// const array = [];

// const array2 = [1, 2, 3, 4];
// array2.length; // get array lenght
// const item1 = array2[3]; // get single array item
// array2[3] = 10; // set array item

const array3 = [10, 1, 3, 8, 95, 89, 20, 30];

let sum = 0;

for (let i = 0; i < array3.length; i += 1) {
  if (array3[i] % 10 === 0) {
    sum += array3[i];
  }
}

// for cycle
// sum = array3[0] + array3[1] + array3[2]

console.log(sum, sum === 60);
<|endoftext|>


<commit_before>
var cyberDojo = (function($cd, $j) {

  $cd.help = function(avatar) {
    var imageSize = 50;
    var avatarImageHtml =
        '';

    var br = '
';

    var welcomeHtml = ''
      + '
'
        + '<input type="button" class="button" value="Run-Tests"/>'
        + ' to create a new traffic-light and display the'
        + ' test result in the output tab in '
        +   ' red  if the tests ran but one or more failed,
'
        +   ' amber  if the tests could not be run,
'
        +   ' green  if the tests ran and all passed.
'
      + '
'

      + br

      + '
'
        + '
'
          + '
'
            + ''
              + '
'
              +   '<input type="radio"'
              +          'name="filename"'
              +          'value="filename"/>'
              +   'filename'
              + '
'
            + '	'
            + 'to open a file for editing.	'
          + '
'
        + '
'
      + '
'

      + br

      + '
'
        + '
'
        + '
'
        + ''
        +   '
'
        +     ''
        +     ''
        +     ''
        +   '
'
        + '	'
        + ''
        +   '
'
        +     ''
        +     ''
        +     ''
        +   '
'
        + '	'
        + ''
        +   '
'
        +     ''
        +     ''
        +     ''
        +   '
'
        + '	'
        + 'to view a diff.	'
        + '
'
        + '
'
      + '
'

      + '
'

      + '
'
        + '<input type="button" class="button" value="Post"/>'
        + ' to send a message to everyone doing the kata.
'
      + '
'

      + br

      + '
'
        + ''
        + '  to go to the home page.'
      + '
'

      + br

      + avatarImageHtml
      + 'If you need to '
      + '<input type="button" class="button" value="Resume-Coding"/>'
      + ' please remember that this computer is the ' + avatar + '.'
      + '';

    var welcome = $j('
')
      .html(welcomeHtml)
      .dialog({
        autoOpen: false,
        width: 600,
        title: "Click...",
        modal: true,
        buttons: {
          ok: function() {
            $j(this).dialog('close');
          }
        }
      });
    welcome.dialog('open');
  };

  return $cd;
})(cyberDojo || {}, $j);
<commit_msg>corrected the yin-yang path in the help dialog<commit_after>
var cyberDojo = (function($cd, $j) {

  $cd.help = function(avatar) {
    var imageSize = 50;
    var avatarImageHtml =
        '';

    var br = '
';

    var welcomeHtml = ''
      + '
'
        + '<input type="button" class="button" value="Run-Tests"/>'
        + ' to create a new traffic-light and display the'
        + ' test result in the output tab in '
        +   ' red  if the tests ran but one or more failed,
'
        +   ' amber  if the tests could not be run,
'
        +   ' green  if the tests ran and all passed.
'
      + '
'

      + br

      + '
'
        + '
'
          + '
'
            + ''
              + '
'
              +   '<input type="radio"'
              +          'name="filename"'
              +          'value="filename"/>'
              +   'filename'
              + '
'
            + '	'
            + 'to open a file for editing.	'
          + '
'
        + '
'
      + '
'

      + br

      + '
'
        + '
'
        + '
'
        + ''
        +   '
'
        +     ''
        +     ''
        +     ''
        +   '
'
        + '	'
        + ''
        +   '
'
        +     ''
        +     ''
        +     ''
        +   '
'
        + '	'
        + ''
        +   '
'
        +     ''
        +     ''
        +     ''
        +   '
'
        + '	'
        + 'to view a diff.	'
        + '
'
        + '
'
      + '
'

      + '
'

      + '
'
        + '<input type="button" class="button" value="Post"/>'
        + ' to send a message to everyone doing the kata.
'
      + '
'

      + br

      + '
'
        + ''
        + '  to go to the home page.'
      + '
'

      + br

      + avatarImageHtml
      + 'If you need to '
      + '<input type="button" class="button" value="Resume-Coding"/>'
      + ' please remember that this computer is the ' + avatar + '.'
      + '';

    var welcome = $j('
')
      .html(welcomeHtml)
      .dialog({
        autoOpen: false,
        width: 600,
        title: "Click...",
        modal: true,
        buttons: {
          ok: function() {
            $j(this).dialog('close');
          }
        }
      });
    welcome.dialog('open');
  };

  return $cd;
})(cyberDojo || {}, $j);
<|endoftext|>