<commit_before>var http = require('http')
var express = require('express')
var app = express()
var port = process.env.PORT || 5000
var createServer = require('pull-ws/server')
var pull = require('pull-stream')
var lendStream = require('pull-lend-stream')
var limit = require('pull-limit')
var sync = require('pull-sync')
var path = require('path')
var fs = require('fs')
var Busboy = require('busboy')
var ws = require('ws')
var debug = require('debug')
var log = debug('pando-server')
log.jobs = debug('pando-server:jobs')
var randombytes = require('randombytes')

// For WebRTC signaling
var client = null
var prospects = {}
function closeProspect (id) {
  if (prospects[id]) prospects[id].close()
}

function incomingAnswer (data) {
  log('INCOMING ANSWER', data)
  var destination = JSON.parse(data).destination
  if (prospects.hasOwnProperty(destination)) {
    prospects[destination].send(data, function (err) {
      if (err) closeProspect(destination)
    })
  } else {
    log('Unknown destination ' + destination + ', ignoring message')
  }
}

function offerHandler (id) {
  return function incomingOffer (message) {
    message = JSON.parse(message)
    message.origin = id
    log('INCOMING OFFER')
    log(message)
    if (client) client.send(JSON.stringify(message))
  }
}

app.use(express.static(path.join(__dirname, 'public')))

var httpServer = http.createServer(app)
httpServer.listen(port)

console.log('http server listening on %d', port)

var lender = lendStream()

var configFile = path.join(__dirname, 'config.json')
try {
  var config = JSON.parse(fs.readFileSync(configFile))
} catch (e) {
  throw new Error('Missing ' + configFile + ' or invalid JSON format')
}
var clientId = config['clientId']
var clientPath = '/' + clientId
console.log('Opening websocket connection for client on ' + clientPath)

app.post(path.join(clientPath, 'upload'), function (req, res) {
  var busboy = new Busboy({ headers: req.headers })
  console.log('receiving files')

  busboy.on('file', function (fieldname, file, filename) {
    var saveTo = path.join(
      path.join(__dirname, 'public'),
      path.basename(filename))
    console.log('saving ' + filename + ' at ' + saveTo)
    file.pipe(fs.createWriteStream(saveTo))
  })
  busboy.on('finish', function () {
    res.writeHead(200, { 'Connection': 'close' })
    res.end('done')
  })
  return req.pipe(busboy)
})

app.post('/webrtc/answer', function (req, res) {
  var busboy = new Busboy({ headers: req.headers })
  log('receiving webrtc answer:')
  busboy.on('field', function (fieldname, data) {
    if (fieldname === 'data') {
      log('answer: ' + data)
      incomingAnswer(data)
    } else {
      log('unexpected field: ' + fieldname)
    }
  })
  busboy.on('finish', function () {
    res.writeHead(200, { 'Connection': 'close' })
    res.end('done')
  })
  return req.pipe(busboy)
})

createServer({ server: httpServer, path: '/' + clientId }, function (stream) {
  console.log('websocket connection open for client')
  stream = sync(stream)
  console.log('creating new lender')
  lender = lendStream()

  pull(
    stream,
    pull.through(function (j) { log.jobs('distributing job: ' + j) }),
    lender,
    pull.through(function (j) { log.jobs('sending result: ' + j) }),
    stream
  )
})

createServer({ server: httpServer, path: '/volunteer' }, function (stream) {
  log('websocket connection open for volunteer')
  lender.lendStream(function (err, s) {
    if (err) {
      if (stream.close) return stream.close(err)

      pull(
        pull.error(err),
        stream
      )
      return
    }

    pull(
      s,
      limit(stream),
      s
    )
  })
})

new ws.Server({server: httpServer, path: '/' + clientId + '/webrtc-signaling'})
  .on('connection', function (ws) {
    log('client connected for webrtc-signaling')
    ws.on('message', incomingAnswer)
    client = ws
  })

new ws.Server({server: httpServer, path: '/volunteer-webrtc'})
  .on('connection', function (ws) {
    function remove () {
      log('volunteer ' + id + ' disconnected')
      delete prospects[id]
    }
    var id = ws.id = randombytes(16).inspect()
    ws.on('message', offerHandler(id))
    ws.on('close', remove)
    prospects[id] = ws
    setTimeout(function () {
      closeProspect(id)
    }, 30 * 1000)
  })

console.log('websocket server created')
<commit_msg>Added warning to log unexpected messages from the client<commit_after>var http = require('http')
var express = require('express')
var app = express()
var port = process.env.PORT || 5000
var createServer = require('pull-ws/server')
var pull = require('pull-stream')
var lendStream = require('pull-lend-stream')
var limit = require('pull-limit')
var sync = require('pull-sync')
var path = require('path')
var fs = require('fs')
var Busboy = require('busboy')
var ws = require('ws')
var debug = require('debug')
var log = debug('pando-server')
log.jobs = debug('pando-server:jobs')
var randombytes = require('randombytes')

// For WebRTC signaling
var client = null
var prospects = {}
function closeProspect (id) {
  if (prospects[id]) prospects[id].close()
}

function incomingAnswer (data) {
  log('INCOMING ANSWER', data)
  var destination = JSON.parse(data).destination
  if (prospects.hasOwnProperty(destination)) {
    prospects[destination].send(data, function (err) {
      if (err) closeProspect(destination)
    })
  } else {
    log('Unknown destination ' + destination + ', ignoring message')
  }
}

function offerHandler (id) {
  return function incomingOffer (message) {
    message = JSON.parse(message)
    message.origin = id
    log('INCOMING OFFER')
    log(message)
    if (client) client.send(JSON.stringify(message))
  }
}

app.use(express.static(path.join(__dirname, 'public')))

var httpServer = http.createServer(app)
httpServer.listen(port)

console.log('http server listening on %d', port)

var lender = lendStream()

var configFile = path.join(__dirname, 'config.json')
try {
  var config = JSON.parse(fs.readFileSync(configFile))
} catch (e) {
  throw new Error('Missing ' + configFile + ' or invalid JSON format')
}
var clientId = config['clientId']
var clientPath = '/' + clientId
console.log('Opening websocket connection for client on ' + clientPath)

app.post(path.join(clientPath, 'upload'), function (req, res) {
  var busboy = new Busboy({ headers: req.headers })
  console.log('receiving files')

  busboy.on('file', function (fieldname, file, filename) {
    var saveTo = path.join(
      path.join(__dirname, 'public'),
      path.basename(filename))
    console.log('saving ' + filename + ' at ' + saveTo)
    file.pipe(fs.createWriteStream(saveTo))
  })
  busboy.on('finish', function () {
    res.writeHead(200, { 'Connection': 'close' })
    res.end('done')
  })
  return req.pipe(busboy)
})

app.post('/webrtc/answer', function (req, res) {
  var busboy = new Busboy({ headers: req.headers })
  log('receiving webrtc answer:')
  busboy.on('field', function (fieldname, data) {
    if (fieldname === 'data') {
      log('answer: ' + data)
      incomingAnswer(data)
    } else {
      log('unexpected field: ' + fieldname)
    }
  })
  busboy.on('finish', function () {
    res.writeHead(200, { 'Connection': 'close' })
    res.end('done')
  })
  return req.pipe(busboy)
})

createServer({ server: httpServer, path: '/' + clientId }, function (stream) {
  console.log('websocket connection open for client')
  stream = sync(stream)
  console.log('creating new lender')
  lender = lendStream()

  pull(
    stream,
    pull.through(function (j) { log.jobs('distributing job: ' + j) }),
    lender,
    pull.through(function (j) { log.jobs('sending result: ' + j) }),
    stream
  )
})

createServer({ server: httpServer, path: '/volunteer' }, function (stream) {
  log('websocket connection open for volunteer')
  lender.lendStream(function (err, s) {
    if (err) {
      if (stream.close) return stream.close(err)

      pull(
        pull.error(err),
        stream
      )
      return
    }

    pull(
      s,
      limit(stream),
      s
    )
  })
})

new ws.Server({server: httpServer, path: '/' + clientId + '/webrtc-signaling'})
  .on('connection', function (ws) {
    log('client connected for webrtc-signaling')
    ws.on('message', function (data) {
      log('WARNING: unexpected message from client: ' + data)
    })
    client = ws
  })

new ws.Server({server: httpServer, path: '/volunteer-webrtc'})
  .on('connection', function (ws) {
    function remove () {
      log('volunteer ' + id + ' disconnected')
      delete prospects[id]
    }
    var id = ws.id = randombytes(16).inspect()
    ws.on('message', offerHandler(id))
    ws.on('close', remove)
    prospects[id] = ws
    setTimeout(function () {
      closeProspect(id)
    }, 30 * 1000)
  })

console.log('websocket server created')
<|endoftext|>


<commit_before>
describe("Column_type_dropdown", function() {

  var view, table, container;

  beforeEach(function() {
    table = TestUtil.createTable();
    view = new cdb.admin.ColumntypeDropdown({
      position: 'position',
      horizontal_position: "left",
      tick: "left",
      template_base: "table/views/table_column_type_options"
    });
    view.dialogContainer = $('

');
    view.render();
  });

  afterEach(function() {
    $('.confirmTypeChangeDialog').remove();
  })

  it('should set the options', function() {
    view.setTable(table, 'test2')
    expect(view.table).toEqual(table);
    expect(view.column).toEqual('test2');
  });

  describe("When the requested type change is not type safe", function() {
    it('should show the confirmation dialog when the change is destructive ', function() {
      view.setTable(table, 'test2');
      view.setColumnTypeChange('boolean');
      expect(view.confirmDialog.className).toEqual('confirmTypeChangeDialog');zz
    })

    it('should change the type after dialog ok is click', function() {
      var s = sinon.spy();
      spyOn(table, 'changeColumnType');

      view.setTable(table, 'test2');
      view.setColumnTypeChange('boolean');
      view.confirmDialog.ok();

      expect(table.changeColumnType).toHaveBeenCalled();
    })

  })

  describe('when the change is type safe', function() {

    it('should change type without ask for confirmation ', function() {
      var s = sinon.spy();
      spyOn(table, 'changeColumnType');

      view.setTable(table, 'test2');
      view.setColumnTypeChange('string');

      expect(view.confirmDialog).toBeFalsy();
    })

    it('should change the type', function() {
      var s = sinon.spy();
      spyOn(table, 'changeColumnType');

      view.setTable(table, 'test2');
      view.setColumnTypeChange('string');

      expect(table.changeColumnType).toHaveBeenCalled();
    })

  })

});
<commit_msg>fixed typo in test<commit_after>
describe("Column_type_dropdown", function() {

  var view, table, container;

  beforeEach(function() {
    table = TestUtil.createTable();
    view = new cdb.admin.ColumntypeDropdown({
      position: 'position',
      horizontal_position: "left",
      tick: "left",
      template_base: "table/views/table_column_type_options"
    });
    view.dialogContainer = $('

');
    view.render();
  });

  afterEach(function() {
    $('.confirmTypeChangeDialog').remove();
  })

  it('should set the options', function() {
    view.setTable(table, 'test2')
    expect(view.table).toEqual(table);
    expect(view.column).toEqual('test2');
  });

  describe("When the requested type change is not type safe", function() {
    it('should show the confirmation dialog when the change is destructive ', function() {
      view.setTable(table, 'test2');
      view.setColumnTypeChange('boolean');
      expect(view.confirmDialog.className).toEqual('confirmTypeChangeDialog');
    })

    it('should change the type after dialog ok is click', function() {
      var s = sinon.spy();
      spyOn(table, 'changeColumnType');

      view.setTable(table, 'test2');
      view.setColumnTypeChange('boolean');
      view.confirmDialog.ok();

      expect(table.changeColumnType).toHaveBeenCalled();
    })

  })

  describe('when the change is type safe', function() {

    it('should change type without ask for confirmation ', function() {
      var s = sinon.spy();
      spyOn(table, 'changeColumnType');

      view.setTable(table, 'test2');
      view.setColumnTypeChange('string');

      expect(view.confirmDialog).toBeFalsy();
    })

    it('should change the type', function() {
      var s = sinon.spy();
      spyOn(table, 'changeColumnType');

      view.setTable(table, 'test2');
      view.setColumnTypeChange('string');

      expect(table.changeColumnType).toHaveBeenCalled();
    })

  })

});
<|endoftext|>


<commit_before>var fs = require('fs');
var md5 = require('MD5');

module.exports = function Cache(opts) {
	if (opts === undefined) opts = {};
	this.dir  = opts.dir  || './cache';
	this.life = opts.life || 240;
	this.mode = opts.mode || 'json'; // json | string | raw
	self = this;

	this.get = function(key, fn) {
		if(fn === undefined) fn = function(err, data) {};
		self.getPath(key, function(err, path) {
			if(err) return fn(err, undefined);
			fs.exists(path, function(exists) {
				if(!exists) return fn(null, undefined);
				fs.stat(path, function(err, stats) {
					if(err) return fn(err, undefined);
					var fileTime = stats.mtime;
					var now = new Date();
					var diff = (now-fileTime)/60000;
					if(diff>self.life) return fn(null, undefined);
					fs.readFile(path, function(err, data) {
						if(err) return fn(err, undefined);
						var result = self.mode == 'json'
							? JSON.parse(data)
							: self.mode == 'string'
							? data.toString()
							: data;
						fn(null, result);
					});
				});
			});
		});
	}

	this.set = function(key, data, fn) {
		if(fn === undefined) fn = function(err) {};
		if (this.mode == 'json') data = JSON.stringify(data);
		self.getPath(key, function(err, path) {
			if(err) return fn(err);
			fs.writeFile(path, data, function(err) {
				if(fn !== undefined) fn(err);
			});
		});
	}

	this.getSync = function(key) {
		var path = this.getPathSync(key);
		if(!fs.existsSync(path)) return undefined;
		var fileTime = fs.statSync(path).mtime;
		var now = new Date();
		var diff = (now-fileTime)/60000;
		if(diff>this.life) return undefined;
		var data = fs.readFileSync(path);
		return self.mode == 'json'
			? JSON.parse(data)
			: self.mode == 'string'
			? data.toString()
			: data;
	}

	this.setSync = function(key, data) {
		if (!this.raw) data = JSON.stringify(data);
		fs.writeFileSync(this.getPathSync(key), data)
	}

	this.getPathSync = function(key) {
		if(!fs.existsSync(this.dir)) {
			throw new Error('Cache directory does not exist: ' + this.dir);
		}
		return this.dir + '/' + this.getFilename(key)
	}

	this.getPath = function(key, fn) {
		if(fn === undefined) fn = function(err, path) {};
		fs.exists(self.dir, function(exists) {
			if(!exists) {
				var err = new Error('Cache directory does not exist: ' + self.dir);
				return fn(err, undefined);
			}
			fn(null, self.dir + '/' + self.getFilename(key));
		});
	}

	this.getFilename = function(key) {
		return md5(key);
	}
}

<commit_msg>Now possible to use cache life 0<commit_after>var fs = require('fs');
var md5 = require('MD5');

module.exports = function Cache(opts) {
	if (opts === undefined) opts = {};
	this.dir  = opts.dir  || './cache';
	this.life = opts.life === undefined ? 240 : opts.life;
	this.mode = opts.mode || 'json'; // json | string | raw
	self = this;

	this.get = function(key, fn) {
		if(fn === undefined) fn = function(err, data) {};
		self.getPath(key, function(err, path) {
			if(err) return fn(err, undefined);
			fs.exists(path, function(exists) {
				if(!exists) return fn(null, undefined);
				fs.stat(path, function(err, stats) {
					if(err) return fn(err, undefined);
					var fileTime = stats.mtime;
					var now = new Date();
					var diff = (now-fileTime)/60000;
					if(diff>self.life) return fn(null, undefined);
					fs.readFile(path, function(err, data) {
						if(err) return fn(err, undefined);
						var result = self.mode == 'json'
							? JSON.parse(data)
							: self.mode == 'string'
							? data.toString()
							: data;
						fn(null, result);
					});
				});
			});
		});
	}

	this.set = function(key, data, fn) {
		if(fn === undefined) fn = function(err) {};
		if (this.mode == 'json') data = JSON.stringify(data);
		self.getPath(key, function(err, path) {
			if(err) return fn(err);
			fs.writeFile(path, data, function(err) {
				if(fn !== undefined) fn(err);
			});
		});
	}

	this.getSync = function(key) {
		var path = this.getPathSync(key);
		if(!fs.existsSync(path)) return undefined;
		var fileTime = fs.statSync(path).mtime;
		var now = new Date();
		var diff = (now-fileTime)/60000;
		if(diff>this.life) return undefined;
		var data = fs.readFileSync(path);
		return self.mode == 'json'
			? JSON.parse(data)
			: self.mode == 'string'
			? data.toString()
			: data;
	}

	this.setSync = function(key, data) {
		if (!this.raw) data = JSON.stringify(data);
		fs.writeFileSync(this.getPathSync(key), data)
	}

	this.getPathSync = function(key) {
		if(!fs.existsSync(this.dir)) {
			throw new Error('Cache directory does not exist: ' + this.dir);
		}
		return this.dir + '/' + this.getFilename(key)
	}

	this.getPath = function(key, fn) {
		if(fn === undefined) fn = function(err, path) {};
		fs.exists(self.dir, function(exists) {
			if(!exists) {
				var err = new Error('Cache directory does not exist: ' + self.dir);
				return fn(err, undefined);
			}
			fn(null, self.dir + '/' + self.getFilename(key));
		});
	}

	this.getFilename = function(key) {
		return md5(key);
	}
}

<|endoftext|>


<commit_before>var async = require("async");
var moment = require("moment");
var fs = require("fs-extra");

module.exports = function(json, outputDirectory, callback) {
  async.eachSeries(
    json.entries,
    function(input, next) {
      var entry = {};

      entry.tags = input.tags || [];
      entry.created = entry.dateStamp = moment
        .utc(input.creationDate)
        .valueOf();
      entry.metadata = {};

      if (input.starred) {
        entry.metadata.Starred = "yes";
      }

      if (input.weather) entry.metadata.Weather = input.weather.weatherCode;
      if (input.location)
        entry.metadata.Coordinates =
          input.location.latitude + ", " + input.location.longitude;

      var id = input.text.match(/!\[\]\(dayone-moment:\/\/([^.\),]+)\)/)[1];
      // console.log(id);

      var image =
        "_images/" +
        input.photos.filter(function(i) {
          return i.identifier === id;
        })[0].md5 +
        ".jpeg";

      // console.log(image);

      input.text = input.text.split("dayone-moment://" + id).join(image);

      // input.text = input.text.split('dayone-moment://F37015BF4E5840F192BE44E13EFCAF23')

      var file = [];

      file.push("Date: " + moment(entry.dateStamp).format('MMMM Do YYYY, h:mm:ss a'));

      for (var i in entry.metadata) file.push(i + ": " + entry.metadata[i]);

      if (file.length) file.push("");
      file.push(input.text);

      file = file.join('\n');

      // console.log(input);
      console.log(entry);

      var lines = input.text.trim().split('\n');

      lines = lines.filter(function(line){
        return line.indexOf('![') === -1 && line.indexOf('://') === -1;
      });

      if (lines.length) slug = lines[0].split('/').join('-').split(' ').join('-').toLowerCase();

      slug = slug.split('.').join('');
      slug = slug.split(',').join('');
      slug = slug.split('/').join('');
      slug = slug.split('/').join('');
      slug = slug.split('\'').join('');

      while (slug.indexOf('--') > -1)
        slug = slug.split('--').join('-');

      fs.writeFile(
        outputDirectory + "/" + moment(entry.dateStamp).format('YYYY-MM-DD-') + (slug || 'untitled') + ".txt",
        file,
        next
      );
    },
    callback
  );
};
<commit_msg>Added comments to day one import script<commit_after>var async = require("async");
var moment = require("moment");
var fs = require("fs-extra");

/*

TODO: BUG FIX FOR MULTIPLE IMAGES IN POST

"when a Day ONE entry contains more than one image it seems that

1) only the first image is converted
2) the old path is left in place for the other images
3) but it also looks like those images are not part of the new folder either
"

*/

module.exports = function(json, outputDirectory, callback) {
  async.eachSeries(
    json.entries,
    function(input, next) {
      var entry = {};

      entry.tags = input.tags || [];
      entry.created = entry.dateStamp = moment
        .utc(input.creationDate)
        .valueOf();
      entry.metadata = {};

      if (input.starred) {
        entry.metadata.Starred = "yes";
      }

      if (input.weather) entry.metadata.Weather = input.weather.weatherCode;
      if (input.location)
        entry.metadata.Coordinates =
          input.location.latitude + ", " + input.location.longitude;

      var id = input.text.match(/!\[\]\(dayone-moment:\/\/([^.\),]+)\)/)[1];
      // console.log(id);

      var image =
        "_images/" +
        input.photos.filter(function(i) {
          return i.identifier === id;
        })[0].md5 +
        ".jpeg";

      // console.log(image);

      input.text = input.text.split("dayone-moment://" + id).join(image);

      // input.text = input.text.split('dayone-moment://F37015BF4E5840F192BE44E13EFCAF23')

      var file = [];

      file.push("Date: " + moment(entry.dateStamp).format('MMMM Do YYYY, h:mm:ss a'));

      for (var i in entry.metadata) file.push(i + ": " + entry.metadata[i]);

      if (file.length) file.push("");
      file.push(input.text);

      file = file.join('\n');

      // console.log(input);
      console.log(entry);

      var lines = input.text.trim().split('\n');

      lines = lines.filter(function(line){
        return line.indexOf('![') === -1 && line.indexOf('://') === -1;
      });

      if (lines.length) slug = lines[0].split('/').join('-').split(' ').join('-').toLowerCase();

      slug = slug.split('.').join('');
      slug = slug.split(',').join('');
      slug = slug.split('/').join('');
      slug = slug.split('/').join('');
      slug = slug.split('\'').join('');

      while (slug.indexOf('--') > -1)
        slug = slug.split('--').join('-');

      fs.writeFile(
        outputDirectory + "/" + moment(entry.dateStamp).format('YYYY-MM-DD-') + (slug || 'untitled') + ".txt",
        file,
        next
      );
    },
    callback
  );
};
<|endoftext|>


<commit_before>(function () {
    'use strict';

    var React = require('react'),
        DateInput = require('./DateInput'),
        Environment = require('./Environment'),
        Model = require('./Model'),

        nightsText = function (count) {
            switch (count) {
            case 0:
                return 'Single day';

            case 1:
                return '1 night';

            default:
                return count + ' nights';
            }
        };

    module.exports = React.createClass({
        propTypes: {
            environment: React.PropTypes.instanceOf(Environment),
            model: React.PropTypes.instanceOf(Model),
            onChange: React.PropTypes.func
        },

        render: function () {
            return React.DOM.div(
                {className: 'srch-form__form-group form-group--period-of-stay-input'},
                this.valueInputs()
            );
        },

        valueInputs: function () {
            var m = this.props.model;

            return [
                React.DOM.div(
                    {className: 'period-of-stay-check-in', key: 0},

                    React.DOM.label(null, 'Check-in day'),

                    DateInput({
                        ref: 'checkIn',
                        value: m.checkInDate,
                        onChange: this.handleCheckInChange
                    }),

                    React.DOM.span({className:'srch-form__help-block'}, 'Format: dd.mm.yyyy'),
                    React.DOM.i({className:'fa fa-calendar srch-form__calendar-icon'}, '')

            ),

                React.DOM.div(
                    {className: 'period-of-stay-check-out', key: 1},

                    React.DOM.label(null, 'Check-out day'),

                    DateInput({
                        ref: 'checkOut',
                        value: m.checkOutDate,
                        onChange: this.handleCheckOutChange
                    }),

                    React.DOM.span({className:'srch-form__help-block'}, 'Format: dd.mm.yyyy'),
                    React.DOM.i({className:'fa fa-calendar srch-form__calendar-icon'}, '')
                ),

                React.DOM.span(
                    {className: 'period-of-stay-nights', key: 2},
                    nightsText(m.nightsCount())
                )
            ];
        },

        handleCheckInChange: function (value) {
            this.props.onChange(this.props.model.newCheckIn(value, this.props.environment));
        },

        handleCheckOutChange: function (value) {
            this.props.onChange(this.props.model.newCheckOut(value, this.props.environment));
        }
    });
}());
<commit_msg>Minor simplifications and improvements<commit_after>(function () {
    'use strict';

    var React = require('react'),
        DateInput = require('./DateInput'),
        Environment = require('./Environment'),
        Model = require('./Model'),

        nightsText = function (count) {
            switch (count) {
            case 0:
                return 'Single day';

            case 1:
                return '1 night';

            default:
                return count + ' nights';
            }
        };

    module.exports = React.createClass({
        propTypes: {
            environment: React.PropTypes.instanceOf(Environment),
            model: React.PropTypes.instanceOf(Model),
            onChange: React.PropTypes.func
        },

        render: function () {
            return React.DOM.div(
                {className: 'srch-form__form-group form-group--period-of-stay-input'},
                this.valueInputs()
            );
        },

        valueInputs: function () {
            var m = this.props.model;

            return [
                React.DOM.div(
                    {className: 'period-of-stay-check-in', key: 'k0'},

                    React.DOM.label({}, 'Check-in day'),

                    DateInput({
                        ref: 'checkIn',
                        value: m.checkInDate,
                        onChange: this.handleCheckInChange
                    }),

                    React.DOM.i({className:'fa fa-calendar calendar-icon'}, '')

                ),

                React.DOM.div(
                    {className: 'period-of-stay-check-out', key: 'k1'},

                    React.DOM.label({}, 'Check-out day'),

                    DateInput({
                        ref: 'checkOut',
                        value: m.checkOutDate,
                        onChange: this.handleCheckOutChange
                    }),

                    React.DOM.i({className:'fa fa-calendar calendar-icon'}, '')
                ),

                React.DOM.span(
                    {className: 'period-of-stay-nights', key: 'k2'},
                    nightsText(m.nightsCount())
                )
            ];
        },

        handleCheckInChange: function (value) {
            this.props.onChange(this.props.model.newCheckIn(value, this.props.environment));
        },

        handleCheckOutChange: function (value) {
            this.props.onChange(this.props.model.newCheckOut(value, this.props.environment));
        }
    });
}());
<|endoftext|>


<commit_before>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require jquery.ui.draggable
//= require jquery.ui.droppable
//= require_tree .
//= require bootstrap/dropdown
//= require moment/moment
//= require moment/langs

$(document).ready(function () {
  // Replace default titles on images with link by qTip tooltips
  $('a [title!=""], a[title!=""], [data-content!=""], [data-title!=""]').each(function () {
    $(this).qtip({
      content: {
        text: $(this).data('content') || true,
        title: $(this).data('title') || false
      },
      style: {
        classes: 'qtip-todc-bootstrap',
        tip: {
          width: 12
        }
      },
      show: {
        solo: true
      },
      position: {
        my: 'top center',
        at: 'bottom center',
        viewport: $(window)
      }
    })
  })
})
<commit_msg>change the qTip adjust method to shift<commit_after>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require jquery.ui.draggable
//= require jquery.ui.droppable
//= require_tree .
//= require bootstrap/dropdown
//= require moment/moment
//= require moment/langs

$(document).ready(function () {
  // Replace default titles on images with link by qTip tooltips
  $('a [title!=""], a[title!=""], [data-content!=""], [data-title!=""]').each(function () {
    $(this).qtip({
      content: {
        text: $(this).data('content') || true,
        title: $(this).data('title') || false
      },
      style: {
        classes: 'qtip-todc-bootstrap',
        tip: {
          width: 12
        }
      },
      show: {
        solo: true
      },
      position: {
        adjust: {
          method: 'shift'
        },
        my: 'top center',
        at: 'bottom center',
        viewport: $(window)
      }
    })
  })
})
<|endoftext|>


<commit_before>/*! Kernel CI Dashboard | Licensed under the GNU GPL v3 (or later) */
require([
    'jquery',
    'utils/error',
    'utils/init',
    'utils/request',
    'utils/tables',
    'utils/html',
    'utils/date'
], function($, e, init, r, t, html) {
    'use strict';
    var buildsTable,
        dateRange,
        pageLen,
        searchFilter;

    document.getElementById('li-build').setAttribute('class', 'active');

    dateRange = 14;

    function getBuildsFail() {
        html.removeElement('table-loading');
        html.replaceContent(
            document.getElementById('table-div'),
            html.errorDiv('Error loading data.'));
    }

    function getBuildsDone(response) {
        var columns,
            resLen,
            results,
            rowUrl;

        results = response.result;
        resLen = results.length;
        if (resLen === 0) {
            html.removeElement('table-loading');
            html.replaceContent(
                document.getElementById('table-div'),
                html.errorDiv('No data available'));
        } else {
            rowUrl = '/build/%(job)s/kernel/%(kernel)s/' +
                'defconfig/%(defconfig_full)s/';

            columns = [
                {
                    data: '_id',
                    visible: false,
                    searchable: false,
                    orderable: false
                },
                {
                    data: 'job',
                    title: 'Tree ‐ Branch',
                    className: 'tree-column',
                    render: function(data, type, object) {
                        var aNode,
                            branch,
                            branchNode,
                            rendered;

                        branch = object.git_branch;
                        rendered = data;

                        if (branch !== null && branch !== undefined) {
                            rendered = rendered + ' ' + branch;
                        }

                        if (type === 'display') {
                            aNode = document.createElement('a');
                            aNode.className = 'table-link';
                            aNode.setAttribute('href', '/job/' + data + '/');

                            aNode.appendChild(document.createTextNode(data));

                            if (branch !== null && branch !== undefined) {
                                branchNode = document.createElement('small');
                                branchNode.appendChild(
                                    document.createTextNode(branch));

                                aNode.insertAdjacentHTML(
                                    'beforeend', ' ‐ ');
                                aNode.appendChild(branchNode);
                            }

                            rendered = aNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'kernel',
                    title: 'Kernel',
                    type: 'string',
                    className: 'kernel-column',
                    render: function(data, type) {
                        var tooltipNode,
                            rendered;

                        rendered = data;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();
                            tooltipNode.setAttribute('title', data);

                            tooltipNode.appendChild(
                                document.createTextNode(data));

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'defconfig_full',
                    title: 'Defconfig',
                    className: 'defconfig-column',
                    render: function(data, type) {
                        var tooltipNode,
                            rendered;

                        rendered = data;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();
                            tooltipNode.setAttribute('title', data);

                            tooltipNode.appendChild(
                                document.createTextNode(data));

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'arch',
                    title: 'Arch.'
                },
                {
                    data: 'created_on',
                    title: 'Date',
                    type: 'date',
                    className: 'date-column pull-center',
                    render: function(data, type) {
                        var tooltipNode,
                            created,
                            iNode;

                        if (data === null) {
                            created = data;
                            if (type === 'display') {
                                tooltipNode = html.tooltip();
                                tooltipNode.setAttribute('Not available');

                                iNode = document.createElement('i');
                                iNode.className = 'fa fa-ban';

                                tooltipNode.appendChild(iNode);
                                created = tooltipNode.outerHTML;
                            }
                        } else {
                            created = new Date(data.$date);
                            if (type === 'display' || type === 'filter') {
                                created = created.toCustomISODate();
                            }
                        }

                        return created;
                    }
                },
                {
                    data: 'status',
                    title: 'Status',
                    type: 'string',
                    className: 'pull-center',
                    render: function(data, type) {
                        var tooltipNode,
                            rendered;

                        rendered = data;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();

                            switch (data) {
                                case 'PASS':
                                    tooltipNode.setAttribute(
                                        'title', 'Build completed');
                                    tooltipNode.appendChild(html.success());
                                    break;
                                case 'FAIL':
                                    tooltipNode.setAttribute(
                                        'title', 'Build failed');
                                    tooltipNode.appendChild(html.fail());
                                    break;
                                default:
                                    tooltipNode.setAttribute(
                                        'title', 'Unknown status');
                                    tooltipNode.appendChild(html.unknown());
                                    break;
                            }

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'job',
                    title: '',
                    orderable: false,
                    searchable: false,
                    className: 'select-column pull-center',
                    render: function(data, type, object) {
                        var aNode,
                            iNode,
                            rendered,
                            tooltipNode;

                        rendered = null;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();
                            tooltipNode.setAttribute(
                                'title', 'Details for ' + data +
                                ' ‐ ' + object.kernel +
                                ' and ' + object.defconfig_full
                            );

                            aNode = document.createElement('a');
                            aNode.setAttribute(
                                'href',
                                '/build/' + data + '/kernel/' + object.kernel +
                                '/defconfig/' + object.defconfig_full +
                                '/?_id=' + object._id.$oid
                            );

                            iNode = document.createElement('i');
                            iNode.className = 'fa fa-search';

                            aNode.appendChild(iNode);
                            tooltipNode.appendChild(aNode);

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                }
            ];

            buildsTable
                .tableData(results)
                .columns(columns)
                .order([5, 'desc'])
                .menu('build reports per page')
                .rowURL(rowUrl)
                .rowURLElements(['job', 'kernel', 'defconfig_full'])
                .draw();

            buildsTable
                .pageLen(pageLen)
                .search(searchFilter);
        }
    }

    function getBuilds() {
        var data,
            deferred;

        data = {
            sort: 'created_on',
            sort_order: -1,
            date_range: dateRange,
            field: [
                '_id', 'job', 'kernel', 'status',
                'arch', 'created_on', 'git_branch', 'defconfig_full'
            ]
        };

        deferred = r.get('/_ajax/build', data);
        $.when(deferred)
            .fail(e.error, getBuildsFail)
            .done(getBuildsDone);
    }

    init.hotkeys();
    init.tooltip();

    if (document.getElementById('search-filter') !== null) {
        searchFilter = document.getElementById('search-filter').value;
    }
    if (document.getElementById('page-len') !== null) {
        pageLen = document.getElementById('page-len').value;
    }
    if (document.getElementById('date-range') !== null) {
        dateRange = document.getElementById('date-range').value;
    }

    buildsTable = t(['builds-table', 'table-loading', 'table-div'], true);
    getBuilds();
});
<commit_msg>Sequentially load boot data<commit_after>/*! Kernel CI Dashboard | Licensed under the GNU GPL v3 (or later) */
require([
    'jquery',
    'utils/error',
    'utils/init',
    'utils/request',
    'utils/tables',
    'utils/html',
    'utils/const',
    'utils/date'
], function($, e, init, r, t, html, appconst) {
    'use strict';
    var buildsTable,
        buildReqData,
        dateRange,
        pageLen,
        searchFilter;

    document.getElementById('li-build').setAttribute('class', 'active');

    dateRange = appconst.MAX_DATE_RANGE;

    /**
     * Update the table with the new data.
     *
     * @param {object} response: The response from the previous request.
    **/
    function getMoreBuildsDone(response) {
        var results;

        results = response.result;
        if (results.length > 0) {
            buildsTable.addRows(results);
        }

        // Remove the loading banner when we get the last response.
        // Not the best solution since the last real response might come
        // before other requests depending on API time.
        if ((response.skip + response.limit) >= response.count) {
            html.removeChildrenByClass('table-process');
        }
    }

    /**
     * Get the other remaining build reports.
     * Triggered after the initial get request.
     *
     * @param {object} response: The response from the previous request.
    **/
    function getMoreBuilds(response) {
        var deferred,
            iNode,
            idx,
            resLen,
            resTotal,
            spanNode,
            totalReq;

        resTotal = response.count;
        resLen = response.result.length;

        if (resLen < resTotal) {
            // Add a small loading banner while we load more results.
            spanNode = document.createElement('span');

            iNode = document.createElement('i');
            iNode.className = 'fa fa-cog fa-spin';

            spanNode.appendChild(iNode);
            spanNode.insertAdjacentHTML('beforeend', ' ');
            spanNode.appendChild(
                document.createTextNode('loading more results'));
            spanNode.insertAdjacentHTML('beforeend', '…');

            html.replaceByClassNode('table-process', spanNode);

            totalReq = Math.floor(resTotal / appconst.MAX_QUERY_LIMIT);

            // Starting at 1 since we already got the first batch of results.
            for (idx = 1; idx <= totalReq; idx = idx + 1) {
                buildReqData.skip = appconst.MAX_QUERY_LIMIT * idx;
                deferred = r.get('/_ajax/build', buildReqData);
                $.when(deferred)
                    .done(getMoreBuildsDone);
            }
        }
    }

    function getBuildsFail() {
        html.removeElement('table-loading');
        html.replaceContent(
            document.getElementById('table-div'),
            html.errorDiv('Error loading data.'));
    }

    function getBuildsDone(response) {
        var columns,
            resLen,
            results,
            rowUrl;

        results = response.result;
        resLen = results.length;
        if (resLen === 0) {
            html.removeElement('table-loading');
            html.replaceContent(
                document.getElementById('table-div'),
                html.errorDiv('No data available'));
        } else {
            rowUrl = '/build/%(job)s/kernel/%(kernel)s/' +
                'defconfig/%(defconfig_full)s/';

            columns = [
                {
                    data: '_id',
                    visible: false,
                    searchable: false,
                    orderable: false
                },
                {
                    data: 'job',
                    title: 'Tree ‐ Branch',
                    className: 'tree-column',
                    render: function(data, type, object) {
                        var aNode,
                            branch,
                            branchNode,
                            rendered;

                        branch = object.git_branch;
                        rendered = data;

                        if (branch !== null && branch !== undefined) {
                            rendered = rendered + ' ' + branch;
                        }

                        if (type === 'display') {
                            aNode = document.createElement('a');
                            aNode.className = 'table-link';
                            aNode.setAttribute('href', '/job/' + data + '/');

                            aNode.appendChild(document.createTextNode(data));

                            if (branch !== null && branch !== undefined) {
                                branchNode = document.createElement('small');
                                branchNode.appendChild(
                                    document.createTextNode(branch));

                                aNode.insertAdjacentHTML(
                                    'beforeend', ' ‐ ');
                                aNode.appendChild(branchNode);
                            }

                            rendered = aNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'kernel',
                    title: 'Kernel',
                    type: 'string',
                    className: 'kernel-column',
                    render: function(data, type) {
                        var tooltipNode,
                            rendered;

                        rendered = data;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();
                            tooltipNode.setAttribute('title', data);

                            tooltipNode.appendChild(
                                document.createTextNode(data));

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'defconfig_full',
                    title: 'Defconfig',
                    className: 'defconfig-column',
                    render: function(data, type) {
                        var tooltipNode,
                            rendered;

                        rendered = data;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();
                            tooltipNode.setAttribute('title', data);

                            tooltipNode.appendChild(
                                document.createTextNode(data));

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'arch',
                    title: 'Arch.'
                },
                {
                    data: 'created_on',
                    title: 'Date',
                    type: 'date',
                    className: 'date-column pull-center',
                    render: function(data, type) {
                        var tooltipNode,
                            created,
                            iNode;

                        if (data === null) {
                            created = data;
                            if (type === 'display') {
                                tooltipNode = html.tooltip();
                                tooltipNode.setAttribute('Not available');

                                iNode = document.createElement('i');
                                iNode.className = 'fa fa-ban';

                                tooltipNode.appendChild(iNode);
                                created = tooltipNode.outerHTML;
                            }
                        } else {
                            created = new Date(data.$date);
                            if (type === 'display' || type === 'filter') {
                                created = created.toCustomISODate();
                            }
                        }

                        return created;
                    }
                },
                {
                    data: 'status',
                    title: 'Status',
                    type: 'string',
                    className: 'pull-center',
                    render: function(data, type) {
                        var tooltipNode,
                            rendered;

                        rendered = data;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();

                            switch (data) {
                                case 'PASS':
                                    tooltipNode.setAttribute(
                                        'title', 'Build completed');
                                    tooltipNode.appendChild(html.success());
                                    break;
                                case 'FAIL':
                                    tooltipNode.setAttribute(
                                        'title', 'Build failed');
                                    tooltipNode.appendChild(html.fail());
                                    break;
                                default:
                                    tooltipNode.setAttribute(
                                        'title', 'Unknown status');
                                    tooltipNode.appendChild(html.unknown());
                                    break;
                            }

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                },
                {
                    data: 'job',
                    title: '',
                    orderable: false,
                    searchable: false,
                    className: 'select-column pull-center',
                    render: function(data, type, object) {
                        var aNode,
                            iNode,
                            rendered,
                            tooltipNode;

                        rendered = null;
                        if (type === 'display') {
                            tooltipNode = html.tooltip();
                            tooltipNode.setAttribute(
                                'title', 'Details for ' + data +
                                ' ‐ ' + object.kernel +
                                ' and ' + object.defconfig_full
                            );

                            aNode = document.createElement('a');
                            aNode.setAttribute(
                                'href',
                                '/build/' + data + '/kernel/' + object.kernel +
                                '/defconfig/' + object.defconfig_full +
                                '/?_id=' + object._id.$oid
                            );

                            iNode = document.createElement('i');
                            iNode.className = 'fa fa-search';

                            aNode.appendChild(iNode);
                            tooltipNode.appendChild(aNode);

                            rendered = tooltipNode.outerHTML;
                        }

                        return rendered;
                    }
                }
            ];

            buildsTable
                .tableData(results)
                .columns(columns)
                .order([5, 'desc'])
                .menu('build reports per page')
                .rowURL(rowUrl)
                .rowURLElements(['job', 'kernel', 'defconfig_full'])
                .draw();

            buildsTable
                .pageLen(pageLen)
                .search(searchFilter);
        }
    }

    function getBuilds() {
        var deferred;

        deferred = r.get('/_ajax/build', buildReqData);
        $.when(deferred)
            .fail(e.error, getBuildsFail)
            .done(getBuildsDone, getMoreBuilds);
    }

    init.hotkeys();
    init.tooltip();

    if (document.getElementById('search-filter') !== null) {
        searchFilter = document.getElementById('search-filter').value;
    }
    if (document.getElementById('page-len') !== null) {
        pageLen = document.getElementById('page-len').value;
    }
    if (document.getElementById('date-range') !== null) {
        dateRange = document.getElementById('date-range').value;
    }

    buildReqData = {
        sort: 'created_on',
        sort_order: -1,
        date_range: dateRange,
        limit: appconst.MAX_QUERY_LIMIT,
        field: [
            '_id',
            'arch',
            'created_on',
            'defconfig_full',
            'git_branch',
            'job',
            'kernel',
            'status'
        ]
    };

    buildsTable = t(['builds-table', 'table-loading', 'table-div'], true);
    getBuilds();
});
<|endoftext|>


<commit_before>///<reference path="FusionCalculator.ts"/>
///<reference path="../data/PersonaData.ts"/>
///<reference path="../data/SkillData.ts"/>
/**
 * Created by Chin on 08-Apr-17.
 */
var PersonaController = (function () {
    function PersonaController($scope, $routeParams, $filter) {
        var personaName = $routeParams.persona_name;
        this.$filter = $filter;
        this.$scope = $scope;
        this.$scope.Math = Math;
        this.$scope.personaName = personaName;
        this.$scope.persona = personaMap[personaName];
        if (!this.$scope.persona)
            return;
        var calc = new FusionCalculator(customPersonaeByArcana);
        this.$scope.perPage = 20;
        // fusion to
        var fusionToRecipes = calc.getRecipes(this.$scope.persona);
        fusionToRecipes.sort(function (a, b) { return a.cost - b.cost; });
        for (var i = 0, recipe = null; recipe = fusionToRecipes[i]; i++) {
            recipe.num = i;
        }
        var fusionTo = {
            allRecipes: fusionToRecipes,
            recipes: fusionToRecipes,
            numRecipes: fusionToRecipes.length,
            lastPage: Math.floor(fusionToRecipes.length / this.$scope.perPage),
            pageNum: 0,
            filterStr: ""
        };
        this.$scope.fusionTo = fusionTo;
        this.$scope.$watch('fusionTo.filterStr', this.getPaginateAndFilterFunc(false).bind(this));
        this.$scope.$watch('fusionTo.filterStr', this.getResetPageFunc(false).bind(this));
        this.$scope.$watch('fusionTo.pageNum', this.getPaginateAndFilterFunc(false).bind(this));
        // fusion from
        var fusionFromRecipes = calc.getAllResultingRecipesFrom(this.$scope.persona);
        fusionFromRecipes.sort(function (a, b) { return a.cost - b.cost; });
        for (var i = 0, recipe = null; recipe = fusionFromRecipes[i]; i++) {
            recipe.num = i;
        }
        var fusionFrom = {
            allRecipes: fusionFromRecipes,
            recipes: fusionFromRecipes,
            numRecipes: fusionFromRecipes.length,
            lastPage: Math.floor(fusionFromRecipes.length / this.$scope.perPage),
            pageNum: 0,
            filterStr: ""
        };
        this.$scope.fusionFrom = fusionFrom;
        this.$scope.$watch('fusionFrom.filterStr', this.getPaginateAndFilterFunc(true).bind(this));
        this.$scope.$watch('fusionFrom.filterStr', this.getResetPageFunc(true).bind(this));
        this.$scope.$watch('fusionFrom.pageNum', this.getPaginateAndFilterFunc(true).bind(this));
        // stats
        var compediumEntry = personaMap[personaName];
        this.$scope.persona.stats = compediumEntry.stats;
        this.$scope.persona.statsHeader = ["St", "Ma", "En", "Ag", "Lu"];
        // elements
        // split the table into 2 for mobile
        var elems = getElems(personaName);
        this.$scope.persona.elems = elems;
        this.$scope.persona.elems1 = elems.slice(0, 5);
        this.$scope.persona.elems2 = elems.slice(5);
        // split the table into 2 for mobile
        var elemsHeader = ["Phys", "Gun", "Fire", "Ice", "Elec", "Wind", "Psy", "Nuke", "Bless", "Curse"];
        this.$scope.persona.elemsHeader = elemsHeader;
        this.$scope.persona.elemsHeader1 = elemsHeader.slice(0, 5);
        this.$scope.persona.elemsHeader2 = elemsHeader.slice(5);
        // Note: skillList are skills in a sorted list for displaying with Angular.
        // It's different from the existing skills property which is a map.
        this.$scope.persona.skillList = getSkills(personaName);
    }
    PersonaController.prototype.paginateAndFilter = function (fusionFromTo, filterFunc) {
        if (fusionFromTo.pageNum < 0)
            fusionFromTo.pageNum = 0;
        if (fusionFromTo.pageNum > fusionFromTo.lastPage)
            fusionFromTo.pageNum = fusionFromTo.lastPage;
        if (fusionFromTo.filterStr) {
            fusionFromTo.recipes = this.$filter('filter')(fusionFromTo.allRecipes, filterFunc(fusionFromTo.filterStr));
        }
        else {
            fusionFromTo.recipes = fusionFromTo.allRecipes;
        }
        fusionFromTo.lastPage = Math.floor(fusionFromTo.recipes.length / this.$scope.perPage);
        fusionFromTo.numRecipes = fusionFromTo.recipes.length;
        fusionFromTo.recipes = fusionFromTo.recipes.slice(fusionFromTo.pageNum * this.$scope.perPage, fusionFromTo.pageNum * this.$scope.perPage + this.$scope.perPage);
    };
    PersonaController.prototype.getPaginateAndFilterFunc = function (isFusionFrom) {
        var _this = this;
        return function (newVal, oldVal, scope) { return _this.paginateAndFilter(isFusionFrom ? scope.fusionFrom : scope.fusionTo, _this.getRecipeFilterFunc(isFusionFrom)); };
    };
    PersonaController.prototype.getRecipeFilterFunc = function (isFusionFrom) {
        var containsIgnoreCase = function (str, filter) { return str.toLowerCase().indexOf(filter.toLowerCase()) !== -1; };
        if (isFusionFrom) {
            return function (filterString) { return function (recipe, index, array) {
                return containsIgnoreCase(recipe.sources[1].name, filterString) || containsIgnoreCase(recipe.result.name, filterString);
            }; };
        }
        else {
            return function (filterString) { return function (recipe, index, array) {
                for (var i = 0; i < recipe.sources.length; i++) {
                    if (containsIgnoreCase(recipe.sources[i].name, filterString)) {
                        return true;
                    }
                }
                return false;
            }; };
        }
    };
    PersonaController.prototype.resetPage = function (fusionFromTo) {
        fusionFromTo.pageNum = 0;
    };
    PersonaController.prototype.getResetPageFunc = function (isFusionFrom) {
        var _this = this;
        return function (newVal, oldVal, scope) { return _this.resetPage(isFusionFrom ? scope.fusionFrom : scope.fusionTo); };
    };
    return PersonaController;
}());
<commit_msg>Update PersonaController.js<commit_after>///<reference path="FusionCalculator.ts"/>
///<reference path="../data/PersonaData.ts"/>
///<reference path="../data/SkillData.ts"/>
/**
 * Created by Chin on 08-Apr-17.
 */
var PersonaController = (function () {
    function PersonaController($scope, $routeParams, $filter) {
        var personaName = $routeParams.persona_name;
        this.$filter = $filter;
        this.$scope = $scope;
        this.$scope.Math = Math;
        this.$scope.personaName = personaName;
        this.$scope.persona = personaMap[personaName];
        if (!this.$scope.persona)
            return;
        var calc = new FusionCalculator(customPersonaeByArcana);
        this.$scope.perPage = 20;
        // fusion to
        var fusionToRecipes = calc.getRecipes(this.$scope.persona);
        fusionToRecipes.sort(function (a, b) { return a.cost - b.cost; });
        for (var i = 0, recipe = null; recipe = fusionToRecipes[i]; i++) {
            recipe.num = i;
        }
        var fusionTo = {
            allRecipes: fusionToRecipes,
            recipes: fusionToRecipes,
            numRecipes: fusionToRecipes.length,
            lastPage: Math.floor(fusionToRecipes.length / this.$scope.perPage),
            pageNum: 0,
            filterStr: ""
        };
        this.$scope.fusionTo = fusionTo;
        this.$scope.$watch('fusionTo.filterStr', this.getPaginateAndFilterFunc(false).bind(this));
        this.$scope.$watch('fusionTo.filterStr', this.getResetPageFunc(false).bind(this));
        this.$scope.$watch('fusionTo.pageNum', this.getPaginateAndFilterFunc(false).bind(this));
        // fusion from
        var fusionFromRecipes = calc.getAllResultingRecipesFrom(this.$scope.persona);
        fusionFromRecipes.sort(function (a, b) { return a.cost - b.cost; });
        for (var i = 0, recipe = null; recipe = fusionFromRecipes[i]; i++) {
            recipe.num = i;
        }
        var fusionFrom = {
            allRecipes: fusionFromRecipes,
            recipes: fusionFromRecipes,
            numRecipes: fusionFromRecipes.length,
            lastPage: Math.floor(fusionFromRecipes.length / this.$scope.perPage),
            pageNum: 0,
            filterStr: ""
        };
        this.$scope.fusionFrom = fusionFrom;
        this.$scope.$watch('fusionFrom.filterStr', this.getPaginateAndFilterFunc(true).bind(this));
        this.$scope.$watch('fusionFrom.filterStr', this.getResetPageFunc(true).bind(this));
        this.$scope.$watch('fusionFrom.pageNum', this.getPaginateAndFilterFunc(true).bind(this));
        // stats
        var compediumEntry = personaMap[personaName];
        this.$scope.persona.stats = compediumEntry.stats;
        this.$scope.persona.statsHeader = ["St", "Ma", "En", "Ag", "Lu"];
        // elements
        // split the table into 2 for mobile
        var elems = personaMap[personaName].elems; // var elems = getElems(personaName);
        this.$scope.persona.elems = elems;
        this.$scope.persona.elems1 = elems.slice(0, 5);
        this.$scope.persona.elems2 = elems.slice(5);
        // split the table into 2 for mobile
        var elemsHeader = ["Phys", "Gun", "Fire", "Ice", "Elec", "Wind", "Psy", "Nuke", "Bless", "Curse"];
        this.$scope.persona.elemsHeader = elemsHeader;
        this.$scope.persona.elemsHeader1 = elemsHeader.slice(0, 5);
        this.$scope.persona.elemsHeader2 = elemsHeader.slice(5);
        // Note: skillList are skills in a sorted list for displaying with Angular.
        // It's different from the existing skills property which is a map.
        this.$scope.persona.skillList = getSkills(personaName);
    }
    PersonaController.prototype.paginateAndFilter = function (fusionFromTo, filterFunc) {
        if (fusionFromTo.pageNum < 0)
            fusionFromTo.pageNum = 0;
        if (fusionFromTo.pageNum > fusionFromTo.lastPage)
            fusionFromTo.pageNum = fusionFromTo.lastPage;
        if (fusionFromTo.filterStr) {
            fusionFromTo.recipes = this.$filter('filter')(fusionFromTo.allRecipes, filterFunc(fusionFromTo.filterStr));
        }
        else {
            fusionFromTo.recipes = fusionFromTo.allRecipes;
        }
        fusionFromTo.lastPage = Math.floor(fusionFromTo.recipes.length / this.$scope.perPage);
        fusionFromTo.numRecipes = fusionFromTo.recipes.length;
        fusionFromTo.recipes = fusionFromTo.recipes.slice(fusionFromTo.pageNum * this.$scope.perPage, fusionFromTo.pageNum * this.$scope.perPage + this.$scope.perPage);
    };
    PersonaController.prototype.getPaginateAndFilterFunc = function (isFusionFrom) {
        var _this = this;
        return function (newVal, oldVal, scope) { return _this.paginateAndFilter(isFusionFrom ? scope.fusionFrom : scope.fusionTo, _this.getRecipeFilterFunc(isFusionFrom)); };
    };
    PersonaController.prototype.getRecipeFilterFunc = function (isFusionFrom) {
        var containsIgnoreCase = function (str, filter) { return str.toLowerCase().indexOf(filter.toLowerCase()) !== -1; };
        if (isFusionFrom) {
            return function (filterString) { return function (recipe, index, array) {
                return containsIgnoreCase(recipe.sources[1].name, filterString) || containsIgnoreCase(recipe.result.name, filterString);
            }; };
        }
        else {
            return function (filterString) { return function (recipe, index, array) {
                for (var i = 0; i < recipe.sources.length; i++) {
                    if (containsIgnoreCase(recipe.sources[i].name, filterString)) {
                        return true;
                    }
                }
                return false;
            }; };
        }
    };
    PersonaController.prototype.resetPage = function (fusionFromTo) {
        fusionFromTo.pageNum = 0;
    };
    PersonaController.prototype.getResetPageFunc = function (isFusionFrom) {
        var _this = this;
        return function (newVal, oldVal, scope) { return _this.resetPage(isFusionFrom ? scope.fusionFrom : scope.fusionTo); };
    };
    return PersonaController;
}());
<|endoftext|>


<commit_before>var bump     = require('gulp-bump'),
    uuid     = require('node-uuid'),
    rename   = require('gulp-rename'),
    replace  = require('gulp-replace'),
    jsonfile = require('jsonfile'),
    _        = require('underscore'),
    del      = require('del'),
    os       = require('os'),
    path     = require('path'),
    gutil    = require('gulp-util'),
    fs       = require('fs');

var licenseUtil = require('./license-util.js');

exports.addTasks = function(gulp) {
  var cleanFiles = function() {
    del.sync(['deploy']);
  };

  var die = function() {
    var args = Array.prototype.slice.call(arguments);
    args = _.map(args, function(value) {
      if ( typeof(value) === 'string' ) {
        value = gutil.colors.red(value);
      }
      return value;
    });
    gutil.log.apply(this, args);
    cleanFiles();
    process.exit(1);
  };

  var getBuildTimestamp = function() {
    var time = new Date();

    var ampm = time.getHours() >= 12 ? 'pm' : 'am';

    var monthNames = ["January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    return monthNames[time.getMonth()] + ' ' + time.getDate() + ' ' + time.getFullYear() + ', '
      + (time.getHours() % 12) + ':' + time.getMinutes() + ' ' + ampm;
  };

  var getPackageProperties = function() {
    var json = JSON.parse(fs.readFileSync('package.json', 'utf8'));
    return json;
  };

  var _mod_name = null;
  var getModuleName = function() {
    if ( _mod_name === null ) {
      var props = getPackageProperties();

      if ( !props || !('name' in props) || (props.name.toString().length < 1) ) {
        die("Invalid or missing package name.");
      }

      _mod_name = props.name;
    }

    return _mod_name;
  };

  var getModuleDir = function() {
    return path.join( process.cwd(), 'deploy', getModuleName() );
  };

  gulp.task('LKM - Bump Build Version', function() {
    return gulp.src(['package.json'])
      .pipe(bump())
      .pipe(gulp.dest('./'));
  });

  gulp.task('LKM - Clean', function(cb) {
    cleanFiles();
    cb();
  });

  gulp.task('LKM - Init', ['LKM - Clean', 'LKM - Bump Build Version']);

  gulp.task('LKM - Compile module.xml', ['LKM - Init'], function() {
    try {
      var props = jsonfile.readFileSync( path.join(process.cwd(),'module.properties.json') );
    }
    catch (error) {
      die("You must include a file named 'module.properties.json' in the root of the module.  Received the following error: ", error);
    }
    var stream = gulp.src([ path.join(__dirname,'../template_files/module.template.xml') ])

    // Generate an EnlistmentId
    props.EnlistmentId = uuid.v4();

    var json = getPackageProperties();

    // Get the build time and other stuff
    props.Author      = json.author;
    props.BuildTime   = getBuildTimestamp();
    props.BuildOS     = os.type();
    props.BuildUser   = process.env.USER;
    props.BuildPath   = path.join( getModuleDir(), 'mobile.module' );
    props.Label       = json.description;
    props.License     = json.license;
    props.LicenseURL  = licenseUtil.getLicenseURL(json.license);
    props.ModuleClass = "org.labkey.mobile.mobileModule";
    props.Name        = getModuleName();
    props.SourcePath  = getModuleDir();
    props.Version     = json.version;
    props.Revision    = 'Not built from a Subversion source tree';

    // Replace all of the keys in the configuration
    _.each(props, function(value, key) {
      stream = stream.pipe(replace('@@' + key + '@@', props[key]));
    });

    // Rename the file and write it out
    stream.pipe(rename('module.xml')).pipe(gulp.dest( path.join(getModuleDir(),'config') ));
  });

  gulp.task('LKM - Copy Files', ['LKM - Init'], function() {
    var core = gulp.src([ path.join(__dirname,'../module_files/**') ])
      .pipe(gulp.dest( getModuleDir() ));

    var content = gulp.src([ path.join( process.cwd(), 'content/**') ])
      .pipe(gulp.dest( path.join(getModuleDir(), 'resources/web/mobile/content') ));
  });

  var checkLABKEYROOT = function(no_die) {
    if (no_die) {
      var die = function() {
        var args = Array.prototype.slice.call(arguments);
        throw args.join("");
      }
    }
    if ('LABKEY_ROOT' in process.env) {
      try {
        var stats = fs.lstatSync(process.env.LABKEY_ROOT);
        if ( !stats.isDirectory() ) {
          throw "LABKEY_ROOT needs to be a directory path.";
        }
      }
      catch (error) {
        die("An error occurred while trying to deploy: ", error);
      }
    }
    else {
      die("You need to define LABKEY_ROOT before using gulp to deploy your mobile module.");
    }

    return path.join( process.env.LABKEY_ROOT, 'server', 'optionalModules' );
  };

  var cleanDeployedtask = function() {
    var optionalModulesPath = checkLABKEYROOT();
    var deployedModulePath  = path.join( optionalModulesPath, getModuleName() );

    gutil.log("Clearing out " + deployedModulePath);
    del.sync([ deployedModulePath ], {force: true});
  };

  gulp.task('LKM - Clean-Deployed', cleanDeployedtask);

  var deployTask = function() {
    var optionalModulesPath = checkLABKEYROOT();
    var deployedModulePath  = path.join( optionalModulesPath, getModuleName() );

    gutil.log("Copying " + getModuleDir() + " to " + deployedModulePath);
    gulp.src( path.join(getModuleDir(),'**') ).pipe(gulp.dest( deployedModulePath ));
  };

  gulp.task('LKM - Deploy', ['LKM - Clean-Deployed'], deployTask );

  gulp.task('build_mobile', ['LKM - Compile module.xml', 'LKM - Copy Files'], function() {
    try {
      checkLABKEYROOT(true);

      cleanDeployedtask();
      deployTask();
    }
    catch(error) {
      gutil.log(gutil.colors.yellow("LABKEY_ROOT is not properly defined, so we will not attempt to deploy module."));
    }
  });
};
<commit_msg>Convert die to safe_die to make scoping properly work.<commit_after>var bump     = require('gulp-bump'),
    uuid     = require('node-uuid'),
    rename   = require('gulp-rename'),
    replace  = require('gulp-replace'),
    jsonfile = require('jsonfile'),
    _        = require('underscore'),
    del      = require('del'),
    os       = require('os'),
    path     = require('path'),
    gutil    = require('gulp-util'),
    fs       = require('fs');

var licenseUtil = require('./license-util.js');

exports.addTasks = function(gulp) {
  var cleanFiles = function() {
    del.sync(['deploy']);
  };

  var die = function() {
    var args = Array.prototype.slice.call(arguments);
    args = _.map(args, function(value) {
      if ( typeof(value) === 'string' ) {
        value = gutil.colors.red(value);
      }
      return value;
    });
    gutil.log.apply(this, args);
    cleanFiles();
    process.exit(1);
  };

  var getBuildTimestamp = function() {
    var time = new Date();

    var ampm = time.getHours() >= 12 ? 'pm' : 'am';

    var monthNames = ["January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    return monthNames[time.getMonth()] + ' ' + time.getDate() + ' ' + time.getFullYear() + ', '
      + (time.getHours() % 12) + ':' + time.getMinutes() + ' ' + ampm;
  };

  var getPackageProperties = function() {
    var json = JSON.parse(fs.readFileSync('package.json', 'utf8'));
    return json;
  };

  var _mod_name = null;
  var getModuleName = function() {
    if ( _mod_name === null ) {
      var props = getPackageProperties();

      if ( !props || !('name' in props) || (props.name.toString().length < 1) ) {
        die("Invalid or missing package name.");
      }

      _mod_name = props.name;
    }

    return _mod_name;
  };

  var getModuleDir = function() {
    return path.join( process.cwd(), 'deploy', getModuleName() );
  };

  gulp.task('LKM - Bump Build Version', function() {
    return gulp.src(['package.json'])
      .pipe(bump())
      .pipe(gulp.dest('./'));
  });

  gulp.task('LKM - Clean', function(cb) {
    cleanFiles();
    cb();
  });

  gulp.task('LKM - Init', ['LKM - Clean', 'LKM - Bump Build Version']);

  gulp.task('LKM - Compile module.xml', ['LKM - Init'], function() {
    try {
      var props = jsonfile.readFileSync( path.join(process.cwd(),'module.properties.json') );
    }
    catch (error) {
      die("You must include a file named 'module.properties.json' in the root of the module.  Received the following error: ", error);
    }
    var stream = gulp.src([ path.join(__dirname,'../template_files/module.template.xml') ])

    // Generate an EnlistmentId
    props.EnlistmentId = uuid.v4();

    var json = getPackageProperties();

    // Get the build time and other stuff
    props.Author      = json.author;
    props.BuildTime   = getBuildTimestamp();
    props.BuildOS     = os.type();
    props.BuildUser   = process.env.USER;
    props.BuildPath   = path.join( getModuleDir(), 'mobile.module' );
    props.Label       = json.description;
    props.License     = json.license;
    props.LicenseURL  = licenseUtil.getLicenseURL(json.license);
    props.ModuleClass = "org.labkey.mobile.mobileModule";
    props.Name        = getModuleName();
    props.SourcePath  = getModuleDir();
    props.Version     = json.version;
    props.Revision    = 'Not built from a Subversion source tree';

    // Replace all of the keys in the configuration
    _.each(props, function(value, key) {
      stream = stream.pipe(replace('@@' + key + '@@', props[key]));
    });

    // Rename the file and write it out
    stream.pipe(rename('module.xml')).pipe(gulp.dest( path.join(getModuleDir(),'config') ));
  });

  gulp.task('LKM - Copy Files', ['LKM - Init'], function() {
    var core = gulp.src([ path.join(__dirname,'../module_files/**') ])
      .pipe(gulp.dest( getModuleDir() ));

    var content = gulp.src([ path.join( process.cwd(), 'content/**') ])
      .pipe(gulp.dest( path.join(getModuleDir(), 'resources/web/mobile/content') ));
  });

  var checkLABKEYROOT = function(no_die) {
    var safe_dir;
    if (no_die) {
      safe_die = function() {
        var args = Array.prototype.slice.call(arguments);
        throw args.join("");
      }
    }
    else {
      safe_die = die;
    }

    if ('LABKEY_ROOT' in process.env) {
      try {
        var stats = fs.lstatSync(process.env.LABKEY_ROOT);
        if ( !stats.isDirectory() ) {
          throw "LABKEY_ROOT needs to be a directory path.";
        }
      }
      catch (error) {
        safe_die("An error occurred while trying to deploy: ", error);
      }
    }
    else {
      safe_die("You need to define LABKEY_ROOT before using gulp to deploy your mobile module.");
    }

    return path.join( process.env.LABKEY_ROOT, 'server', 'optionalModules' );
  };

  var cleanDeployedtask = function() {
    var optionalModulesPath = checkLABKEYROOT();
    var deployedModulePath  = path.join( optionalModulesPath, getModuleName() );

    gutil.log("Clearing out " + deployedModulePath);
    del.sync([ deployedModulePath ], {force: true});
  };

  gulp.task('LKM - Clean-Deployed', cleanDeployedtask);

  var deployTask = function() {
    var optionalModulesPath = checkLABKEYROOT();
    var deployedModulePath  = path.join( optionalModulesPath, getModuleName() );

    gutil.log("Copying " + getModuleDir() + " to " + deployedModulePath);
    gulp.src( path.join(getModuleDir(),'**') ).pipe(gulp.dest( deployedModulePath ));
  };

  gulp.task('LKM - Deploy', ['LKM - Clean-Deployed'], deployTask );

  gulp.task('build_mobile', ['LKM - Compile module.xml', 'LKM - Copy Files'], function() {
    try {
      checkLABKEYROOT(true);

      cleanDeployedtask();
      deployTask();
    }
    catch(error) {
      gutil.log(gutil.colors.yellow("LABKEY_ROOT is not properly defined, so we will not attempt to deploy module."));
    }
  });
};
<|endoftext|>


<commit_before>// React
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link, hashHistory } from 'react-router'

// Material UI
import injectTapEventPlugin from 'react-tap-event-plugin'; injectTapEventPlugin()
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import AppBar from 'material-ui/AppBar'
import IconButton from 'material-ui/IconButton'
import Drawer from 'material-ui/Drawer'
import Popover from 'material-ui/Popover'
import { List, ListItem } from 'material-ui/List'
import Divider from 'material-ui/Divider'

// icons
import MenuButton from 'material-ui/svg-icons/navigation/menu'
import ChatIcon from 'material-ui/svg-icons/communication/chat'
import SettingsIcon from 'material-ui/svg-icons/action/settings'
import ExitIcon from 'material-ui/svg-icons/action/exit-to-app'
import AccountIcon from 'material-ui/svg-icons/action/account-circle'

// custom components
import Room from './room'

class Main extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      logged: false
    }
  }

  render() {
    return(
      <MuiThemeProvider>

          <AppBar
            title="chatroom"
            iconElementLeft={  }
            />
          { this.props.children }

      </MuiThemeProvider>
    )
  }
}

class Nav extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      open: false
    }

    this.close = this.close.bind(this)
    this.open = this.open.bind(this)
  }

  close() { this.setState({open: false}) }
  open() { this.setState({open: true}) }

  rooms() {
    // in the future, this would return some recommended rooms, but for now we can hard code them
    const rooms = ['John', 'Paul', 'George', 'Ringo']
    const result = rooms.map((room, i) => {
      return(
        <ListItem
          key = { i }
          primaryText = { room }
          containerElement={ <Link to={ "/room/" + room }/> }
          onTouchTap = { this.close }/>
      )
    })

    return result
  }

  render() {
    return (

        <IconButton onTouchTap = { this.open }>
          <MenuButton/>
        </IconButton>
        <Drawer
          docked = { false }
          open = { this.state.open }
          onRequestChange = { this.close } >
            <List>
              <ListItem primaryText = "Profile" leftIcon = { <AccountIcon /> }/>
              <ListItem primaryText = "Settings" leftIcon = { <SettingsIcon /> }/>
              <ListItem primaryText = "Rooms"
                        leftIcon = { <ChatIcon /> }
                        nestedItems = { this.rooms() }
                        primaryTogglesNestedList = { true }
                        initiallyOpen = { false } />
              <Divider />
              <ListItem primaryText = "Log out"
                leftIcon = { <ExitIcon /> }
                href = "/logout" />
            </List>
        </Drawer>

    )
  }
}

render((
  <Router history = { hashHistory }>
    <Route path = "/" component = { Main }>
      <Route path = "profile" component = { Main } />
      <Route path = "settings" component = { Main } />
      <Route path = "room">
        <Route path = "/room/:roomId" component = { Room }/>
      </Route>
    </Route>
  </Router>
), document.getElementById('app'))
<commit_msg>move icons to the right<commit_after>// React
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link, hashHistory } from 'react-router'

// Material UI
import injectTapEventPlugin from 'react-tap-event-plugin'; injectTapEventPlugin()
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import AppBar from 'material-ui/AppBar'
import IconButton from 'material-ui/IconButton'
import Drawer from 'material-ui/Drawer'
import Popover from 'material-ui/Popover'
import { List, ListItem } from 'material-ui/List'
import Divider from 'material-ui/Divider'

// icons
import MenuButton from 'material-ui/svg-icons/navigation/menu'
import ChatIcon from 'material-ui/svg-icons/communication/chat'
import SettingsIcon from 'material-ui/svg-icons/action/settings'
import ExitIcon from 'material-ui/svg-icons/action/exit-to-app'
import AccountIcon from 'material-ui/svg-icons/action/account-circle'

// custom components
import Room from './room'

class Main extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      logged: false
    }
  }

  render() {
    return(
      <MuiThemeProvider>

          <AppBar
            title="chatroom"
            iconElementLeft={  }
            />
          { this.props.children }

      </MuiThemeProvider>
    )
  }
}

class Nav extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      open: false
    }

    this.close = this.close.bind(this)
    this.open = this.open.bind(this)
  }

  close() { this.setState({open: false}) }
  open() { this.setState({open: true}) }

  rooms() {
    // in the future, this would return some recommended rooms, but for now we can hard code them
    const rooms = ['John', 'Paul', 'George', 'Ringo']
    const result = rooms.map((room, i) => {
      return(
        <ListItem
          key = { i }
          primaryText = { room }
          containerElement={ <Link to={ "/room/" + room }/> }
          onTouchTap = { this.close }/>
      )
    })

    return result
  }

  render() {
    return (

        <IconButton onTouchTap = { this.open }>
          <MenuButton/>
        </IconButton>
        <Drawer
          docked = { false }
          open = { this.state.open }
          onRequestChange = { this.close } >
            <List>
              <ListItem primaryText = "Profile" rightIcon = { <AccountIcon /> }/>
              <ListItem primaryText = "Settings" rightIcon = { <SettingsIcon /> }/>
              <ListItem primaryText = "Rooms"
                        rightIcon = { <ChatIcon /> }
                        nestedItems = { this.rooms() }
                        primaryTogglesNestedList = { true }
                        initiallyOpen = { false } />
              <Divider />
              <ListItem primaryText = "Log out"
                rightIcon = { <ExitIcon /> }
                href = "/logout" />
            </List>
        </Drawer>

    )
  }
}

render((
  <Router history = { hashHistory }>
    <Route path = "/" component = { Main }>
      <Route path = "profile" component = { Main } />
      <Route path = "settings" component = { Main } />
      <Route path = "room">
        <Route path = "/room/:roomId" component = { Room }/>
      </Route>
    </Route>
  </Router>
), document.getElementById('app'))
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, Erik Wienhold
 * All rights reserved.
 *
 * Licensed under the BSD 3-Clause License.
 *   <http://directory.fsf.org/wiki/License:BSD_3Clause>
 */

var _rave = window.parent.rave;

if (!_rave) {
  console.error("Apache Rave not available");
}

/**
 * @return {any} Rave's current page ID
 */
function getCurrentPageId() {
  return _rave.ui.getCurrentPageId();
}

/**
 * Retrieve a widget from Wookie with a given URI.
 *
 * @param {string} uri a widget URI
 *
 * @return {object} a promise resolving to the matching widget
 */
var getWookieWidget = (function () {

  var cache = {};

  return function getWookieWidget(uri) {
    return $.Deferred.promise(function (dfd) {
      if (uri) {
        if (_.has(cache, uri)) {
          dfd.resolve(cache[uri]);
        } else {
          _rave.api.rpc.getAllWidgets({
            successCallback: function (result) {
              var widget = _.find(result.result.resultSet, function (widget) {
                return widget.url === uri;
              });
              if (widget) {
                dfd.resolve(widget);
              } else {
                dfd.reject({ message: "cannot find Wookie widget for URI " + uri });
              }
            }
          });
        }
      } else {
        dfd.reject({ message: "cannot find Wookie widget without a URI" });
      }
    });
  };

}());

/**
 * A a widget from Wookie to the current page.
 *
 * @param {object} widget a widget provided by Wookie
 *
 * @return {object} a promise resolving to the added region widget
 */
function addWookieWidgetToPage(widget) {
  return $.Deferred.promise(function (dfd) {
    _rave.api.rpc.addWidgetToPage({
      pageId: getCurrentPageId(),
      widgetId: widget.id,
      successCallback: function (id) {
        renderWidget(id)
          .then(function (r) { dfd.resolve(r) });
      }
    });
  });
}

/**
 * Render a region widget based on a region widget ID.
 *
 * @param {string} id a region widget ID
 *
 * @return {object} a promise resolving to the rendered region widget
 */
function renderWidget(id) {
  return $.Deferred.promise(function (dfd) {
    // XXX rave.renderNewWidget does not provide a callback to notify the
    // caller when the widget has been registered and rendered. Retrieving the
    // resulting region widget is only possible after it has been registered.
    // We could wait a certain amount of time, in the hope that the widget will
    // be rendered in that time frame. A more robust solution is to monkey patch
    // $.fn.load to intercept the call made by rave.renderNewWidget. Of course
    // this variant is brittle to implementation changes within Rave.

    var _$ = parent.$;
    var _load = parent.$.fn.load;

    _$.fn.load = function (url, callback) {
      _load.call(this, url, function () {
        callback();
        dfd.resolve(getRegionWidget(id));
      });
    };

    // this should invoke $.fn.load synchronously
    _rave.renderNewWidget(id, true, getCurrentPageId());

    // restore $.fn.load, after it was invoked by _rave.renderNewWidget
    _$.fn.load = _load;
  });
}

/**
 * Remove a region widget from the current page. In deatil this means
 * unregistering the region widget and removing its container element from the
 * document.
 *
 * @param {object} widget a region widget
 *
 * @return {object} a promise resolving when the region widget has been removed
 */
function removeRegionWidget(widget) {
  return $.Deferred.promise(function (dfd) {
    _rave.api.rpc.removeWidget({
      widgetId: widget.widgetId,
      successCallback: function () {
        // properly unregister the widget
        _rave.unregisterWidget(widget);

        // manually remove the widget element from the DOM
        getRegionWidgetElement(widget).remove();

        dfd.resolve();
      }
    });
  });
}

/**
 * Get all region widgets on the current page except this application's widget.
 *
 * @return {array} all widgets except this application's widget
 */
var getOtherRegionWidgets = (function () {

  function removeHash(url) {
    return url.replace(/(?:#.*)?$/);
  }

  return function getOtherRegionWidgets() {
    var thisUrl = removeHash(location.href);
    return _rave.getWidgets().filter(function (widget) {
      var url = removeHash(widget.widgetUrl);
      return url !== thisUrl;
    });
  };

}());

/**
 * Remove all region widgets on the current page except this application's
 * widget.
 *
 * @return {object} a promise resolving when every region widget has been
 *                  removed
 */
function clearRegionWidgets() {
  var fns = getOtherRegionWidgets()
    .map(function (widget) {
      return function () {
        return removeRegionWidget(widget);
      };
    });
  return $.Deferred.sequence(fns, 200);
}

/**
 * Get the DOM Element wrapping a given region widget.
 *
 * @param {object} widget a region widget
 *
 * @return {Element} the DOM Element wrapping `widget`
 */
function getRegionWidgetElement(widget) {
  return widget._el.parentElement;
}

/**
 * Get a region widget by its ID.
 *
 * @param {string} id a region widget ID
 *
 * @return {object} the matching region widget
 */
function getRegionWidget(id) {
  return _rave.getWidget(id);
}

/**
 * Register a function filtering publications made on an OpenAjax Managed Hub.
 *
 * @param {function} filter
 *
 * @see http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.ManagedHub_onPublish_callback_function
 */
var setPublishFilter = (function () {

  var hub = _rave.getManagedHub();

  // remember the original onPublish handler
  var _onPublish = hub._p.onPublish;

  return function setPublishFilter(filter) {
    hub._p.onPublish = function (topic, data, pcont, scont) {
      // invoke the filter only when the original handler allows the publication
      return _onPublish.call(this, topic, data, pcont, scont) &&
             filter(topic, data, pcont, scont);
    };
  };

}());

module.exports = {

  get isEmpty() { return _rave.getWidgets().length <= 1 },

  get pageId() { return getCurrentPageId() },

  setPublishFilter: setPublishFilter,

  getWookieWidget: getWookieWidget,

  getRegionWidgetElement: getRegionWidgetElement,

  addWookieWidgetToPage: addWookieWidgetToPage,

  clearRegionWidgets: clearRegionWidgets

};
<commit_msg>fix error in Apache Rave adapter<commit_after>/*
 * Copyright (c) 2014, Erik Wienhold
 * All rights reserved.
 *
 * Licensed under the BSD 3-Clause License.
 *   <http://directory.fsf.org/wiki/License:BSD_3Clause>
 */

var _rave = window.parent.rave;

if (!_rave) {
  console.error("Apache Rave not available");
}

/**
 * @return {any} Rave's current page ID
 */
function getCurrentPageId() {
  return _rave.ui.getCurrentPageId();
}

/**
 * Retrieve a widget from Wookie with a given URI.
 *
 * @param {string} uri a widget URI
 *
 * @return {object} a promise resolving to the matching widget
 */
var getWookieWidget = (function () {

  var cache = {};

  return function getWookieWidget(uri) {
    return $.Deferred.promise(function (dfd) {
      if (uri) {
        if (_.has(cache, uri)) {
          dfd.resolve(cache[uri]);
        } else {
          _rave.api.rpc.getAllWidgets({
            successCallback: function (result) {
              var widget = _.find(result.result.resultSet, function (widget) {
                return widget.url === uri;
              });
              if (widget) {
                dfd.resolve(widget);
              } else {
                dfd.reject({ message: "cannot find Wookie widget for URI " + uri });
              }
            }
          });
        }
      } else {
        dfd.reject({ message: "cannot find Wookie widget without a URI" });
      }
    });
  };

}());

/**
 * A a widget from Wookie to the current page.
 *
 * @param {object} widget a widget provided by Wookie
 *
 * @return {object} a promise resolving to the added region widget
 */
function addWookieWidgetToPage(widget) {
  return $.Deferred.promise(function (dfd) {
    _rave.api.rpc.addWidgetToPage({
      pageId: getCurrentPageId(),
      widgetId: widget.id,
      successCallback: function (id) {
        renderWidget(id)
          .then(function (r) { dfd.resolve(r) });
      }
    });
  });
}

/**
 * Render a region widget based on a region widget ID.
 *
 * @param {string} id a region widget ID
 *
 * @return {object} a promise resolving to the rendered region widget
 */
function renderWidget(id) {
  return $.Deferred.promise(function (dfd) {
    // XXX rave.renderNewWidget does not provide a callback to notify the
    // caller when the widget has been registered and rendered. Retrieving the
    // resulting region widget is only possible after it has been registered.
    // We could wait a certain amount of time, in the hope that the widget will
    // be rendered in that time frame. A more robust solution is to monkey patch
    // $.fn.load to intercept the call made by rave.renderNewWidget. Of course
    // this variant is brittle to implementation changes within Rave.

    var _$ = parent.$;
    var _load = parent.$.fn.load;

    _$.fn.load = function (url, callback) {
      _load.call(this, url, function () {
        callback();
        dfd.resolve(getRegionWidget(id));
      });
    };

    // this should invoke $.fn.load synchronously
    _rave.renderNewWidget(id, true, getCurrentPageId());

    // restore $.fn.load, after it was invoked by _rave.renderNewWidget
    _$.fn.load = _load;
  });
}

/**
 * Remove a region widget from the current page. In deatil this means
 * unregistering the region widget and removing its container element from the
 * document.
 *
 * @param {object} widget a region widget
 *
 * @return {object} a promise resolving when the region widget has been removed
 */
function removeRegionWidget(widget) {
  return $.Deferred.promise(function (dfd) {
    _rave.api.rpc.removeWidget({
      regionWidgetId: widget.regionWidgetId,
      successCallback: function () {
        // properly unregister the widget
        _rave.unregisterWidget(widget);

        // manually remove the widget element from the DOM
        getRegionWidgetElement(widget).remove();

        dfd.resolve();
      }
    });
  });
}

/**
 * Get all region widgets on the current page except this application's widget.
 *
 * @return {array} all widgets except this application's widget
 */
var getOtherRegionWidgets = (function () {

  function removeHash(url) {
    return url.replace(/(?:#.*)?$/);
  }

  return function getOtherRegionWidgets() {
    var thisUrl = removeHash(location.href);
    return _rave.getWidgets().filter(function (widget) {
      var url = removeHash(widget.widgetUrl);
      return url !== thisUrl;
    });
  };

}());

/**
 * Remove all region widgets on the current page except this application's
 * widget.
 *
 * @return {object} a promise resolving when every region widget has been
 *                  removed
 */
function clearRegionWidgets() {
  var fns = getOtherRegionWidgets()
    .map(function (widget) {
      return function () {
        return removeRegionWidget(widget);
      };
    });
  return $.Deferred.sequence(fns, 200);
}

/**
 * Get the DOM Element wrapping a given region widget.
 *
 * @param {object} widget a region widget
 *
 * @return {Element} the DOM Element wrapping `widget`
 */
function getRegionWidgetElement(widget) {
  return widget._el.parentElement;
}

/**
 * Get a region widget by its ID.
 *
 * @param {string} id a region widget ID
 *
 * @return {object} the matching region widget
 */
function getRegionWidget(id) {
  return _rave.getWidget(id);
}

/**
 * Register a function filtering publications made on an OpenAjax Managed Hub.
 *
 * @param {function} filter
 *
 * @see http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.ManagedHub_onPublish_callback_function
 */
var setPublishFilter = (function () {

  var hub = _rave.getManagedHub();

  // remember the original onPublish handler
  var _onPublish = hub._p.onPublish;

  return function setPublishFilter(filter) {
    hub._p.onPublish = function (topic, data, pcont, scont) {
      // invoke the filter only when the original handler allows the publication
      return _onPublish.call(this, topic, data, pcont, scont) &&
             filter(topic, data, pcont, scont);
    };
  };

}());

module.exports = {

  get isEmpty() { return _rave.getWidgets().length <= 1 },

  get pageId() { return getCurrentPageId() },

  setPublishFilter: setPublishFilter,

  getWookieWidget: getWookieWidget,

  getRegionWidgetElement: getRegionWidgetElement,

  addWookieWidgetToPage: addWookieWidgetToPage,

  clearRegionWidgets: clearRegionWidgets

};
<|endoftext|>