<commit_before>"use strict";

var request = require("request");

var DimmerItem = function(widget,platform,homebridge) {

    this.platform = platform;
    this.uuidAction = widget.uuidAction; //to control a dimmer, use the uuidAction
    this.stateUuid = widget.states.position; //a dimmer always has a state called position, which is the uuid which will receive the event to read
    this.currentState = undefined; //will be a value between 0 and 100 for dimmers

    DimmerItem.super_.call(this, widget,platform,homebridge);
};

// Register a listener to be notified of changes in this items value
DimmerItem.prototype.initListener = function() {
    this.platform.ws.registerListenerForUUID(this.stateUuid, this.callBack.bind(this));
};

DimmerItem.prototype.callBack = function(value) {
    //function that gets called by the registered ws listener
    //console.log("Got new state for dimmer " + value);
    this.currentState = value;

    //also make sure this change is directly communicated to HomeKit
    this.setFromLoxone = true;
    this.otherService
        .getCharacteristic(this.homebridge.hap.Characteristic.On)
        .setValue(this.currentState > 0);
    this.otherService
        .getCharacteristic(this.homebridge.hap.Characteristic.Brightness)
        .setValue(this.currentState,
            function() {
                this.setFromLoxone = false;
            }.bind(this)
        );
};

DimmerItem.prototype.getOtherServices = function() {

    //setting variable to skip update for intial value
    this.setInitialState = true;

    var otherService = new this.homebridge.hap.Service.Lightbulb();

    otherService.getCharacteristic(this.homebridge.hap.Characteristic.On)
        .on('set', this.setItemPowerState.bind(this))
        .on('get', this.getItemPowerState.bind(this))
        .setValue(this.currentState > 0);

    otherService.getCharacteristic(this.homebridge.hap.Characteristic.Brightness)
        .on('set', this.setItemState.bind(this))
        .on('get', this.getItemState.bind(this))
        .setValue(this.currentState);

    return otherService;
};

DimmerItem.prototype.getItemState = function(callback) {
    //returns brightness value
    callback(undefined, this.currentState);
};

DimmerItem.prototype.getItemPowerState = function(callback) {
    //returns true if currentState is > 0
    callback(undefined, this.currentState > 0);
};

DimmerItem.prototype.setItemState = function(value, callback) {

    //sending new state (brighness) to loxone
    //added some logic to prevent a loop when the change because of external event captured by callback

    var self = this;

    if (this.setInitialState) {
        this.setInitialState = false;
        callback();
        return;
    }

    if (this.setFromLoxone) {
        callback();
        return;
    }

    if(value === undefined) {
        //happens at initial load
        callback();
        return;
    }

    this.log("[dimmer] iOS - send brightness message to " + this.name + ": " + value);
    var command = value; //Loxone expects a value between 0 and 100
    if (typeof this.platform.ws != 'undefined' && this.platform.ws.is_connected()) {
      this.platform.ws.sendCommand(this.uuidAction, command);
    }
    callback();

};

DimmerItem.prototype.setItemPowerState = function(value, callback) {

    //sending new state (on/off) to loxone
    //added some logic to prevent a loop when the change because of external event captured by callback

    var self = this;

    if (this.setInitialState) {
        this.setInitialState = false;
        callback();
        return;
    }

    if (this.setFromLoxone) {
        callback();
        return;
    }

    if(value === undefined) {
        //happens at initial load
        callback();
        return;
    }

    this.log("[dimmer] iOS - send on/off message to " + this.name + ": " + value);
    var command = (value == '1') ? 'On' : 'Off';
    if (this.platform.ws.is_connected()) {
      this.platform.ws.sendCommand(this.uuidAction, command);
    }
    callback();

};

module.exports = DimmerItem;
<commit_msg>altered merge request<commit_after>"use strict";

var request = require("request");

var DimmerItem = function(widget,platform,homebridge) {

    this.platform = platform;
    this.uuidAction = widget.uuidAction; //to control a dimmer, use the uuidAction
    this.stateUuid = widget.states.position; //a dimmer always has a state called position, which is the uuid which will receive the event to read
    this.currentState = undefined; //will be a value between 0 and 100 for dimmers

    DimmerItem.super_.call(this, widget,platform,homebridge);
};

// Register a listener to be notified of changes in this items value
DimmerItem.prototype.initListener = function() {
    this.platform.ws.registerListenerForUUID(this.stateUuid, this.callBack.bind(this));
};

DimmerItem.prototype.callBack = function(value) {
    //function that gets called by the registered ws listener
    //console.log("Got new state for dimmer " + value);
    this.currentState = value;

    //also make sure this change is directly communicated to HomeKit
    this.setFromLoxone = true;
    this.otherService
        .getCharacteristic(this.homebridge.hap.Characteristic.On)
        .setValue(this.currentState > 0);
    this.otherService
        .getCharacteristic(this.homebridge.hap.Characteristic.Brightness)
        .setValue(this.currentState,
            function() {
                this.setFromLoxone = false;
            }.bind(this)
        );
};

DimmerItem.prototype.getOtherServices = function() {

    //setting variable to skip update for intial value
    this.setInitialState = true;

    var otherService = new this.homebridge.hap.Service.Lightbulb();

    otherService.getCharacteristic(this.homebridge.hap.Characteristic.On)
        .on('set', this.setItemPowerState.bind(this))
        .on('get', this.getItemPowerState.bind(this))
        .setValue(this.currentState > 0);

    otherService.getCharacteristic(this.homebridge.hap.Characteristic.Brightness)
        .on('set', this.setItemState.bind(this))
        .on('get', this.getItemState.bind(this))
        .setValue(this.currentState);

    return otherService;
};

DimmerItem.prototype.getItemState = function(callback) {
    //returns brightness value
    callback(undefined, this.currentState);
};

DimmerItem.prototype.getItemPowerState = function(callback) {
    //returns true if currentState is > 0
    callback(undefined, this.currentState > 0);
};

DimmerItem.prototype.setItemState = function(value, callback) {

    //sending new state (brighness) to loxone
    //added some logic to prevent a loop when the change because of external event captured by callback

    var self = this;

    if (this.setInitialState) {
        this.setInitialState = false;
        callback();
        return;
    }

    if (this.setFromLoxone) {
        callback();
        return;
    }

    if(value === undefined) {
        //happens at initial load
        callback();
        return;
    }

    this.log("[dimmer] iOS - send brightness message to " + this.name + ": " + value);
    var command = value; //Loxone expects a value between 0 and 100
    if (typeof this.platform.ws != 'undefined') {
      this.platform.ws.sendCommand(this.uuidAction, command);
    }
    callback();

};

DimmerItem.prototype.setItemPowerState = function(value, callback) {

    //sending new state (on/off) to loxone
    //added some logic to prevent a loop when the change because of external event captured by callback

    var self = this;

    if (this.setInitialState) {
        this.setInitialState = false;
        callback();
        return;
    }

    if (this.setFromLoxone) {
        callback();
        return;
    }

    if(value === undefined) {
        //happens at initial load
        callback();
        return;
    }

    this.log("[dimmer] iOS - send on/off message to " + this.name + ": " + value);
    var command = (value == '1') ? 'On' : 'Off';
    if (typeof this.platform.ws != 'undefined') {
      this.platform.ws.sendCommand(this.uuidAction, command);
    }
    callback();

};

module.exports = DimmerItem;
<|endoftext|>


<commit_before>var Transform = require('stream').Transform;
var inherits = require('util').inherits;

function Splitter(matcher, opts) {
  if (!(this instanceof Splitter)) {
    return new Splitter(matcher, opts);
  }
  Transform.call(this, opts);
  this.matcher = matcher || '\n';
  this.buffer = '';
}
inherits(Splitter, Transform);

Splitter.prototype._transform = function (chunk, encoding, cb) {
  var pieces = (this.buffer + chunk).split(this.matcher);
  this.buffer = pieces.pop();
  for (var i = 0; i < pieces.length; i += 1) {
    this.push(pieces[i]);
  }
  cb();
};

Splitter.prototype._flush = function (cb) {
  this.push(this.buffer);
  cb();
};

module.exports = Splitter;

if (module === require.main) {
  process.stdin.pipe(Splitter()).pipe(process.stdout);
}
<commit_msg>dont have unnecessary code in exported file<commit_after>var Transform = require('stream').Transform;
var inherits = require('util').inherits;

function Splitter(matcher, opts) {
  if (!(this instanceof Splitter)) {
    return new Splitter(matcher, opts);
  }
  Transform.call(this, opts);
  this.matcher = matcher || '\n';
  this.buffer = '';
}
inherits(Splitter, Transform);

Splitter.prototype._transform = function (chunk, encoding, cb) {
  var pieces = (this.buffer + chunk).split(this.matcher);
  this.buffer = pieces.pop();
  for (var i = 0; i < pieces.length; i += 1) {
    this.push(pieces[i]);
  }
  cb();
};

Splitter.prototype._flush = function (cb) {
  this.push(this.buffer);
  cb();
};

module.exports = Splitter;
<|endoftext|>


<commit_before>process.env.DEBUG = '*';

const PluginLoader = require('../..');
const EventEmitter = require('events');

var app = new EventEmitter();
app.name = 'App';
app.on('plugins.ready', function(){
    app.logger.info('Application plugins loaded');
    app.debug('here we are!!');
});

const manager = new PluginLoader({
    context: app,
    basepath: __dirname,
    afterMount: function(context){
        context.emit('plugins.ready');
    }
});

manager.find('./plugins').then((plugins) => {
    plugins.push({
        'debug': function(plugin, context, options){
        context.debug = plugin('in-load');
    }});

    return manager.load(plugins);
})
.then((plugins)=>{
    return manager.mount(plugins)
})
.catch(console.error);
<commit_msg>load: cleanup<commit_after>process.env.DEBUG = '*';

const PluginLoader = require('../..');
const EventEmitter = require('events');

var app = new EventEmitter();
app.name = 'App';
app.on('plugins.ready', function(){
    app.logger.info('Application plugins loaded');
    app.debug('here we are!!');
});

const manager = new PluginLoader({
    context: app,
    basepath: __dirname,
    afterMount: (context) => context.emit('plugins.ready')
});

manager.find('./plugins').then((plugins) => {
    plugins.push({
        'debug': function(plugin, context, options){
        context.debug = plugin('in-load');
    }});

    return manager.load(plugins);
})
.then((plugins)=>{
    return manager.mount(plugins)
})
.catch(console.error);
<|endoftext|>


<commit_before>var http = require('http'),
   express = require('express'),
   path = require('path'),
   readLine = require('readline'),
   debugCreator = require('debug'),
   favicon = require('static-favicon'),
   logger = require('morgan');

var app = express(),
   serverLogger = debugCreator('express');

// express settings
app.set('port', process.argv[2] || process.env.PORT || 8999);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// middleware setup
app.use(favicon());
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', function(req, res) {
   var settings = {
      title: 'Express'
   };
   res.render('index', settings);
});

// catch 404 and redirect to index
app.use(function(req, res) {
   res.redirect('/');
});

var server = http.createServer(app);
server.listen(app.get('port'), function() {
  serverLogger('Express server listening on port ' + server.address().port);
});

// graceful shutdown on windows
if (process.platform === 'win32') {
   var rl = readLine.createInterface({
      input: process.stdin,
      output: process.stdout
   });

   rl.on('SIGINT', function() {
      process.emit('SIGINT');
   });
}

process.on('SIGINT', function() {

   process.exit();
});
<commit_msg>feat(APPLICATION_SETTINGS): set APPLICATION_SETTINGS<commit_after>var http = require('http'),
   express = require('express'),
   path = require('path'),
   readLine = require('readline'),
   debugCreator = require('debug'),
   favicon = require('static-favicon'),
   logger = require('morgan');

var APPLICATION_SETTINGS = {
      ip: 'localhost',
      port: 8950,
      examplesPortRange: {
         begin: 8951,
         end: 8999
      }
   };

var app = express(),
   serverLogger = debugCreator('express');

// express settings
app.set('ip', APPLICATION_SETTINGS.ip);
app.set('port', APPLICATION_SETTINGS.port);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// middleware setup
app.use(favicon());
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', function(req, res) {
   var settings = {
      title: 'Express'
   };
   res.render('index', settings);
});

// catch 404 and redirect to index
app.use(function(req, res) {
   res.redirect('/');
});

var server = http.createServer(app);
server.listen(app.get('port'), function() {
  serverLogger('Express server listening on port ' + server.address().port);
});

// graceful shutdown on windows
if (process.platform === 'win32') {
   var rl = readLine.createInterface({
      input: process.stdin,
      output: process.stdout
   });

   rl.on('SIGINT', function() {
      process.emit('SIGINT');
   });
}

process.on('SIGINT', function() {

   process.exit();
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function () {
  this.route('cabins', {path: '/hytter', resetNamespace: true}, function () {
    this.route('edit', {path: '/:id'});
  });

  this.route('session.login', {path: '/logg-inn'});
  this.route('session.logout', {path: '/logg-ut'});
});

export default Router;
<commit_msg>Add route for adding new cabin<commit_after>import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function () {
  this.route('cabins', {path: '/hytter', resetNamespace: true}, function () {
    this.route('edit', {path: '/:id'});
    this.route('new', {path: '/ny'});
  });

  this.route('session.login', {path: '/logg-inn'});
  this.route('session.logout', {path: '/logg-ut'});
});

export default Router;
<|endoftext|>


<commit_before>Template.registerHelper("activeRoute", function(route) {
	var currentRoute = Router.current().route.getName();
	return currentRoute === route ? " active" : "";
});

Template.registerHelper("calendarTime", function(date) {
	if(date) {
		return moment(date).calendar();
	}
	return "Unknown";
});

Template.registerHelper("equals", function(a, b) {
	return a === b;
});

Template.navigation.events({
	"click #logout": function(e) {
		Meteor.logout(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("login");
			}
		});
	}
});

Template.login.events({
	"click #facebookLogin": function(e) {
		Meteor.loginWithFacebook(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("target");
			}
		});
	},
	"click #googleLogin": function(e) {
		Meteor.loginWithGoogle(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("target");
			}
		});
	}
});

Template.target.helpers({
	"target": function() {
		return Meteor.users.findOne(Meteor.user().target).profile.name;
	},
	"actions": function() {
		return Actions.find().fetch();
	},
	"message": function() {
		var a = "Unknown";
		var m = "claims to have killed";
		var t = "Unknown";
		var assassin = Meteor.users.findOne(this.assassin);
		var target = Meteor.users.findOne(this.target);

		if(this.assassin === Meteor.userId()) {a = "You"; m = "claim to have killed";}
		else if(assassin) {a = assassin.profile.name;}

		if(this.target === Meteor.userId()) {t = "You";}
		else if(target) {t = target.profile.name;}
		if(this.confirmed) {m = "killed";}

		return "" + a + " " + m + " " + t + "";
	}
});

Template.target.events({
	"click #logout": function() {
		Meteor.logout(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("login");
			}
		});
	}
});

Template.leaderboard.helpers({
	"userList": function() {
		return Meteor.users.find({"inGame": true}, {sort: {"kills": -1}}).fetch();
	}
});<commit_msg>Add confirmation message<commit_after>Template.registerHelper("activeRoute", function(route) {
	var currentRoute = Router.current().route.getName();
	return currentRoute === route ? " active" : "";
});

Template.registerHelper("calendarTime", function(date) {
	if(date) {
		return moment(date).calendar();
	}
	return "Unknown";
});

Template.registerHelper("equals", function(a, b) {
	return a === b;
});

Template.navigation.events({
	"click #logout": function(e) {
		Meteor.logout(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("login");
			}
		});
	}
});

Template.login.events({
	"click #facebookLogin": function(e) {
		Meteor.loginWithFacebook(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("target");
			}
		});
	},
	"click #googleLogin": function(e) {
		Meteor.loginWithGoogle(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("target");
			}
		});
	}
});

Template.target.helpers({
	"target": function() {
		return Meteor.users.findOne(Meteor.user().target).profile.name;
	},
	"actions": function() {
		return Actions.find({}, {sort: {"timestamp": -1}}).fetch();
	},
	"message": function() {
		var a = "Unknown";
		var m = "claims to have killed";
		var t = "Unknown";
		var c = "";
		var assassin = Meteor.users.findOne(this.assassin);
		var target = Meteor.users.findOne(this.target);

		if(this.assassin === Meteor.userId()) {a = "You"; m = "claim to have killed";}
		else if(assassin) {a = assassin.profile.name;}

		if(this.target === Meteor.userId()) {t = "You"; c = '
Is this correct? Yes / No';}
		else if(target) {t = target.profile.name;}
		if(this.confirmed) {m = "killed"; c = "";}

		return "" + a + " " + m + " " + t + "" + c;
	}
});

Template.target.events({
	"click #logout": function() {
		Meteor.logout(function(error) {
			if(error) {
				alert(error);
			}
			else {
				Router.go("login");
			}
		});
	}
});

Template.leaderboard.helpers({
	"userList": function() {
		return Meteor.users.find({"inGame": true}, {sort: {"kills": -1}}).fetch();
	}
});<|endoftext|>


<commit_before>function redraw_multiple_selects(container) {
  var c = container;
  if (typeof container == "string") {
    c = "#"+container;
  }
  $("select[multiple]",c).selectn("destroy",c);
  $("select[multiple]",c).selectn();
}

// Make the XML request thing, specify the callback function
function refreshProjectList(radiobutton) {
  url = get_alloc_var('url')+'task/updateProjectList.php?projectType='+radiobutton.value;
  makeAjaxRequest(url, 'projectListDropdown','',1)
}

function add_gst(value) {
  var tax_percent = get_alloc_var("tax_percent");
  return Math.round(value * (tax_percent/100 +1)*100)/100;
}

function deduct_gst(value) {
  var tax_percent = get_alloc_var("tax_percent");
  return Math.round(value / (tax_percent/100 +1)*100)/100;
}

function toggle_view_edit(reset) {
  $(".view").toggle();
  $(".edit").toggle();
  if (reset) {
    $(this).parents("form").reset();
  }
  redraw_multiple_selects();
  return false;
}

function makeAjaxRequest(url,entityid,extra_fields,redraw) {
  $("#"+entityid).html('');
  jQuery.get(url,extra_fields,function(data) {
    $("#"+entityid).hide();
    $("#"+entityid).html(data);
    $("#"+entityid).fadeIn("fast");

    // We may need to redraw the select widgets
    if (redraw) {
      redraw_multiple_selects(entityid);
    }
  });
}

// This is a generic show/hide for anything
function set_grow_shrink(id, id_to_hide, use_classes_instead_of_ids) {
  // toggle the other div - if any
  if (use_classes_instead_of_ids && id_to_hide) {
    $("."+id_to_hide).slideToggle("fast");
  } else if (id_to_hide) {
    $("#"+id_to_hide).slideToggle("fast");
  }
  // hide or show the actual div
  if (use_classes_instead_of_ids) {
    $("."+id).slideToggle("fast");
  } else {
    $("#"+id).slideToggle("fast");
  }
  return false;
}

function sidebyside_activate(id,redraw) {
  var arr = [];
  $.each($(".sidebyside"), function(k,v) {
    arr[arr.length] = v.id.replace("sbs_link_","");
  });

  if (!id) {
    id = get_alloc_var("side_by_side_link");
  }
  if (!id) {
    id = arr[0];
  }

  if (id == "sbsAll") {
    for (var i=0; i<arr.length; i++) {
      if (arr[i] != "sbsAll") {
        $("#"+arr[i]).show();
        $('#sbs_link_'+arr[i]).removeClass("sidebyside_active").addClass("sidebyside");
      }
    }
    $('#sbs_link_' + id).addClass("sidebyside_active");

  } else {
    for (var i=0; i<arr.length; i++) {
      if (arr[i] != "sbsAll") {
        $("#"+arr[i]).hide();
      }
      $('#sbs_link_' + arr[i]).removeClass("sidebyside_active").addClass("sidebyside");
    }
    $('#sbs_link_' + id).addClass("sidebyside_active");
    $("#"+id).show();
  }

  // allows us to target particular pages for redraw_multiple_selects();
  redraw_multiple_selects();
}

function help_text_on(id, str) {
  $('#main').append("

");
  $('#helper').hide().html(str);

  offset = $('#'+id).offset();

  x = offset.left -400;
  if (x < 0) {
    x = x + 380;
  }
  $("#helper").css('left',x);

  y = offset.top - 50;
  if (y > 350) {
    y = y-$('#helper').height() -40;
  }

  $("#helper").css('top',y);
  $("#helper").fadeIn("normal");
}
function help_text_off(id) {
  $("#helper").fadeOut("normal");
  $('#helper').remove();
}
function preload_field(element, text) {
  $(document).ready(function() {
    $(element).bind("focus", function(e){
      if (this.value == text) {
        this.style.color = "#333333";
        this.value = "";
      }
    });
    $(element).each(function(){
      if (this.value == "") {
        this.style.color = "#bbbbbb";
        this.value = text;
      }
    });
    $('form').submit(function(){
      $(element).each(function(){
        if (this.value == text) {
          this.value = "";
        }
      });
    });
  });
}

function save_recipients(data) {
  var p = data.select.parent();
  var commentID = p.find("input[name=commentID]").val();
  var values = data.select.val();

  jQuery.post("../comment/updateRecipients.php",{ "commentID":commentID, "comment_recipients":values},function(data) {
    p.parent().hide();
    if (data == 'external') {
      var label = '[ External Conversation ]'
      p.parents(".panel").addClass("loud");
    } else {
      var label = '[ Internal Conversation ]'
      p.parents(".panel").removeClass("loud");
    }
    p.parent().parent().find("a.recipient_editor_link").html(label).show();
  });
}

calendar_counter = 0
function refresh_calendars() {
  $(".datefield").each(function(){
    calendar_counter = calendar_counter +1;
    var calendar_id = "calendar_"+calendar_counter;
    var button_id = "calendar_button_"+calendar_counter;
    $(this).attr("id",calendar_id);
    $(this).next("img").attr("id",button_id);

    var settings = {}
    settings["inputField"] = calendar_id;
    settings["ifFormat"] = "%Y-%m-%d";
    settings["button"] = button_id;
    settings["showOthers"] = 1;
    settings["align"] = "Bl";
    settings["firstDay"] = get_alloc_var("cal_first_day");
    settings["step"] = 1;
    settings["weekNumbers"] = 0;
    settings["date"] = $(this).attr("value");
    Calendar.setup(settings);
  });
}

// Preload mouseover images
if (document.images) {
  pic1= new Image(9,11);
  pic1.src="../images/arrow_blank.gif";
  pic2= new Image(9,11);
  pic2.src="../images/arrow_faded.gif";
  pic3= new Image(9,11);
  pic3.src="../images/arrow_down.gif";
  pic4= new Image(9,11);
  pic4.src="../images/arrow_up.gif";
  pic5= new Image(119,13);
  pic5.src="../images/ticker2.gif";
  pic6= new Image(16,16);
  pic6.src="../images/spinner.gif";
}

// When the document has loaded...
$(document).ready(function() {

  // Focus the login form fields
  if ($("#login_form").length) {
    if (!$("#username").val()) {
      $("#username").focus();
    } else {
      $("#password").focus();
    }
  }

  // Give the tables alternating stripes
  $(".list tr:nth-child(even)").addClass("even");
  $(".list tr:nth-child(odd)").addClass("odd");
  $(".delete_button").live("click", function(e){
    return confirm("Click OK to confirm deletion.");
  });
  $(".confirm_button").bind("click", function(e){
    return confirm("Click OK to confirm.");
  });
  $("input.datefield").bind("dblclick", function(e){
    var now = new Date();
    this.value=now.getFullYear()+'-'+(now.getMonth()+1)+'-'+now.getDate();
  });

  $('tr.clickrow').bind('click',function(e){
    var id = this.id.split('_')[1]; // clickrow_43242
    if (id && !$(e.target).is('input:checkbox') && !$(e.target).is('a') && !$(e.target).is('b')) {
      $('#checkbox_'+id).attr('checked',!$('#checkbox_'+id).attr('checked'));
    }
  });

  // This loads up certain textboxes with faint help text that vanishes upon focus
  preload_field("#menu_form_needle", "Enter search text or ID...");
  preload_field("input.datefield", "YYYY-MM-DD");

  $("#search_action").change(function(){
    var bits = $(this).val().split("_");
    if (bits[0] == "create" || bits[0] == "history") {
      $("#form_search").submit();
    }
  });

  // Add resize grippies to all textareas
  $('textarea:not(.processed)').TextAreaResizer();

  // Add toggles for filters
  $(".toggleFilter").click(function(){
    var d = $(".filter").css("display");
    if (d == "table") {
      var l = "Show Filter";
      var d = "none";
    } else {
      var l = "Hide Filter";
      var d = "table";
    }
    $(".filter").css("display",d);
    $(this).text(l);
    redraw_multiple_selects();
    return false;
  });

  // Activate user preference for displaying filters
  if (get_alloc_var("show_filters") != "yes") {
    $(".toggleFilter").trigger("click");
  }

  $(".calendar_links").hide();
  $(".calendar_day").bind('mouseover',function(){
    $(".calendar_links").hide();
    $(this).find(".calendar_links").show();
  });
  $(".alloc_calendar").bind('mouseout',function() {
    $(".calendar_links").hide();
  });

  $('input.toggler').click(function(){
    return $('.task_checkboxes').each(function() {
      this.checked = !this.checked
    });
  });

  // Activate side by side links/tabs, if any
  $(".sidebyside").click(function(e) {
    var redraw = $(this).attr("data-sbs-redraw");
    sidebyside_activate(e.target.id.replace("sbs_link_",""),redraw);
    return false;
  });
  sidebyside_activate();

  $(".edit").hide();

  // Mark up the date fields with dynamic calendars
  refresh_calendars();

  // Interested Parties recipients editor
  $(".recipient_editor_link").click(function(){
    var commentID = this.id.split("_")[2]
    $(this).toggle();
    $("#recipient_dropdown_"+commentID).slideToggle("fast");
    redraw_multiple_selects("recipient_dropdown_"+commentID);
    return false;
  });

  $(".commentreply").click(function(e){
    $("#interested_parties_selector").hide();
    $(this).parents(".pcomment").append($("#id_new_comment").css( { "display" : "inline-table" } ));
    $("#id_new_comment").find("input[name=entity]").val("comment");
    $("#id_new_comment").find("input[name=entityID]").val($(this).parents(".pcomment").attr("data-comment-id"));
    return false;
  });

  $(".commentnew").click(function(e){
    $("#interested_parties_selector").show();
    $("#id_new_comment").find("input[name=entity]").val($("#id_new_comment").find("input[name=commentMaster]").val());
    $("#id_new_comment").find("input[name=entityID]").val($("#id_new_comment").find("input[name=commentMasterID]").val());
    $("#new_comment_container").append($("#id_new_comment").css( { "display" : "inline-table" } ));
    return false;
  });

  $("a.star").live('click',function(){
    if ($("b",$(this)).hasClass('icon-star-empty')) {
      $("b",$(this)).removeClass('icon-star-empty').addClass('icon-star');
      $(this).addClass("hot");
    } else {
      $("b",$(this)).removeClass('icon-star hot').addClass('icon-star-empty');
      $(this).removeClass("hot");
    }
    $.get($(this).attr("href"));
    return false;
  });

  // This duplicates a button with class=default and puts it first,
  // so that the web browser treats it as the default submission button.
  $('form').each(function () {
    var thisform = $(this);
    thisform.prepend(thisform.find('button.default').clone().css({
      position: 'absolute',
      left: '-999px',
      top: '-999px',
      height: 0,
      width: 0
    }));
  });

  $(".config-link").click(function(){

    var elem = $("."+$(this).attr("id")).css({"position":"absolute"
                                             ,"top":10
                                             ,"right":0
                                             ,"display":"inline"
                                             }).addClass("corner").addClass("shadow");

    // config boxes that have class "lazy" are lazy-loading, i.e. dynamically populated via ajax
    var i = $(this).attr("id");
    if ($("."+i).hasClass("lazy")) {
      $("."+i).html('');
      $.get(get_alloc_var("url")+"home/"+i+".php", function(data) {
        $("."+i).html(data);
        redraw_multiple_selects();
      });
    }

    $(this).parent().append(elem);
    redraw_multiple_selects($(this).parent());
    return false;
  });

  // This is mainly used for the edit comment recipient logic on the comments screens
  // The data-callback is most likely save_recipients(); Go there.
  $("html").bind("selectn-closed",function(e,data){
    if (data.select.attr("data-callback")) {
      window[data.select.attr("data-callback")](data);
    }
  });

});

<commit_msg>22243 Fix help text bubble location.<commit_after>function redraw_multiple_selects(container) {
  var c = container;
  if (typeof container == "string") {
    c = "#"+container;
  }
  $("select[multiple]",c).selectn("destroy",c);
  $("select[multiple]",c).selectn();
}

// Make the XML request thing, specify the callback function
function refreshProjectList(radiobutton) {
  url = get_alloc_var('url')+'task/updateProjectList.php?projectType='+radiobutton.value;
  makeAjaxRequest(url, 'projectListDropdown','',1)
}

function add_gst(value) {
  var tax_percent = get_alloc_var("tax_percent");
  return Math.round(value * (tax_percent/100 +1)*100)/100;
}

function deduct_gst(value) {
  var tax_percent = get_alloc_var("tax_percent");
  return Math.round(value / (tax_percent/100 +1)*100)/100;
}

function toggle_view_edit(reset) {
  $(".view").toggle();
  $(".edit").toggle();
  if (reset) {
    $(this).parents("form").reset();
  }
  redraw_multiple_selects();
  return false;
}

function makeAjaxRequest(url,entityid,extra_fields,redraw) {
  $("#"+entityid).html('');
  jQuery.get(url,extra_fields,function(data) {
    $("#"+entityid).hide();
    $("#"+entityid).html(data);
    $("#"+entityid).fadeIn("fast");

    // We may need to redraw the select widgets
    if (redraw) {
      redraw_multiple_selects(entityid);
    }
  });
}

// This is a generic show/hide for anything
function set_grow_shrink(id, id_to_hide, use_classes_instead_of_ids) {
  // toggle the other div - if any
  if (use_classes_instead_of_ids && id_to_hide) {
    $("."+id_to_hide).slideToggle("fast");
  } else if (id_to_hide) {
    $("#"+id_to_hide).slideToggle("fast");
  }
  // hide or show the actual div
  if (use_classes_instead_of_ids) {
    $("."+id).slideToggle("fast");
  } else {
    $("#"+id).slideToggle("fast");
  }
  return false;
}

function sidebyside_activate(id,redraw) {
  var arr = [];
  $.each($(".sidebyside"), function(k,v) {
    arr[arr.length] = v.id.replace("sbs_link_","");
  });

  if (!id) {
    id = get_alloc_var("side_by_side_link");
  }
  if (!id) {
    id = arr[0];
  }

  if (id == "sbsAll") {
    for (var i=0; i<arr.length; i++) {
      if (arr[i] != "sbsAll") {
        $("#"+arr[i]).show();
        $('#sbs_link_'+arr[i]).removeClass("sidebyside_active").addClass("sidebyside");
      }
    }
    $('#sbs_link_' + id).addClass("sidebyside_active");

  } else {
    for (var i=0; i<arr.length; i++) {
      if (arr[i] != "sbsAll") {
        $("#"+arr[i]).hide();
      }
      $('#sbs_link_' + arr[i]).removeClass("sidebyside_active").addClass("sidebyside");
    }
    $('#sbs_link_' + id).addClass("sidebyside_active");
    $("#"+id).show();
  }

  // allows us to target particular pages for redraw_multiple_selects();
  redraw_multiple_selects();
}

function help_text_on(id, str) {
  $('#main').append("

");
  $('#helper').html(str).hide();
  var offset = $('#'+id).position();
  var x = offset.left -420;
  if (x < 0) {
    x = x + 400;
  }
  var y = offset.top + 20;
  if ((y + $('#helper').height() + 40) > $(document).height()) {
    y = y-$('#helper').height() - 40;
  }
  $("#helper").css('left',x);
  $("#helper").css('top',y);
  $("#helper").fadeIn("normal");
}
function help_text_off(id) {
  $("#helper").fadeOut("normal");
  $('#helper').remove();
}
function preload_field(element, text) {
  $(document).ready(function() {
    $(element).bind("focus", function(e){
      if (this.value == text) {
        this.style.color = "#333333";
        this.value = "";
      }
    });
    $(element).each(function(){
      if (this.value == "") {
        this.style.color = "#bbbbbb";
        this.value = text;
      }
    });
    $('form').submit(function(){
      $(element).each(function(){
        if (this.value == text) {
          this.value = "";
        }
      });
    });
  });
}

function save_recipients(data) {
  var p = data.select.parent();
  var commentID = p.find("input[name=commentID]").val();
  var values = data.select.val();

  jQuery.post("../comment/updateRecipients.php",{ "commentID":commentID, "comment_recipients":values},function(data) {
    p.parent().hide();
    if (data == 'external') {
      var label = '[ External Conversation ]'
      p.parents(".panel").addClass("loud");
    } else {
      var label = '[ Internal Conversation ]'
      p.parents(".panel").removeClass("loud");
    }
    p.parent().parent().find("a.recipient_editor_link").html(label).show();
  });
}

calendar_counter = 0
function refresh_calendars() {
  $(".datefield").each(function(){
    calendar_counter = calendar_counter +1;
    var calendar_id = "calendar_"+calendar_counter;
    var button_id = "calendar_button_"+calendar_counter;
    $(this).attr("id",calendar_id);
    $(this).next("img").attr("id",button_id);

    var settings = {}
    settings["inputField"] = calendar_id;
    settings["ifFormat"] = "%Y-%m-%d";
    settings["button"] = button_id;
    settings["showOthers"] = 1;
    settings["align"] = "Bl";
    settings["firstDay"] = get_alloc_var("cal_first_day");
    settings["step"] = 1;
    settings["weekNumbers"] = 0;
    settings["date"] = $(this).attr("value");
    Calendar.setup(settings);
  });
}

// Preload mouseover images
if (document.images) {
  pic1= new Image(9,11);
  pic1.src="../images/arrow_blank.gif";
  pic2= new Image(9,11);
  pic2.src="../images/arrow_faded.gif";
  pic3= new Image(9,11);
  pic3.src="../images/arrow_down.gif";
  pic4= new Image(9,11);
  pic4.src="../images/arrow_up.gif";
  pic5= new Image(119,13);
  pic5.src="../images/ticker2.gif";
  pic6= new Image(16,16);
  pic6.src="../images/spinner.gif";
}

// When the document has loaded...
$(document).ready(function() {

  // Focus the login form fields
  if ($("#login_form").length) {
    if (!$("#username").val()) {
      $("#username").focus();
    } else {
      $("#password").focus();
    }
  }

  // Give the tables alternating stripes
  $(".list tr:nth-child(even)").addClass("even");
  $(".list tr:nth-child(odd)").addClass("odd");
  $(".delete_button").live("click", function(e){
    return confirm("Click OK to confirm deletion.");
  });
  $(".confirm_button").bind("click", function(e){
    return confirm("Click OK to confirm.");
  });
  $("input.datefield").bind("dblclick", function(e){
    var now = new Date();
    this.value=now.getFullYear()+'-'+(now.getMonth()+1)+'-'+now.getDate();
  });

  $('tr.clickrow').bind('click',function(e){
    var id = this.id.split('_')[1]; // clickrow_43242
    if (id && !$(e.target).is('input:checkbox') && !$(e.target).is('a') && !$(e.target).is('b')) {
      $('#checkbox_'+id).attr('checked',!$('#checkbox_'+id).attr('checked'));
    }
  });

  // This loads up certain textboxes with faint help text that vanishes upon focus
  preload_field("#menu_form_needle", "Enter search text or ID...");
  preload_field("input.datefield", "YYYY-MM-DD");

  $("#search_action").change(function(){
    var bits = $(this).val().split("_");
    if (bits[0] == "create" || bits[0] == "history") {
      $("#form_search").submit();
    }
  });

  // Add resize grippies to all textareas
  $('textarea:not(.processed)').TextAreaResizer();

  // Add toggles for filters
  $(".toggleFilter").click(function(){
    var d = $(".filter").css("display");
    if (d == "table") {
      var l = "Show Filter";
      var d = "none";
    } else {
      var l = "Hide Filter";
      var d = "table";
    }
    $(".filter").css("display",d);
    $(this).text(l);
    redraw_multiple_selects();
    return false;
  });

  // Activate user preference for displaying filters
  if (get_alloc_var("show_filters") != "yes") {
    $(".toggleFilter").trigger("click");
  }

  $(".calendar_links").hide();
  $(".calendar_day").bind('mouseover',function(){
    $(".calendar_links").hide();
    $(this).find(".calendar_links").show();
  });
  $(".alloc_calendar").bind('mouseout',function() {
    $(".calendar_links").hide();
  });

  $('input.toggler').click(function(){
    return $('.task_checkboxes').each(function() {
      this.checked = !this.checked
    });
  });

  // Activate side by side links/tabs, if any
  $(".sidebyside").click(function(e) {
    var redraw = $(this).attr("data-sbs-redraw");
    sidebyside_activate(e.target.id.replace("sbs_link_",""),redraw);
    return false;
  });
  sidebyside_activate();

  $(".edit").hide();

  // Mark up the date fields with dynamic calendars
  refresh_calendars();

  // Interested Parties recipients editor
  $(".recipient_editor_link").click(function(){
    var commentID = this.id.split("_")[2]
    $(this).toggle();
    $("#recipient_dropdown_"+commentID).slideToggle("fast");
    redraw_multiple_selects("recipient_dropdown_"+commentID);
    return false;
  });

  $(".commentreply").click(function(e){
    $("#interested_parties_selector").hide();
    $(this).parents(".pcomment").append($("#id_new_comment").css( { "display" : "inline-table" } ));
    $("#id_new_comment").find("input[name=entity]").val("comment");
    $("#id_new_comment").find("input[name=entityID]").val($(this).parents(".pcomment").attr("data-comment-id"));
    return false;
  });

  $(".commentnew").click(function(e){
    $("#interested_parties_selector").show();
    $("#id_new_comment").find("input[name=entity]").val($("#id_new_comment").find("input[name=commentMaster]").val());
    $("#id_new_comment").find("input[name=entityID]").val($("#id_new_comment").find("input[name=commentMasterID]").val());
    $("#new_comment_container").append($("#id_new_comment").css( { "display" : "inline-table" } ));
    return false;
  });

  $("a.star").live('click',function(){
    if ($("b",$(this)).hasClass('icon-star-empty')) {
      $("b",$(this)).removeClass('icon-star-empty').addClass('icon-star');
      $(this).addClass("hot");
    } else {
      $("b",$(this)).removeClass('icon-star hot').addClass('icon-star-empty');
      $(this).removeClass("hot");
    }
    $.get($(this).attr("href"));
    return false;
  });

  // This duplicates a button with class=default and puts it first,
  // so that the web browser treats it as the default submission button.
  $('form').each(function () {
    var thisform = $(this);
    thisform.prepend(thisform.find('button.default').clone().css({
      position: 'absolute',
      left: '-999px',
      top: '-999px',
      height: 0,
      width: 0
    }));
  });

  $(".config-link").click(function(){

    var elem = $("."+$(this).attr("id")).css({"position":"absolute"
                                             ,"top":10
                                             ,"right":0
                                             ,"display":"inline"
                                             }).addClass("corner").addClass("shadow");

    // config boxes that have class "lazy" are lazy-loading, i.e. dynamically populated via ajax
    var i = $(this).attr("id");
    if ($("."+i).hasClass("lazy")) {
      $("."+i).html('');
      $.get(get_alloc_var("url")+"home/"+i+".php", function(data) {
        $("."+i).html(data);
        redraw_multiple_selects();
      });
    }

    $(this).parent().append(elem);
    redraw_multiple_selects($(this).parent());
    return false;
  });

  // This is mainly used for the edit comment recipient logic on the comments screens
  // The data-callback is most likely save_recipients(); Go there.
  $("html").bind("selectn-closed",function(e,data){
    if (data.select.attr("data-callback")) {
      window[data.select.attr("data-callback")](data);
    }
  });

});

<|endoftext|>


<commit_before>var Terminal = require('./compiled/Terminal');
var React = require('react');
var _ = require('lodash');
var Rx = require('rx');

// TODO: Figure out how it works.
var createEventHandler = function () {
    var subject = function() {
        subject.onNext.apply(subject, arguments);
    };

    getEnumerablePropertyNames(Rx.Subject.prototype)
        .forEach(function (property) {
            subject[property] = Rx.Subject.prototype[property];
        });
    Rx.Subject.call(subject);

    return subject;
};
function getEnumerablePropertyNames(target) {
    var result = [];
    for (var key in target) {
        result.push(key);
    }
    return result;
}

var keys = {
    goUp: function(event) { return (event.ctrlKey && event.keyCode === 80) || event.keyCode === 38; },
    goDown: function(event) { return (event.ctrlKey && event.keyCode === 78) || event.keyCode === 40; },
    execute: function(event) { return event.keyCode === 13; },
    tab: function(event) { return event.keyCode === 9; }
};

$(document).ready(function () {
    window.terminal = new Terminal(getDimensions());

    $(window).resize(function() {
        terminal.resize(getDimensions());
    });

    React.render(<Board terminal={window.terminal}/>, document.getElementById('black-board'));

    $(document).keydown(function(event) {
        focusLastInput(event);
    });
});

var Board = React.createClass({
    componentDidMount: function () {
        this.props.terminal.on('invocation', this.forceUpdate.bind(this));
    },
    handleKeyDown: function (event) {
        // Ctrl+l
        if (event.ctrlKey && event.keyCode === 76) {
            this.props.terminal.clearInvocations();

            event.stopPropagation();
            event.preventDefault();
        }
    },
    render: function () {
        var invocations = this.props.terminal.invocations.map(function (invocation) {
            return (
                <Invocation key={invocation.id} invocation={invocation}/>
            )
        });
        return (

                    {invocations}

                <StatusLine currentWorkingDirectory={this.props.terminal.currentDirectory}/>

        );
    }
});

var Invocation = React.createClass({
    componentDidMount: function () {
        this.props.invocation.on('data', function () {
            this.setState({ canBeDecorated: this.props.invocation.canBeDecorated()});
        }.bind(this));
    },
    componentDidUpdate: scrollToBottom,

    getInitialState: function() {
        return {
            decorate: true,
            canBeDecorated: false
        };
    },
    render: function () {
        var buffer, decorationToggle;

        if (this.state.canBeDecorated && this.state.decorate) {
            buffer = this.props.invocation.decorate();
        } else {
            buffer = this.props.invocation.getBuffer().render();
        }

        if (this.state.canBeDecorated) {
            decorationToggle = <DecorationToggle invocation={this}/>;
        }

        return (

                <Prompt prompt={this.props.invocation.getPrompt()} status={this.props.invocation.status}/>
                {decorationToggle}
                {buffer}

        );
    }
});

var DecorationToggle = React.createClass({
    getInitialState: function() {
        return {enabled: this.props.invocation.state.decorate};
    },
    handleClick: function() {
        var newState = !this.state.enabled;
        this.setState({enabled: newState});
        this.props.invocation.setState({decorate: newState});
    },
    render: function () {
        var classes = ['decoration-toggle'];

        if (!this.state.enabled) {
            classes.push('disabled');
        }

        return (

        );
    }
});

var Prompt = React.createClass({
    getInitialState: function () {
        //TODO: Reset index to 0 when input changes.
        return {
            suggestions: [],
            selectedAutocompleteIndex: 0,
            latestKeyCode: null
        }
    },
    getInputNode: function () {
        return this.refs.command.getDOMNode()
    },
    componentWillMount: function () {
        var keyDownStream = createEventHandler();

        keyDownStream.subscribe(function(event){
            if (!_.contains([16, 17, 18], event.keyCode) && !event.ctrlKey && !event.altKey && !event.metaKey) {
                this.setState({latestKeyCode: event.keyCode});
            }
        }.bind(this));

        var meaningfulKeyDownStream = keyDownStream.filter(function(event) {
            return _.some(_.values(keys), function(matcher) { return matcher(event); });
        });

        meaningfulKeyDownStream.filter(keys.execute).subscribe(function(event) {
            event.stopPropagation();
            event.preventDefault();

            if (this.autocompleteIsShown()) {
                this.selectAutocomplete(event);
            } else {
                this.execute(event);
            }

        }.bind(this));

        meaningfulKeyDownStream.filter(this.autocompleteIsShown).filter(function(event) {
            return keys.execute(event) || keys.tab(event);
        }).subscribe(function(event) {
            event.stopPropagation();
            event.preventDefault();

            this.selectAutocomplete(event);

        }.bind(this));

        meaningfulKeyDownStream.filter(function(event) {
            return keys.goDown(event) || keys.goUp(event);
        }).subscribe(function(event) {
            event.stopPropagation();
            event.preventDefault();

            if (!this.showAutocomplete()) {
                this.navigateHistory(event);
            }
        }.bind(this));

        this.handlers = {
            onKeyDown: keyDownStream
        }
    },
    componentDidMount: function () {
        this.getInputNode().focus();
    },
    execute: function (event) {
        // TODO: Make sure executing an empty command works well.

        // TODO: send input read dynamically.
        var text = event.target.innerText;
        // Prevent two-line input on cd.
        setTimeout(function (){ this.props.prompt.send(text); }.bind(this), 0);
    },
    navigateHistory: function (event) {
        if (keys.goUp(event)) {
            var prevCommand = this.props.prompt.history.getPrevious();

            if (typeof prevCommand != 'undefined') {
                var target = event.target;

                withCaret(target, function(){
                    target.innerText = prevCommand;

                    return target.innerText.length;
                });
            }
        } else {
            var command = this.props.prompt.history.getNext();
            target = event.target;

            withCaret(target, function() {
                target.innerText = command || '';

                return target.innerText.length;
            });
        }
    },
    navigateAutocomplete: function (event) {
        if(keys.goUp(event)) {
            this.setState({ selectedAutocompleteIndex: Math.max(0, this.state.selectedAutocompleteIndex - 1) });
        } else {
            this.setState({ selectedAutocompleteIndex: Math.min(this.state.suggestions.length - 1, this.state.selectedAutocompleteIndex + 1) });
        }
    },
    selectAutocomplete: function (event) {
        var target = event.target;
        var state = this.state;

        withCaret(target, function() {
            target.innerHTML = state.suggestions[state.selectedAutocompleteIndex] + ' ';

            // TODO: replace only the current token.
            return target.innerText.length;
        });
        // TODO: remove forceUpdate.
        this.forceUpdate();
    },
    handleInput: function (event) {
        var target = event.target;
        this.props.prompt.buffer.setTo(target.innerText);

        //withCaret(target, function(oldPosition){
        //    // Do syntax highlighting.
        //    target.innerText = target.innerText.toUpperCase();
        //    return oldPosition;
        //});

        this.setState({ suggestions: this.props.prompt.getSuggestions()});
    },
    currentToken: function () {
        // TODO: return only the token under cursor.
        return this.getInputNode().innerText.split(/\s+/).pop();
    },
    showAutocomplete: function () {
        //TODO: use streams.
        return this.refs.command &&
            this.state.suggestions.length &&
            this.currentToken().length &&
            this.props.status == 'not-started' &&
            this.state.latestKeyCode != 13 &&
            this.state.latestKeyCode != 27 &&
            this.state.latestKeyCode != 9;
    },
    autocompleteIsShown: function () {
        return this.refs.autocomplete;
    },
    render: function () {
        var classes = ['prompt-wrapper', this.props.status].join(' ');

        if (this.showAutocomplete()) {
            var autocomplete = <Autocomplete suggestions={this.state.suggestions}
                                             caretPosition={$(this.getInputNode()).caret('offset')}
                                             selectedIndex={this.state.selectedAutocompleteIndex}
                                             ref="autocomplete" />;
        }

        return (

                {autocomplete}

        )
    }
});

var Autocomplete = React.createClass({
    render: function () {
        var position = _.pick(this.props.caretPosition, 'left');

        var suggestionViews = this.props.suggestions.map(function(suggestion, index) {
            var className = index == this.props.selectedIndex ? 'selected' : '';
            return (
{suggestion}
);
        }, this);

        if (this.props.caretPosition.top + 300 > window.innerHeight) {
            position['bottom'] = 28;
            suggestionViews = _(suggestionViews).reverse().value();
        }

        return (

                    {suggestionViews}

        )
    }
});

var StatusLine = React.createClass({
    render: function () {
        return (

                <CurrentDirectory currentWorkingDirectory={this.props.currentWorkingDirectory}/>

        )
    }
});

var CurrentDirectory = React.createClass({
    render: function () {
        return (

{this.props.currentWorkingDirectory}

        )
    }
});

function getDimensions() {
    var letter = document.getElementById('sizes-calculation');
    return {
        columns: Math.floor(window.innerWidth / letter.clientWidth * 10),
        rows:    Math.floor(window.innerHeight / letter.clientHeight)
    };
}

function scrollToBottom() {
    $('html body').animate({ scrollTop: $(document).height() }, 0);
}

function focusLastInput(event) {
    if (_.contains(event.target.classList, 'prompt') || event.metaKey) {
        return;
    }

    var target = _.last(document.getElementsByClassName('prompt'));
    target.focus();
    withCaret(target, function() { return target.innerText.length; });
}

function withCaret(target, callback) {
    var selection = window.getSelection();
    var range = document.createRange();

    var offset = callback(selection.baseOffset);

    if (target.childNodes.length) {
        range.setStart(target.childNodes[0], offset);
    } else {
        range.setStart(target, 0);
    }
    range.collapse(true);
    selection.removeAllRanges();
    selection.addRange(range);
}
<commit_msg>Extract isCommandKey().<commit_after>//TODO: Use ECMAScript 6.
var Terminal = require('./compiled/Terminal');
var React = require('react');
var _ = require('lodash');
var Rx = require('rx');

// TODO: Figure out how it works.
var createEventHandler = function () {
    var subject = function() {
        subject.onNext.apply(subject, arguments);
    };

    getEnumerablePropertyNames(Rx.Subject.prototype)
        .forEach(function (property) {
            subject[property] = Rx.Subject.prototype[property];
        });
    Rx.Subject.call(subject);

    return subject;
};
function getEnumerablePropertyNames(target) {
    var result = [];
    for (var key in target) {
        result.push(key);
    }
    return result;
}

var keys = {
    goUp: function(event) { return (event.ctrlKey && event.keyCode === 80) || event.keyCode === 38; },
    goDown: function(event) { return (event.ctrlKey && event.keyCode === 78) || event.keyCode === 40; },
    execute: function(event) { return event.keyCode === 13; },
    tab: function(event) { return event.keyCode === 9; }
};

$(document).ready(function () {
    window.terminal = new Terminal(getDimensions());

    $(window).resize(function() {
        terminal.resize(getDimensions());
    });

    React.render(<Board terminal={window.terminal}/>, document.getElementById('black-board'));

    $(document).keydown(function(event) {
        focusLastInput(event);
    });
});

var Board = React.createClass({
    componentDidMount: function () {
        this.props.terminal.on('invocation', this.forceUpdate.bind(this));
    },
    handleKeyDown: function (event) {
        // Ctrl+l
        if (event.ctrlKey && event.keyCode === 76) {
            this.props.terminal.clearInvocations();

            event.stopPropagation();
            event.preventDefault();
        }
    },
    render: function () {
        var invocations = this.props.terminal.invocations.map(function (invocation) {
            return (
                <Invocation key={invocation.id} invocation={invocation}/>
            )
        });
        return (

                    {invocations}

                <StatusLine currentWorkingDirectory={this.props.terminal.currentDirectory}/>

        );
    }
});

var Invocation = React.createClass({
    componentDidMount: function () {
        this.props.invocation.on('data', function () {
            this.setState({ canBeDecorated: this.props.invocation.canBeDecorated()});
        }.bind(this));
    },
    componentDidUpdate: scrollToBottom,

    getInitialState: function() {
        return {
            decorate: true,
            canBeDecorated: false
        };
    },
    render: function () {
        var buffer, decorationToggle;

        if (this.state.canBeDecorated && this.state.decorate) {
            buffer = this.props.invocation.decorate();
        } else {
            buffer = this.props.invocation.getBuffer().render();
        }

        if (this.state.canBeDecorated) {
            decorationToggle = <DecorationToggle invocation={this}/>;
        }

        return (

                <Prompt prompt={this.props.invocation.getPrompt()} status={this.props.invocation.status}/>
                {decorationToggle}
                {buffer}

        );
    }
});

var DecorationToggle = React.createClass({
    getInitialState: function() {
        return {enabled: this.props.invocation.state.decorate};
    },
    handleClick: function() {
        var newState = !this.state.enabled;
        this.setState({enabled: newState});
        this.props.invocation.setState({decorate: newState});
    },
    render: function () {
        var classes = ['decoration-toggle'];

        if (!this.state.enabled) {
            classes.push('disabled');
        }

        return (

        );
    }
});

var Prompt = React.createClass({
    getInitialState: function () {
        //TODO: Reset index to 0 when input changes.
        return {
            suggestions: [],
            selectedAutocompleteIndex: 0,
            latestKeyCode: null
        }
    },
    getInputNode: function () {
        return this.refs.command.getDOMNode()
    },
    componentWillMount: function () {
        var keyDownStream = createEventHandler();

        keyDownStream.subscribe(function(event){
            if (!isCommandKey()) {
                this.setState({latestKeyCode: event.keyCode});
            }
        }.bind(this));

        var meaningfulKeyDownStream = keyDownStream.filter(function(event) {
            return _.some(_.values(keys), function(matcher) { return matcher(event); });
        });

        meaningfulKeyDownStream.filter(keys.execute).subscribe(function(event) {
            event.stopPropagation();
            event.preventDefault();

            if (this.autocompleteIsShown()) {
                this.selectAutocomplete(event);
            } else {
                this.execute(event);
            }

        }.bind(this));

        meaningfulKeyDownStream.filter(this.autocompleteIsShown).filter(function(event) {
            return keys.execute(event) || keys.tab(event);
        }).subscribe(function(event) {
            event.stopPropagation();
            event.preventDefault();

            this.selectAutocomplete(event);

        }.bind(this));

        meaningfulKeyDownStream.filter(function(event) {
            return keys.goDown(event) || keys.goUp(event);
        }).subscribe(function(event) {
            event.stopPropagation();
            event.preventDefault();

            if (!this.showAutocomplete()) {
                this.navigateHistory(event);
            }
        }.bind(this));

        this.handlers = {
            onKeyDown: keyDownStream
        }
    },
    componentDidMount: function () {
        this.getInputNode().focus();
    },
    execute: function (event) {
        // TODO: Make sure executing an empty command works well.

        // TODO: send input read dynamically.
        var text = event.target.innerText;
        // Prevent two-line input on cd.
        setTimeout(function (){ this.props.prompt.send(text); }.bind(this), 0);
    },
    navigateHistory: function (event) {
        if (keys.goUp(event)) {
            var prevCommand = this.props.prompt.history.getPrevious();

            if (typeof prevCommand != 'undefined') {
                var target = event.target;

                withCaret(target, function(){
                    target.innerText = prevCommand;

                    return target.innerText.length;
                });
            }
        } else {
            var command = this.props.prompt.history.getNext();
            target = event.target;

            withCaret(target, function() {
                target.innerText = command || '';

                return target.innerText.length;
            });
        }
    },
    navigateAutocomplete: function (event) {
        if(keys.goUp(event)) {
            this.setState({ selectedAutocompleteIndex: Math.max(0, this.state.selectedAutocompleteIndex - 1) });
        } else {
            this.setState({ selectedAutocompleteIndex: Math.min(this.state.suggestions.length - 1, this.state.selectedAutocompleteIndex + 1) });
        }
    },
    selectAutocomplete: function (event) {
        var target = event.target;
        var state = this.state;

        withCaret(target, function() {
            target.innerHTML = state.suggestions[state.selectedAutocompleteIndex] + ' ';

            // TODO: replace only the current token.
            return target.innerText.length;
        });
        // TODO: remove forceUpdate.
        this.forceUpdate();
    },
    handleInput: function (event) {
        var target = event.target;
        this.props.prompt.buffer.setTo(target.innerText);

        //withCaret(target, function(oldPosition){
        //    // Do syntax highlighting.
        //    target.innerText = target.innerText.toUpperCase();
        //    return oldPosition;
        //});

        this.setState({ suggestions: this.props.prompt.getSuggestions()});
    },
    currentToken: function () {
        // TODO: return only the token under cursor.
        return this.getInputNode().innerText.split(/\s+/).pop();
    },
    showAutocomplete: function () {
        //TODO: use streams.
        return this.refs.command &&
            this.state.suggestions.length &&
            this.currentToken().length &&
            this.props.status == 'not-started' &&
            this.state.latestKeyCode != 13 &&
            this.state.latestKeyCode != 27 &&
            this.state.latestKeyCode != 9;
    },
    autocompleteIsShown: function () {
        return this.refs.autocomplete;
    },
    render: function () {
        var classes = ['prompt-wrapper', this.props.status].join(' ');

        if (this.showAutocomplete()) {
            var autocomplete = <Autocomplete suggestions={this.state.suggestions}
                                             caretPosition={$(this.getInputNode()).caret('offset')}
                                             selectedIndex={this.state.selectedAutocompleteIndex}
                                             ref="autocomplete" />;
        }

        return (

                {autocomplete}

        )
    }
});

var Autocomplete = React.createClass({
    render: function () {
        var position = _.pick(this.props.caretPosition, 'left');

        var suggestionViews = this.props.suggestions.map(function(suggestion, index) {
            var className = index == this.props.selectedIndex ? 'selected' : '';
            return (
{suggestion}
);
        }, this);

        if (this.props.caretPosition.top + 300 > window.innerHeight) {
            position['bottom'] = 28;
            suggestionViews = _(suggestionViews).reverse().value();
        }

        return (

                    {suggestionViews}

        )
    }
});

var StatusLine = React.createClass({
    render: function () {
        return (

                <CurrentDirectory currentWorkingDirectory={this.props.currentWorkingDirectory}/>

        )
    }
});

var CurrentDirectory = React.createClass({
    render: function () {
        return (

{this.props.currentWorkingDirectory}

        )
    }
});

function getDimensions() {
    var letter = document.getElementById('sizes-calculation');
    return {
        columns: Math.floor(window.innerWidth / letter.clientWidth * 10),
        rows:    Math.floor(window.innerHeight / letter.clientHeight)
    };
}

function scrollToBottom() {
    $('html body').animate({ scrollTop: $(document).height() }, 0);
}

function focusLastInput(event) {
    if (_.contains(event.target.classList, 'prompt') || event.metaKey) {
        return;
    }

    var target = _.last(document.getElementsByClassName('prompt'));
    target.focus();
    withCaret(target, function() { return target.innerText.length; });
}

function withCaret(target, callback) {
    var selection = window.getSelection();
    var range = document.createRange();

    var offset = callback(selection.baseOffset);

    if (target.childNodes.length) {
        range.setStart(target.childNodes[0], offset);
    } else {
        range.setStart(target, 0);
    }
    range.collapse(true);
    selection.removeAllRanges();
    selection.addRange(range);
}

function isCommandKey(event) {
    return _.contains([16, 17, 18], event.keyCode) || event.ctrlKey || event.altKey || event.metaKey;
}
<|endoftext|>


<commit_before>
var main = function(){
 //To drag the pictures
 $(".wallsaying").fadeOut(1000);
};

$(document).ready(main);
<commit_msg>Update drag.js<commit_after>
var main = function(){
 //To drag the pictures
 $(".wallsaying").fadeOut(1000);
 $(".dragme").draggable();
};

$(document).ready(main);
<|endoftext|>


<commit_before>export default [
  {
    name: 'befolkning_hovedgruppe',
    query: {
      year: 'latest',
      tableName: 'befolkning_hovedgruppe',
      unit: 'prosent',
      dimensions: [
        {
          name: 'innvkat5',
          variables: ['innvandrere']
        },
        {
          name: 'kjonn',
          variables: ['alle']
        }
      ]
    },
    drillDown: {
      page: 'befolkning',
      card: 'befolkning_hovedgruppe',
      buttonTitle: 'Gå til befolkninssammensetning'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: [],
    title: options => {
      return `Innvandrere utgjør ${options.share}% av befolkningen`
    },
    subTitle: options => {
      return `For hele landet er tallet ${options.share}%`
    }
  },
  {
    name: 'flyktninger_befolkningsandel',
    query: {
      year: 'latest',
      tableName: 'bosatt_befolkning',
      unit: 'promille',
      dimensions: [
        {
          name: 'bosetting',
          variables: ['bosatt_per_1000']
        }
      ]
    },
    drillDown: {
      page: 'befolkning',
      card: 'befolkning_innvandringsgrunn',
      buttonTitle: 'Gå til innvandringsårsak'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: [],
    title: options => {
      return `Flyktninger utgjør ${options.share}‰ av befolkningen`
    },
    subTitle: options => {
      return `For hele landet er tallet ${options.share}‰`
    },
  },
  {
    name: 'bosatt_anmodede',
    query: {
      year: 'latest',
      tableName: 'bosatt_anmodede',
      unit: 'prosent',
      dimensions: [
        {
          name: 'bosetting',
          variables: ['bosatt']
        }
      ]
    },
    drillDown: {
      page: 'befolkning',
      card: 'bosatt_anmodede',
      buttonTitle: 'Gå til bosetting'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: ['aar'],
    title: options => {
      return `I ${options.aar} har de bosatt ${options.share}% av de de ble anmodet om.`
    },
    subTitle: options => {
      return `Gjennomsnittet i Norge er ${options.share}%`
    },
  },
  {
    name: 'i_arbeid',
    query: {
      year: 'latest',
      tableName: 'sysselsatte_innvkat',
      unit: 'prosent',
      dimensions: [
        {
          name: 'innvkat3',
          variables: ['innvandrere', 'befolkningen_ellers']
        }
      ]
    },
    drillDown: {
      page: 'arbeid',
      card: 'sysselsatte-innvkat',
      buttonTitle: 'Gå til sysselsetting'
    },
    chartKind: 'bar',
    compareRegionToSimilar: false,
    additionalTitleParams: ['innvkat3'],
    title: options => {
      return `${options.share}% av ${options.innvkat3.replace('_', ' ')} er i arbeid`
    },
    subTitle: options => {
      return `For hele landet er tallet ${options.share}%`
    },
  },
  {
    name: 'innvandrere_intro_arbied',
    query: {
      year: 'latest',
      tableName: 'intro_avslutning_direkte',
      unit: 'prosent',
      dimensions: [
        {
          name: 'avslutningArsak8',
          variables: ['arbeid']
        },
        {
          name: 'kjonn',
          variables: ['alle']
        }
      ]
    },
    drillDown: {
      page: 'kvalifisering',
      card: 'etter-intro',
      buttonTitle: 'Gå til resultater fra introprogrammet'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: [],
    title: options => {
      return `${options.share}% av innvandrerne går direkte fra introprogram til arbeid/utdanning`
    },
    subTitle: options => {
      return `Gjennomsnittet i Norge er ${options.share}%`
    },
  }
]
<commit_msg>Change title on region query number two<commit_after>export default [
  {
    name: 'befolkning_hovedgruppe',
    query: {
      year: 'latest',
      tableName: 'befolkning_hovedgruppe',
      unit: 'prosent',
      dimensions: [
        {
          name: 'innvkat5',
          variables: ['innvandrere']
        },
        {
          name: 'kjonn',
          variables: ['alle']
        }
      ]
    },
    drillDown: {
      page: 'befolkning',
      card: 'befolkning_hovedgruppe',
      buttonTitle: 'Gå til befolkninssammensetning'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: [],
    title: options => {
      return `Innvandrere utgjør ${options.share}% av befolkningen`
    },
    subTitle: options => {
      return `For hele landet er tallet ${options.share}%`
    }
  },
  {
    name: 'flyktninger_befolkningsandel',
    query: {
      year: 'latest',
      tableName: 'bosatt_befolkning',
      unit: 'promille',
      dimensions: [
        {
          name: 'bosetting',
          variables: ['bosatt_per_1000']
        }
      ]
    },
    drillDown: {
      page: 'befolkning',
      card: 'befolkning_innvandringsgrunn',
      buttonTitle: 'Gå til innvandringsårsak'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: ['aar'],
    title: options => {
      return `Bosatte ${options.share} flyktninger per tusen innbygger i år ${options.aar}`
    },
    subTitle: options => {
      return `For hele landet er tallet ${options.share}‰`
    },
  },
  {
    name: 'bosatt_anmodede',
    query: {
      year: 'latest',
      tableName: 'bosatt_anmodede',
      unit: 'prosent',
      dimensions: [
        {
          name: 'bosetting',
          variables: ['bosatt']
        }
      ]
    },
    drillDown: {
      page: 'befolkning',
      card: 'bosatt_anmodede',
      buttonTitle: 'Gå til bosetting'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: ['aar'],
    title: options => {
      return `I ${options.aar} har de bosatt ${options.share}% av de de ble anmodet om.`
    },
    subTitle: options => {
      return `Gjennomsnittet i Norge er ${options.share}%`
    },
  },
  {
    name: 'i_arbeid',
    query: {
      year: 'latest',
      tableName: 'sysselsatte_innvkat',
      unit: 'prosent',
      dimensions: [
        {
          name: 'innvkat3',
          variables: ['innvandrere', 'befolkningen_ellers']
        }
      ]
    },
    drillDown: {
      page: 'arbeid',
      card: 'sysselsatte-innvkat',
      buttonTitle: 'Gå til sysselsetting'
    },
    chartKind: 'bar',
    compareRegionToSimilar: false,
    additionalTitleParams: ['innvkat3'],
    title: options => {
      return `${options.share}% av ${options.innvkat3.replace('_', ' ')} er i arbeid`
    },
    subTitle: options => {
      return `For hele landet er tallet ${options.share}%`
    },
  },
  {
    name: 'innvandrere_intro_arbied',
    query: {
      year: 'latest',
      tableName: 'intro_avslutning_direkte',
      unit: 'prosent',
      dimensions: [
        {
          name: 'avslutningArsak8',
          variables: ['arbeid']
        },
        {
          name: 'kjonn',
          variables: ['alle']
        }
      ]
    },
    drillDown: {
      page: 'kvalifisering',
      card: 'etter-intro',
      buttonTitle: 'Gå til resultater fra introprogrammet'
    },
    chartKind: 'benchmark',
    compareRegionToSimilar: true,
    additionalTitleParams: [],
    title: options => {
      return `${options.share}% av innvandrerne går direkte fra introprogram til arbeid/utdanning`
    },
    subTitle: options => {
      return `Gjennomsnittet i Norge er ${options.share}%`
    },
  }
]
<|endoftext|>


<commit_before>var _ = require('lodash');
var React = require('react');
var Router = require('react-router');
var DefaultRoute = Router.DefaultRoute;
var Route = Router.Route;
var RouteHandler = Router.RouteHandler;
var Persistence = require('./modules/persistence/persistence.js');
var AppComponent = require('./components/app.js');
var Explorer = require('./components/explorer/index.js');
var ProjectActions = require('./actions/ProjectActions');
var ExplorerActions = require('./actions/ExplorerActions');
var UserActions = require('./actions/UserActions');
var ExplorerUtils = require('./utils/ExplorerUtils');
var FormatUtils = require('./utils/FormatUtils');
var runValidations = require('./utils/ValidationUtils').runValidations;
var explorerValidations = require('./validations/ExplorerValidations').explorer;
var ProjectStore = require('./stores/ProjectStore');
var ExplorerStore = require('./stores/ExplorerStore');
var QueryStringUtils = require('./utils/QueryStringUtils');

function App(config) {
  if (config.persistence && !config.user) {
    throw new Error("If you initialize Explorer with a persistence layer you must provide a user object as well.");
  }

  this.targetNode = document.getElementById(config.targetId);
  this.persistence = config.persistence || null;
  this.client = config.client;

  UserActions.update(config.user || {});

  // Create the project store and kick off fetching schema for it.
  ProjectActions.create({ client: this.client });

  // Create the main active explorer
  var explorerAttrs = _.assign(
    { id: FormatUtils.generateRandomId("TEMP-") },
    ExplorerUtils.formatQueryParams(QueryStringUtils.getQueryAttributes()) // Grab params form URL and load into new explorer
  );
  ExplorerActions.create(explorerAttrs);
  ExplorerActions.setActive(explorerAttrs.id);

  // Run the query for this explorer if it's valid
  if (runValidations(explorerValidations, ExplorerStore.getActive().query).isValid) {
    ExplorerActions.exec(this.client, ExplorerStore.getActive().id);
  }

  this.componentConfig = {
    persistence: this.persistence,
    options: config.options || {},
    client: this.client
  };

  // Grab the persisted explorers if a persitence module was passed in
  if (this.persistence) {
    ExplorerActions.getPersisted(this.persistence);
  }

  this.routes = (
    <Route name="app" path={config.appRoot || "/"} handler={AppComponent}>
      <Route name="explorer" handler={Explorer}/>
    </Route>
  );
}

App.prototype.render = function() {
  var targetNode = this.targetNode;
  var config = this.componentConfig;

  Router.run(this.routes, Router.HistoryLocation, function(Handler) {
    React.render(<Handler config={config}/>, targetNode);
  });
};

window.React = React;
window.Keen = window.Keen || {};
window.Keen.DataTools = window.Keen.DataTools || {};
window.Keen.DataTools.Persistence = Persistence;
window.Keen.DataTools.App = module.exports = App;<commit_msg>Exposing AppDispatcher<commit_after>var _ = require('lodash');
var React = require('react');
var Router = require('react-router');
var DefaultRoute = Router.DefaultRoute;
var Route = Router.Route;
var RouteHandler = Router.RouteHandler;
var Persistence = require('./modules/persistence/persistence.js');
var AppDispatcher = require('./dispatcher/AppDispatcher');
var AppComponent = require('./components/app.js');
var Explorer = require('./components/explorer/index.js');
var ProjectActions = require('./actions/ProjectActions');
var ExplorerActions = require('./actions/ExplorerActions');
var UserActions = require('./actions/UserActions');
var ExplorerUtils = require('./utils/ExplorerUtils');
var FormatUtils = require('./utils/FormatUtils');
var runValidations = require('./utils/ValidationUtils').runValidations;
var explorerValidations = require('./validations/ExplorerValidations').explorer;
var ProjectStore = require('./stores/ProjectStore');
var ExplorerStore = require('./stores/ExplorerStore');
var QueryStringUtils = require('./utils/QueryStringUtils');

function App(config) {
  if (config.persistence && !config.user) {
    throw new Error("If you initialize Explorer with a persistence layer you must provide a user object as well.");
  }

  this.appDispatcher = AppDispatcher;
  this.targetNode = document.getElementById(config.targetId);
  this.persistence = config.persistence || null;
  this.client = config.client;

  UserActions.update(config.user || {});

  // Create the project store and kick off fetching schema for it.
  ProjectActions.create({ client: this.client });

  // Create the main active explorer
  var explorerAttrs = _.assign(
    { id: FormatUtils.generateRandomId("TEMP-") },
    ExplorerUtils.formatQueryParams(QueryStringUtils.getQueryAttributes()) // Grab params form URL and load into new explorer
  );
  ExplorerActions.create(explorerAttrs);
  ExplorerActions.setActive(explorerAttrs.id);

  // Run the query for this explorer if it's valid
  if (runValidations(explorerValidations, ExplorerStore.getActive().query).isValid) {
    ExplorerActions.exec(this.client, ExplorerStore.getActive().id);
  }

  this.componentConfig = {
    persistence: this.persistence,
    options: config.options || {},
    client: this.client
  };

  // Grab the persisted explorers if a persitence module was passed in
  if (this.persistence) {
    ExplorerActions.getPersisted(this.persistence);
  }

  this.routes = (
    <Route name="app" path={config.appRoot || "/"} handler={AppComponent}>
      <Route name="explorer" handler={Explorer}/>
    </Route>
  );
}

App.prototype.render = function() {
  var targetNode = this.targetNode;
  var config = this.componentConfig;

  Router.run(this.routes, Router.HistoryLocation, function(Handler) {
    React.render(<Handler config={config}/>, targetNode);
  });
};

window.React = React;
window.Keen = window.Keen || {};
window.Keen.DataTools = window.Keen.DataTools || {};
window.Keen.DataTools.Persistence = Persistence;
window.Keen.DataTools.App = module.exports = App;<|endoftext|>


<commit_before>/**
 * This is our top-level namespace. We will be placing all our objects under
 * this namespace.
 */
window.ChatApp = {
    View : {},
    Model : { }
}

/**
 * This is the socket.io server we will be connecting to.
 */
ChatApp.serverUrl = 'http://localhost:8080/';

/**
 * We only actually start executing the javascript, once the dom is fully
 * loaded. All the initialization for the application logic is done here.
 */
$(document).ready(function() {

    var app = new ChatApp.Application();

});
<commit_msg>Trying with a different ip<commit_after>/**
 * This is our top-level namespace. We will be placing all our objects under
 * this namespace.
 */
window.ChatApp = {
    View : {},
    Model : { }
}

/**
 * This is the socket.io server we will be connecting to.
 */
ChatApp.serverUrl = 'http://192.168.90.23:8080/';

/**
 * We only actually start executing the javascript, once the dom is fully
 * loaded. All the initialization for the application logic is done here.
 */
$(document).ready(function() {

    var app = new ChatApp.Application();

});
<|endoftext|>


<commit_before>_WebSocket = window.WebSocket;
window.WebSocket = ()=>{ throw Error('WebSocket was called without being stubbed') };

describe('nexus-host.js', function() {
  const defaultNexusServer = 'ws://localhost:3000';
  const defaultHostName = 'myHostName';
  beforeEach(function() {
    this.stubWebSocket = () => {
      this.ws = {
        send: newSpy('send'),
        close: newSpy('close'),
      },
      stub(window).WebSocket.toReturn(this.ws);
    };

    this.newHost = ({nexusServer, hostName, disableDefaultCallbacks}={}) => (
      this.host = new nexusHost(
        nexusServer || defaultNexusServer,
        hostName || defaultHostName,
        disableDefaultCallbacks
      )
    );

    this.triggerNewClient = ({clientID, request}={}) => {
      const data = JSON.stringify({
        type: 'NEW_CLIENT',
        clientID: clientID || 7,
        request: request || JSON.stringify({
          // to figure out
        })
      });
      this.ws.onmessage({ data });
    };

    this.triggerClientMessage = ({clientID, message}={}) => {
      const data = JSON.stringify({
        type: 'FROM_CLIENT',
        clientID: clientID || 7,
        payload: message || "HAHA",
      });
      this.ws.onmessage({ data });
    };

    this.triggerClientLost = (clientID) => {
      const data = JSON.stringify({
        type: 'LOST_CLIENT',
        payload: clientID || 7,
      });
      this.ws.onmessage({ data });
    };

    this.triggerHostRegistered = (hostID=9) => {
      const data = JSON.stringify({
        type: 'REGISTERED',
        hostID: hostID,
      });
      this.ws.onmessage({ data });
    };

    this.triggerConnectionClosed = (event) => {
      this.ws.onclose && this.ws.onclose(event);
    };
  });

  describe('#new NexusHost(nexusServer, hostName, [options])', function() {
    it('throws an error if a nexusServer address is not provided', function() {
      expect(() => new nexusHost()).toThrow(new Error('Missing nexusServer address'));
    });

    it('throws an error if a hostName is not provided', function() {
      expect(() => new nexusHost('ws://localhost:3000')).toThrow(new Error('Missing hostName'));
    });

    it('connects to the nexus server', function() {
      this.stubWebSocket();
      this.newHost();
      expect(window.WebSocket).toHaveBeenCalledWith(defaultNexusServer);
    });

    describe('after connecting', function() {
      it('tries to register', function() {
        this.stubWebSocket();
        this.newHost();
        expect(()=>this.ws.onopen()).not.toThrow();

        expect(this.ws.send).toHaveBeenCalledWith(JSON.stringify({
          type: 'HOST',
          payload: defaultHostName,
        }));
      });
    });
  });

  describe('if connection fails', function() {
    it('calls the .onerror if provided', function() {
      this.stubWebSocket();
      this.newHost().onError = (event) => { this.event = event };
      let err = {data:'err'};

      this.ws.onerror(err); // simulate error

      expect(this.event).toBe(err);
    });

    it('does not crash if there is no .onerror callback specified', function() {
      this.stubWebSocket();
      this.newHost().onError = null;

      expect(()=>this.ws.onerror(err)).not.toThrow();
    });
  });

  describe('when a new user connects', function() {
    it('calls the .onNewClient if provided', function() {
      this.stubWebSocket();
      const callback = newSpy('onNewClient');
      this.newHost().onNewClient = callback;

      const clientID = 5;
      const request = {};
      this.triggerNewClient({clientID, request}); // simulate event

      expect(callback).toHaveBeenCalledWith(clientID, request);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onNewClient = null;

      expect(()=>this.triggerNewClient()).not.toThrow();
    });
  });

  describe('when we get something from the user', function() {
    it('calls the .onClientMessage if provided', function() {
      this.stubWebSocket();
      const callback = newSpy('onClientMessage');
      this.newHost().onClientMessage = callback;

      const clientID = 5;
      const message = 'Yo';
      this.triggerClientMessage({clientID, message}); // simulate event

      expect(callback).toHaveBeenCalledWith(clientID, message);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onClientMessage = null;

      expect(()=>this.triggerClientMessage()).not.toThrow();
    });
  });

  describe('when the user gets disconnected', function() {
    it('calls the .onClientLost if provided', function() {
      this.stubWebSocket();
      const callback = newSpy('onClientLost');
      this.newHost().onClientLost = callback;

      const clientID = 5;
      this.triggerClientLost(clientID); // simulate event

      expect(callback).toHaveBeenCalledWith(clientID);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onClientLost = null;

      expect(()=>this.triggerClientLost()).not.toThrow();
    });
  });

  describe('#send(msg, clientID)', function() {
    it('tries to send the message to the client with the ID', function() {
      this.stubWebSocket();
      const clientID = 8;
      const payload = 'hello there';
      this.newHost().send(payload, clientID);
      expect(this.ws.send).toHaveBeenCalledWith(JSON.stringify({
        type: 'SEND',
        clientID,
        payload,
      }));
    });
  });

  describe('#send(msg)', function() {
    it('tries to send the message everyone', function() {
      this.stubWebSocket();
      const payload = 'hello there';
      this.newHost().send(payload);
      expect(this.ws.send).toHaveBeenCalledWith(JSON.stringify({
        type: 'SEND',
        payload,
      }));
    });
  });

  describe('when the host gets registered', function() {
    it('calls the .onRegistered callback', function() {
      this.stubWebSocket();
      const callback = newSpy('onRegistered');
      this.newHost().onRegistered = callback;

      const hostID = 5;
      this.triggerHostRegistered(hostID); // simulate event

      expect(callback).toHaveBeenCalledWith(hostID);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onRegistered = null;

      expect(()=>this.triggerHostRegistered()).not.toThrow();
    });
  });

  describe('when the host gets registered', function() {
    it('calls the .onRegistered callback', function() {
      this.stubWebSocket();
      const callback = newSpy('onRegistered');
      this.newHost().onRegistered = callback;

      const hostID = 5;
      this.triggerHostRegistered(hostID); // simulate event

      expect(callback).toHaveBeenCalledWith(hostID);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onRegistered = null;

      expect(()=>this.triggerHostRegistered()).not.toThrow();
    });
  });

  describe('when the connection gets closed', function() {
    it('calls the .onClosed callback', function() {
      this.stubWebSocket();
      const callback = newSpy('onClosed');
      this.newHost().onClose = callback;

      const event = {};
      this.triggerConnectionClosed(event); // simulate event

      expect(callback).toHaveBeenCalledWith(event);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onClose = null;

      expect(()=>this.triggerConnectionClosed()).not.toThrow();
    });
  });

  // prevent variable and arrary from changing
  const callbackList = Object.freeze([
    "onRegistered",
    "onError",
    "onNewClient",
    "onClientMessage",
    "onClientLost",
  ]);

  describe('when disableDefaultCallbacks is true', function() {
    it('does not set default callbacks', function() {
      this.stubWebSocket();
      const host = this.newHost({disableDefaultCallbacks: true});
      for(let i=0;i<callbackList.length;i++) {
        expect(host[callbackList[i]]).toBe(undefined);
      }
    });
  });

  describe('when disableDefaultCallbacks is not defined', function() {
    it('sets default callbacks', function() {
      this.stubWebSocket();
      const host = this.newHost();
      for(let i=0;i<callbackList.length;i++) {
        expect(host[callbackList[i]]).not.toBe(undefined);
      }
    });
  });

  describe('#close(code, reason)', function() {
    it('closes the websocket connection', function(){
      this.stubWebSocket();
      this.newHost().close();
      expect(this.ws.close).toHaveBeenCalledWith(1000, "Host closed their connection");
    });
  });
});
<commit_msg>Fix spec that accidentally relied on a global<commit_after>_WebSocket = window.WebSocket;
window.WebSocket = ()=>{ throw Error('WebSocket was called without being stubbed') };

describe('nexus-host.js', function() {
  const defaultNexusServer = 'ws://localhost:3000';
  const defaultHostName = 'myHostName';
  beforeEach(function() {
    this.stubWebSocket = () => {
      this.ws = {
        send: newSpy('send'),
        close: newSpy('close'),
      },
      stub(window).WebSocket.toReturn(this.ws);
    };

    this.newHost = ({nexusServer, hostName, disableDefaultCallbacks}={}) => (
      this.host = new nexusHost(
        nexusServer || defaultNexusServer,
        hostName || defaultHostName,
        disableDefaultCallbacks
      )
    );

    this.triggerNewClient = ({clientID, request}={}) => {
      const data = JSON.stringify({
        type: 'NEW_CLIENT',
        clientID: clientID || 7,
        request: request || JSON.stringify({
          // to figure out
        })
      });
      this.ws.onmessage({ data });
    };

    this.triggerClientMessage = ({clientID, message}={}) => {
      const data = JSON.stringify({
        type: 'FROM_CLIENT',
        clientID: clientID || 7,
        payload: message || "HAHA",
      });
      this.ws.onmessage({ data });
    };

    this.triggerClientLost = (clientID) => {
      const data = JSON.stringify({
        type: 'LOST_CLIENT',
        payload: clientID || 7,
      });
      this.ws.onmessage({ data });
    };

    this.triggerHostRegistered = (hostID=9) => {
      const data = JSON.stringify({
        type: 'REGISTERED',
        hostID: hostID,
      });
      this.ws.onmessage({ data });
    };

    this.triggerConnectionClosed = (event) => {
      this.ws.onclose && this.ws.onclose(event);
    };
  });

  describe('#new NexusHost(nexusServer, hostName, [options])', function() {
    it('throws an error if a nexusServer address is not provided', function() {
      expect(() => new nexusHost()).toThrow(new Error('Missing nexusServer address'));
    });

    it('throws an error if a hostName is not provided', function() {
      expect(() => new nexusHost('ws://localhost:3000')).toThrow(new Error('Missing hostName'));
    });

    it('connects to the nexus server', function() {
      this.stubWebSocket();
      this.newHost();
      expect(window.WebSocket).toHaveBeenCalledWith(defaultNexusServer);
    });

    describe('after connecting', function() {
      it('tries to register', function() {
        this.stubWebSocket();
        this.newHost();
        expect(()=>this.ws.onopen()).not.toThrow();

        expect(this.ws.send).toHaveBeenCalledWith(JSON.stringify({
          type: 'HOST',
          payload: defaultHostName,
        }));
      });
    });
  });

  describe('if connection fails', function() {
    it('calls the .onerror if provided', function() {
      this.stubWebSocket();
      this.newHost().onError = (event) => { this.event = event };
      let err = {data:'err'};

      this.ws.onerror(err); // simulate error

      expect(this.event).toBe(err);
    });

    it('does not crash if there is no .onerror callback specified', function() {
      this.stubWebSocket();
      this.newHost().onError = null;

      let err = {data:'err'}; // simulate error

      expect(()=>this.ws.onerror(err)).not.toThrow();
    });
  });

  describe('when a new user connects', function() {
    it('calls the .onNewClient if provided', function() {
      this.stubWebSocket();
      const callback = newSpy('onNewClient');
      this.newHost().onNewClient = callback;

      const clientID = 5;
      const request = {};
      this.triggerNewClient({clientID, request}); // simulate event

      expect(callback).toHaveBeenCalledWith(clientID, request);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onNewClient = null;

      expect(()=>this.triggerNewClient()).not.toThrow();
    });
  });

  describe('when we get something from the user', function() {
    it('calls the .onClientMessage if provided', function() {
      this.stubWebSocket();
      const callback = newSpy('onClientMessage');
      this.newHost().onClientMessage = callback;

      const clientID = 5;
      const message = 'Yo';
      this.triggerClientMessage({clientID, message}); // simulate event

      expect(callback).toHaveBeenCalledWith(clientID, message);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onClientMessage = null;

      expect(()=>this.triggerClientMessage()).not.toThrow();
    });
  });

  describe('when the user gets disconnected', function() {
    it('calls the .onClientLost if provided', function() {
      this.stubWebSocket();
      const callback = newSpy('onClientLost');
      this.newHost().onClientLost = callback;

      const clientID = 5;
      this.triggerClientLost(clientID); // simulate event

      expect(callback).toHaveBeenCalledWith(clientID);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onClientLost = null;

      expect(()=>this.triggerClientLost()).not.toThrow();
    });
  });

  describe('#send(msg, clientID)', function() {
    it('tries to send the message to the client with the ID', function() {
      this.stubWebSocket();
      const clientID = 8;
      const payload = 'hello there';
      this.newHost().send(payload, clientID);
      expect(this.ws.send).toHaveBeenCalledWith(JSON.stringify({
        type: 'SEND',
        clientID,
        payload,
      }));
    });
  });

  describe('#send(msg)', function() {
    it('tries to send the message everyone', function() {
      this.stubWebSocket();
      const payload = 'hello there';
      this.newHost().send(payload);
      expect(this.ws.send).toHaveBeenCalledWith(JSON.stringify({
        type: 'SEND',
        payload,
      }));
    });
  });

  describe('when the host gets registered', function() {
    it('calls the .onRegistered callback', function() {
      this.stubWebSocket();
      const callback = newSpy('onRegistered');
      this.newHost().onRegistered = callback;

      const hostID = 5;
      this.triggerHostRegistered(hostID); // simulate event

      expect(callback).toHaveBeenCalledWith(hostID);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onRegistered = null;

      expect(()=>this.triggerHostRegistered()).not.toThrow();
    });
  });

  describe('when the host gets registered', function() {
    it('calls the .onRegistered callback', function() {
      this.stubWebSocket();
      const callback = newSpy('onRegistered');
      this.newHost().onRegistered = callback;

      const hostID = 5;
      this.triggerHostRegistered(hostID); // simulate event

      expect(callback).toHaveBeenCalledWith(hostID);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onRegistered = null;

      expect(()=>this.triggerHostRegistered()).not.toThrow();
    });
  });

  describe('when the connection gets closed', function() {
    it('calls the .onClosed callback', function() {
      this.stubWebSocket();
      const callback = newSpy('onClosed');
      this.newHost().onClose = callback;

      const event = {};
      this.triggerConnectionClosed(event); // simulate event

      expect(callback).toHaveBeenCalledWith(event);
    });

    it('does not crash if there is no callback specified', function() {
      this.stubWebSocket();
      this.newHost().onClose = null;

      expect(()=>this.triggerConnectionClosed()).not.toThrow();
    });
  });

  // prevent variable and arrary from changing
  const callbackList = Object.freeze([
    "onRegistered",
    "onError",
    "onNewClient",
    "onClientMessage",
    "onClientLost",
  ]);

  describe('when disableDefaultCallbacks is true', function() {
    it('does not set default callbacks', function() {
      this.stubWebSocket();
      const host = this.newHost({disableDefaultCallbacks: true});
      for(let i=0;i<callbackList.length;i++) {
        expect(host[callbackList[i]]).toBe(undefined);
      }
    });
  });

  describe('when disableDefaultCallbacks is not defined', function() {
    it('sets default callbacks', function() {
      this.stubWebSocket();
      const host = this.newHost();
      for(let i=0;i<callbackList.length;i++) {
        expect(host[callbackList[i]]).not.toBe(undefined);
      }
    });
  });

  describe('#close(code, reason)', function() {
    it('closes the websocket connection', function(){
      this.stubWebSocket();
      this.newHost().close();
      expect(this.ws.close).toHaveBeenCalledWith(1000, "Host closed their connection");
    });
  });
});
<|endoftext|>


<commit_before>// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular/cli/plugins/karma')
    ],
    client:{
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: {
      reports: [ 'html', 'lcovonly' ],
      fixWebpackSourcePaths: true
    },
    angularCli: {
      environment: 'dev'
    },
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false
  });
};
<commit_msg>Added headless Chrome as an alternative test browser<commit_after>// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular/cli/plugins/karma')
    ],
    client:{
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: {
      reports: [ 'html', 'lcovonly' ],
      fixWebpackSourcePaths: true
    },
    angularCli: {
      environment: 'dev'
    },
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    customLaunchers: {
      ChromeHeadless:  {
        base:   'Chrome',
        flags:  [
          '--headless',
          '--disable-gpu',
          '--remote-debugging-port=9222'
        ]
      }
    },
    browsers: ['Chrome'],
    singleRun: false
  });
};
<|endoftext|>