<commit_before>// ==UserScript==
// @name         UTS Timetable Generator
// @author       szdc
// @namespace    http://github.com/szdc
// @version      0.1
// @description  Timetable generator for UTS students
// @match        https://mysubjects.uts.edu.au/aplus2015/aptimetable*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
// @copyright    2015+, szdc
// ==/UserScript==

$(document).ready(function () {
  'use strict';

  var subjects   = [],
      activities = [];

  init();

  function init() {
    // Find the table rows that hold the timetable data
    var table = $('table[cellspacing="1"] tr');

    // Process each row
    table.each(processRow);
    console.log('Subjects found: ' + subjects.length);

    // Get all activity groups.
    var activityGroups = getAllActivityGroups();
    console.log('Total activity groups: ' + activityGroups.length);

    // Get all timetable combinations
    var timetableCombinations = cartesianProductOf(activityGroups);
    console.log('Timetable combinations: ' + timetableCombinations.length);

    // Get all valid timetable combinations
    var validTimetables = timetableCombinations.filter(Timetable.isValid);
    console.log('Valid timetables: ' + validTimetables.length);
  }

  /**
   * Processes a timetable row.
   */
  function processRow() {
    var isSubjectHeader = $(this).find('td > a').length > 0,
        isActivityRow   = $(this).attr('bgcolor') === '#eeeeee';

    if (isSubjectHeader) {
      // New subject
      subjects.push(Subject.fromTableRow($(this)));
    } else if (isActivityRow) {
      // New activity under the latest subject
      var subject = subjects[subjects.length - 1];
      subject.addActivity(Activity.fromTableRow($(this), subject));
    }
  }

  /**
   * Gets an array of all activity groups.
   */
  function getAllActivityGroups() {
    return subjects.reduce(function (activityGroups, subject) {
      var groups = subject.getActivityGroups(),
          keys = Object.keys(groups);

      keys.forEach(function (key) {
        activityGroups.push(groups[key]);
      });

      return activityGroups;
    }, []);
  }

  /**
   * Returns the cartesian product of N arrays.
   */
  function cartesianProductOf(arr) {
    return arr.reduce(function(a, b) {
      var ret = [];
      a.forEach(function(a) {
        b.forEach(function(b) {
          ret.push(a.concat([b]));
        });
      });
      return ret;
    }, [[]]);
  }
});

/**
 * Represents a UTS subject.
 */
function Subject(name, code, semester) {
  if (arguments.length < 3) {
    throw new Error('Too few arguments supplied to create the Subject object.');
  }

  var activityGroups = {};

  /**
   * Adds an activity.
   */
  function addActivity(activity) {
    var type = activity.getType();
    if (typeof activityGroups[type] === 'undefined') {
      activityGroups[type] = [];
    }
    activityGroups[type].push(activity);
  }

  return {
    addActivity: addActivity,
    getActivityGroups: function () { return activityGroups; },
    getCode: function () { return code; }
  };
}

/**
 * Creates a new Subject object from a table row.
 */
Subject.fromTableRow = function (row) {
  var content = row.find('b:first');

  var name     = content.text().substr(content.text().indexOf(':') + 1).trim(),
      code     = content.children('a').attr('href').match(/\d+/)[0],
      semester = /AUT/.test(content.text()) ? 'autumn' : 'spring';

  return new Subject(name, code, semester);
};

/**
 * Represents a UTS subject activity.
 */
function Activity(type, number, day, startTime, duration, finishTime, subject) {
  if (arguments.length < 5) {
    throw new Error('Too few arguments supplied to create the Activity object.');
  }

  function hasTimeClashWith(activity) {
    var timeClashExists = startTime <= activity.getFinishTime() && finishTime >= activity.getStartTime();
    return timeClashExists;
  }

  function toString() {
    return day + ' ' + startTime + '-' + finishTime + ': ' + subject.getCode() + ' ' + type + ' ' + number + ' (' + duration + ')';
  }

  return {
    hasTimeClashWith: hasTimeClashWith,
    getStartTime: function () { return startTime; },
    getFinishTime: function () { return finishTime; },
    getType: function () { return type; },
    getNumber: function () { return number; },
    getDay: function () { return day; },
    getSubject: function () { return subject; },
    toString: toString
  };
}

/**
 * Creates a new Activity object from a table row.
 */
Activity.fromTableRow = function (row, subject) {
  var cells = row.children().map(function() {return this.innerHTML;});

  var type       = cells[0],
      number     = cells[1],
      day        = cells[2],
      startTime  = cells[3],
      duration   = cells[4],
      finishTime = new Date('1/1/2015 ' + startTime).addMinutes(duration).get24hrTime(),
      startTime = parseInt(startTime.replace(':', ''));

  return new Activity(type, number, day, startTime, duration, finishTime, subject);
};

function Timetable() {}

/**
 * Determines if an array of activities forms a valid timetable.
 */
Timetable.isValid = function (activities) {
  var invalidTimes = {
    "Mon": [], "Tue": [], "Wed": [], "Thu": [], "Fri": [], "Sat": [], "Sun": []
  };

  var valid = activities.every(function (activity) {
    var conflicts = invalidTimes[activity.getDay()];

    if (conflicts.length === 0) {
      conflicts.push(activity);
      return true;
    }

    for (var i = 0; i < conflicts.length; i++) {
      var existingActivity = conflicts[i];
      if (activity.hasTimeClashWith(existingActivity)) {
        return false;
      }
    }
    conflicts.push(activity);
    return true;
  });

  return valid;
};

/**
 * Adds minutes to the date object.
 */
Date.prototype.addMinutes = function (minutes) {
  return new Date(this.getTime() + parseInt(minutes) * 60000);
};

/**
 * Returns the 24hr-formatted time.
 */
Date.prototype.get24hrTime = function () {
  return this.getHours() * 100 + this.getMinutes();
};

<commit_msg>Added a compare method to the Activity class.<commit_after>// ==UserScript==
// @name         UTS Timetable Generator
// @author       szdc
// @namespace    http://github.com/szdc
// @version      0.1
// @description  Timetable generator for UTS students
// @match        https://mysubjects.uts.edu.au/aplus2015/aptimetable*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
// @copyright    2015+, szdc
// ==/UserScript==

$(document).ready(function () {
  'use strict';

  var subjects   = [],
      activities = [];

  init();

  function init() {
    // Find the table rows that hold the timetable data
    var table = $('table[cellspacing="1"] tr');

    // Process each row
    table.each(processRow);
    console.log('Subjects found: ' + subjects.length);

    // Get all activity groups.
    var activityGroups = getAllActivityGroups();
    console.log('Total activity groups: ' + activityGroups.length);

    // Get all timetable combinations
    var timetableCombinations = cartesianProductOf(activityGroups);
    console.log('Timetable combinations: ' + timetableCombinations.length);

    // Get all valid timetable combinations
    var validTimetables = timetableCombinations.filter(Timetable.isValid);
    console.log('Valid timetables: ' + validTimetables.length);
  }

  /**
   * Processes a timetable row.
   */
  function processRow() {
    var isSubjectHeader = $(this).find('td > a').length > 0,
        isActivityRow   = $(this).attr('bgcolor') === '#eeeeee';

    if (isSubjectHeader) {
      // New subject
      subjects.push(Subject.fromTableRow($(this)));
    } else if (isActivityRow) {
      // New activity under the latest subject
      var subject = subjects[subjects.length - 1];
      subject.addActivity(Activity.fromTableRow($(this), subject));
    }
  }

  /**
   * Gets an array of all activity groups.
   */
  function getAllActivityGroups() {
    return subjects.reduce(function (activityGroups, subject) {
      var groups = subject.getActivityGroups(),
          keys = Object.keys(groups);

      keys.forEach(function (key) {
        activityGroups.push(groups[key]);
      });

      return activityGroups;
    }, []);
  }

  /**
   * Returns the cartesian product of N arrays.
   */
  function cartesianProductOf(arr) {
    return arr.reduce(function(a, b) {
      var ret = [];
      a.forEach(function(a) {
        b.forEach(function(b) {
          ret.push(a.concat([b]));
        });
      });
      return ret;
    }, [[]]);
  }
});

/**
 * Represents a UTS subject.
 */
function Subject(name, code, semester) {
  if (arguments.length < 3) {
    throw new Error('Too few arguments supplied to create the Subject object.');
  }

  var activityGroups = {};

  /**
   * Adds an activity.
   */
  function addActivity(activity) {
    var type = activity.getType();
    if (typeof activityGroups[type] === 'undefined') {
      activityGroups[type] = [];
    }
    activityGroups[type].push(activity);
  }

  return {
    addActivity: addActivity,
    getActivityGroups: function () { return activityGroups; },
    getCode: function () { return code; }
  };
}

/**
 * Creates a new Subject object from a table row.
 */
Subject.fromTableRow = function (row) {
  var content = row.find('b:first');

  var name     = content.text().substr(content.text().indexOf(':') + 1).trim(),
      code     = content.children('a').attr('href').match(/\d+/)[0],
      semester = /AUT/.test(content.text()) ? 'autumn' : 'spring';

  return new Subject(name, code, semester);
};

/**
 * Represents a UTS subject activity.
 */
function Activity(type, number, day, startTime, duration, finishTime, subject) {
  if (arguments.length < 5) {
    throw new Error('Too few arguments supplied to create the Activity object.');
  }

  function hasTimeClashWith(activity) {
    var timeClashExists = startTime <= activity.getFinishTime() && finishTime >= activity.getStartTime();
    return timeClashExists;
  }

  function toString() {
    return day + ' ' + startTime + '-' + finishTime + ': ' + subject.getCode() + ' ' + type + ' ' + number + ' (' + duration + ')';
  }

  return {
    hasTimeClashWith: hasTimeClashWith,
    getStartTime: function () { return startTime; },
    getFinishTime: function () { return finishTime; },
    getType: function () { return type; },
    getNumber: function () { return number; },
    getDay: function () { return day; },
    getSubject: function () { return subject; },
    toString: toString
  };
}

/**
 * Creates a new Activity object from a table row.
 */
Activity.fromTableRow = function (row, subject) {
  var cells = row.children().map(function() {return this.innerHTML;});

  var type       = cells[0],
      number     = cells[1],
      day        = cells[2],
      startTime  = cells[3],
      duration   = cells[4],
      finishTime = new Date('1/1/2015 ' + startTime).addMinutes(duration).get24hrTime(),
      startTime = parseInt(startTime.replace(':', ''));

  return new Activity(type, number, day, startTime, duration, finishTime, subject);
};

/**
 * Compares two activities.
 */
Activity.compare = function (a, b) {
  var days = { "Mon": 0, "Tue": 1, "Wed": 2, "Thu": 3, "Fri": 4, "Sat": 5, "Sun": 6 };

  if (a.getDay() === b.getDay()) {
    return a.getStartTime() - b.getStartTime();
  } else {
    return days[a.getDay()] - days[b.getDay()];
  }
};

function Timetable() {}

/**
 * Determines if an array of activities forms a valid timetable.
 */
Timetable.isValid = function (activities) {
  var invalidTimes = {
    "Mon": [], "Tue": [], "Wed": [], "Thu": [], "Fri": [], "Sat": [], "Sun": []
  };

  var valid = activities.every(function (activity) {
    var conflicts = invalidTimes[activity.getDay()];

    if (conflicts.length === 0) {
      conflicts.push(activity);
      return true;
    }

    for (var i = 0; i < conflicts.length; i++) {
      var existingActivity = conflicts[i];
      if (activity.hasTimeClashWith(existingActivity)) {
        return false;
      }
    }
    conflicts.push(activity);
    return true;
  });

  return valid;
};

/**
 * Adds minutes to the date object.
 */
Date.prototype.addMinutes = function (minutes) {
  return new Date(this.getTime() + parseInt(minutes) * 60000);
};

/**
 * Returns the 24hr-formatted time.
 */
Date.prototype.get24hrTime = function () {
  return this.getHours() * 100 + this.getMinutes();
};

<|endoftext|>


<commit_before>var http = require('http');
var rangeParser = require('range-parser');
var mime = require('mime');
var partFile = require('part-file');
var Readable = require('readable-stream');
var piece = require('./piece');
var util = require('util');

var MIN_BUFFER = 1.5 * 1000 * 1000;

var pipeline = function(inp, out) {
	inp.pipe(out);
	out.on('close', function() {
		inp.destroy();
	});
};

module.exports = function(torrent, file, options) {
	var destination = options.destination;
	var piecesToBuffer = Math.ceil((options.buffer || MIN_BUFFER) / torrent.pieceLength);

	var PieceStream = function(range) {
		Readable.call(this);
		range = range || {start:0, end:file.length-1};
		this.position = ((range.start + file.offset) / torrent.pieceLength) | 0;
		this.remaining = range.end - range.start + 1;
		this.skip = (range.start + file.offset) % torrent.pieceLength;
		this.destroyed = false;
		this._buffer = this.position + Math.min(piecesToBuffer, (this.remaining / torrent.pieceLength) | 0);
		this._onreadable = null;

		server.position = this.position;
	};

	util.inherits(PieceStream, Readable);

	PieceStream.prototype._read = function() {
		if (!this.remaining) return this.push(null);

		var self = this;
		var onread = function(err, data) {
			if (err) return self.emit('error', err);
			if (self.skip) data = data.slice(self.skip);
			if (data.length > self.remaining) data = data.slice(0, self.remaining);
			self.skip = 0;
			self.remaining -= data.length;
			if (self.destroyed) return;
			self.push(data);
			server.position = self.position;
		};

		if (!this.buffering()) return dest.read(this.position++ - start, onread);

		this._onreadable = function(index) {
			if (self.buffering()) return;
			dest.removeListener('readable', self._onreadable);
			dest.read(self.position++ - start, onread);
			server.position = self.position;
		};

		dest.on('readable', this._onreadable);
	};

	PieceStream.prototype.buffering = function() {
		for (var i = this.position; i < this._buffer; i++) {
			if (!dest.readable(i - start)) return true;
		}
		return !dest.readable(this.position - start);
	};

	PieceStream.prototype.destroy = function() {
		this.destroyed = true;
		if (this._onreadable) dest.removeListener('readable', this._onreadable);
		this.emit('close');
	};

	var missing = [];

	var start = (file.offset / torrent.pieceLength) | 0;
	var end = ((file.offset + file.length + 1) / torrent.pieceLength) | 0;
	var dest = partFile(destination, torrent.pieceLength, torrent.pieces.slice(start, end+1));

	var prioritize = function(i) {
		missing.sort(function(a, b) {
			if (a === end) return -1;
			if (b === end) return 1;
			if (a >= i && b < i) return -1;
			if (b >= i && a < i) return 1;
			return a - b;
		});
	};

	var stream = function(range) {
		var s = new PieceStream(range);
		prioritize(s.position);
		return s;
	};

	var lastFile = torrent.files[torrent.files.length-1];
	var pieces = torrent.pieces.map(function(_, i) {
		if (i < start) return;
		if (i > end) return;

		missing.push(i);

		if (i === torrent.pieces.length-1) return piece(((lastFile.length + lastFile.offset) % torrent.pieceLength) || torrent.pieceLength);
		return piece(torrent.pieceLength);
	});

	var server = http.createServer(function(request, response) {
		var range = request.headers.range;

		request.connection.setTimeout(0);
		response.setHeader('Accept-Ranges', 'bytes');
		response.setHeader('Content-Type', mime.lookup(file.name));

		range = range && rangeParser(file.length, range)[0];

		if (!range) {
			response.setHeader('Content-Length', file.length);
			if (request.method === 'HEAD') return response.end();
			pipeline(stream(), response);
			return;
		}

		response.statusCode = 206;
		response.setHeader('Content-Length', range.end - range.start + 1);
		response.setHeader('Content-Range', 'bytes '+range.start+'-'+range.end+'/'+file.length);

		if (request.method === 'HEAD') return response.end();
		pipeline(stream(range), response);
	});

	dest.on('readable', function(index) {
		index += start;
		var i = missing.indexOf(index);
		pieces[index] = null;
		if (i > -1) missing.splice(i, 1);
		server.emit('readable', index);
	});

	prioritize(0);

	server.position = 0;
	server.missing = missing;
	server.filename = file.name;
	server.destination = destination;

	server.sizeof = function(index, offset) {
		var p = pieces[index];
		return p ? p.sizeof(offset) : 0;
	};

	server.select = function(index, force) {
		var p = pieces[index];
		if (!p) return -1;
		var i = p.select();
		return i === -1 && force ? p.select(true) : i;
	};

	server.deselect = function(index, offset) {
		var p = pieces[index];
		if (p) p.deselect(offset);
	};

	server.write = function(index, offset, block) {
		var p = pieces[index];
		if (!p) return;

		var buffer = p.write(offset, block);
		if (!buffer) return;

		dest.write(index - start, buffer, function(err) {
			if (err) return p.reset();
		});
	};

	server.read = function(index, offset, length, callback) {
		dest.read(index - start, function(err, buffer) {
			if (err) return callback(err);
			callback(null, buffer.slice(offset, offset+length));
		});
	};

	return server;
};
<commit_msg>Server now emitting 'finished' signal if the entire download is complete.<commit_after>var http = require('http');
var rangeParser = require('range-parser');
var mime = require('mime');
var partFile = require('part-file');
var Readable = require('readable-stream');
var piece = require('./piece');
var util = require('util');

var MIN_BUFFER = 1.5 * 1000 * 1000;

var pipeline = function(inp, out) {
	inp.pipe(out);
	out.on('close', function() {
		inp.destroy();
	});
};

module.exports = function(torrent, file, options) {
	var destination = options.destination;
	var piecesToBuffer = Math.ceil((options.buffer || MIN_BUFFER) / torrent.pieceLength);

	var PieceStream = function(range) {
		Readable.call(this);
		range = range || {start:0, end:file.length-1};
		this.position = ((range.start + file.offset) / torrent.pieceLength) | 0;
		this.remaining = range.end - range.start + 1;
		this.skip = (range.start + file.offset) % torrent.pieceLength;
		this.destroyed = false;
		this._buffer = this.position + Math.min(piecesToBuffer, (this.remaining / torrent.pieceLength) | 0);
		this._onreadable = null;

		server.position = this.position;
	};

	util.inherits(PieceStream, Readable);

	PieceStream.prototype._read = function() {
		if (!this.remaining) return this.push(null);

		var self = this;
		var onread = function(err, data) {
			if (err) return self.emit('error', err);
			if (self.skip) data = data.slice(self.skip);
			if (data.length > self.remaining) data = data.slice(0, self.remaining);
			self.skip = 0;
			self.remaining -= data.length;
			if (self.destroyed) return;
			self.push(data);
			server.position = self.position;
		};

		if (!this.buffering()) return dest.read(this.position++ - start, onread);

		this._onreadable = function(index) {
			if (self.buffering()) return;
			dest.removeListener('readable', self._onreadable);
			dest.read(self.position++ - start, onread);
			server.position = self.position;
		};

		dest.on('readable', this._onreadable);
	};

	PieceStream.prototype.buffering = function() {
		for (var i = this.position; i < this._buffer; i++) {
			if (!dest.readable(i - start)) return true;
		}
		return !dest.readable(this.position - start);
	};

	PieceStream.prototype.destroy = function() {
		this.destroyed = true;
		if (this._onreadable) dest.removeListener('readable', this._onreadable);
		this.emit('close');
	};

	var missing = [];

	var start = (file.offset / torrent.pieceLength) | 0;
	var end = ((file.offset + file.length + 1) / torrent.pieceLength) | 0;
	var dest = partFile(destination, torrent.pieceLength, torrent.pieces.slice(start, end+1));

	var prioritize = function(i) {
		missing.sort(function(a, b) {
			if (a === end) return -1;
			if (b === end) return 1;
			if (a >= i && b < i) return -1;
			if (b >= i && a < i) return 1;
			return a - b;
		});
	};

	var stream = function(range) {
		var s = new PieceStream(range);
		prioritize(s.position);
		return s;
	};

	var lastFile = torrent.files[torrent.files.length-1];
	var pieces = torrent.pieces.map(function(_, i) {
		if (i < start) return;
		if (i > end) return;

		missing.push(i);

		if (i === torrent.pieces.length-1) return piece(((lastFile.length + lastFile.offset) % torrent.pieceLength) || torrent.pieceLength);
		return piece(torrent.pieceLength);
	});

	var server = http.createServer(function(request, response) {
		var range = request.headers.range;

		request.connection.setTimeout(0);
		response.setHeader('Accept-Ranges', 'bytes');
		response.setHeader('Content-Type', mime.lookup(file.name));

		range = range && rangeParser(file.length, range)[0];

		if (!range) {
			response.setHeader('Content-Length', file.length);
			if (request.method === 'HEAD') return response.end();
			pipeline(stream(), response);
			return;
		}

		response.statusCode = 206;
		response.setHeader('Content-Length', range.end - range.start + 1);
		response.setHeader('Content-Range', 'bytes '+range.start+'-'+range.end+'/'+file.length);

		if (request.method === 'HEAD') return response.end();
		pipeline(stream(range), response);
	});

	dest.on('readable', function(index) {
		index += start;
		var i = missing.indexOf(index);
		pieces[index] = null;
		if (i > -1) missing.splice(i, 1);
		server.emit('readable', index);

		if (pieces.every(function(piece) { return !piece }))
			server.emit('finished');
	});

	prioritize(0);

	server.position = 0;
	server.missing = missing;
	server.filename = file.name;
	server.destination = destination;

	server.sizeof = function(index, offset) {
		var p = pieces[index];
		return p ? p.sizeof(offset) : 0;
	};

	server.select = function(index, force) {
		var p = pieces[index];
		if (!p) return -1;
		var i = p.select();
		return i === -1 && force ? p.select(true) : i;
	};

	server.deselect = function(index, offset) {
		var p = pieces[index];
		if (p) p.deselect(offset);
	};

	server.write = function(index, offset, block) {
		var p = pieces[index];
		if (!p) return;

		var buffer = p.write(offset, block);
		if (!buffer) return;

		dest.write(index - start, buffer, function(err) {
			if (err) return p.reset();
		});
	};

	server.read = function(index, offset, length, callback) {
		dest.read(index - start, function(err, buffer) {
			if (err) return callback(err);
			callback(null, buffer.slice(offset, offset+length));
		});
	};

	return server;
};
<|endoftext|>


<commit_before>// # Subscribe Form Helper
// Usage: `{{subscribe_form}}`
var _ = require('lodash'),

    // (Less) dirty requires
    proxy = require('../../../../helpers/proxy'),
    templates = proxy.templates,
    urlService = proxy.urlService,
    SafeString = proxy.SafeString,

    params = ['error', 'success', 'email'],

    subscribeScript;

function makeHidden(name, extras) {
    return templates.input({
        type: 'hidden',
        name: name,
        className: name,
        extras: extras
    });
}

/**
 * This helper script sets the referrer and current location if not existent.
 *
 * document.querySelector['.location']['value'] = document.querySelector('.location')['value'] || window.location.href;
 */
subscribeScript =
    '<script>' +
    '(function(g,h,o,s,t){' +
    'h[o](\'.location\')[s]=h[o](\'.location\')[s] || g.location.href;' +
    'h[o](\'.referrer\')[s]=h[o](\'.referrer\')[s] || h.referrer;' +
    '})(window,document,\'querySelector\',\'value\');' +
    '</script>';

// We use the name subscribe_form to match the helper for consistency:
module.exports = function subscribe_form(options) { // eslint-disable-line camelcase
    var root = options.data.root,
        data = _.merge({}, options.hash, _.pick(root, params), {
            // routeKeywords.subscribe: 'subscribe'
            action: urlService.utils.urlJoin('/', urlService.utils.getSubdir(), 'subscribe/'),
            script: new SafeString(subscribeScript),
            hidden: new SafeString(
                makeHidden('confirm') +
                makeHidden('location', root.subscribed_url ? 'value=' + root.subscribed_url : '') +
                makeHidden('referrer', root.subscribed_referrer ? 'value=' + root.subscribed_referrer : '')
            )
        });

    return templates.execute('subscribe_form', data, options);
};
<commit_msg>🐛 Fixed missing location/referrer data with multiple {{subscribe_form}} (#9713)<commit_after>// # Subscribe Form Helper
// Usage: `{{subscribe_form}}`
var _ = require('lodash'),

    // (Less) dirty requires
    proxy = require('../../../../helpers/proxy'),
    templates = proxy.templates,
    urlService = proxy.urlService,
    SafeString = proxy.SafeString,

    params = ['error', 'success', 'email'],

    subscribeScript;

function makeHidden(name, extras) {
    return templates.input({
        type: 'hidden',
        name: name,
        className: name,
        extras: extras
    });
}

/**
 * This helper script sets the referrer and current location if not existent.
 *
 * document.querySelector['.location']['value'] = document.querySelector('.location')['value'] || window.location.href;
 */
subscribeScript = `
<script>
    (function(g,h,o,s,t){
        var buster = function(b,m) {
            h[o]('input.'+b).forEach(function (i) {
                i.value=i.value || m;
            });
        };
        buster('location', g.location.href);
        buster('referrer', h.referrer);
    })(window,document,'querySelectorAll','value');
</script>
`;

// We use the name subscribe_form to match the helper for consistency:
module.exports = function subscribe_form(options) { // eslint-disable-line camelcase
    var root = options.data.root,
        data = _.merge({}, options.hash, _.pick(root, params), {
            // routeKeywords.subscribe: 'subscribe'
            action: urlService.utils.urlJoin('/', urlService.utils.getSubdir(), 'subscribe/'),
            script: new SafeString(subscribeScript),
            hidden: new SafeString(
                makeHidden('confirm') +
                makeHidden('location', root.subscribed_url ? 'value=' + root.subscribed_url : '') +
                makeHidden('referrer', root.subscribed_referrer ? 'value=' + root.subscribed_referrer : '')
            )
        });

    return templates.execute('subscribe_form', data, options);
};
<|endoftext|>


<commit_before>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 12 )
{
groet = "Goeiemorgen";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17 && myDate.getHours() <= 24 )
{
groet = "Goedenavond";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({
processing: {
//prompt: (bot) => bot.say('...'),
receive: () => 'processing'
},

start: {
receive: (bot,message) => {
return bot.say(`${groet} - welkom bij Independer.`)
.then(() => 'askName');
}
},

bye: {
prompt: (bot) => bot.say('Geen probleem.'),
receive: () => 'processing'
},

/*
askName: {
prompt: (bot) => bot.say('Hoe heet je?'),
receive: (bot,message) => {
const name = message.text;
return bot.setProp('name', name)
.then(() => bot.say(`Ok ${name}, hoe kan ik je helpen? \n
%[Heb je schade](postback:schade) %[Zoek je een verzekering](postback:zoek)`))
.then(() => 'processing');
},
},
*/

askName: {
    prompt: (bot) => bot.say('Postback is working. What\'s your name?'),
    receive: (bot, message) => {
        const name = message.text;
        return bot.setProp('name', name)
            .then(() => bot.say(`Great! I\'ll call you ${name}`))
            .then(()=> bot.say('Is that OK? %[Yes](postback:bye) %[No](postback:nee)'))
            .then(() => 'speak');
    }
},

error: {
prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
receive: () => ''
},

finish: {
receive: () => 'finish'
},

speak: {
receive: (bot, message) => {

let upperText = message.text.trim().toUpperCase();

console.log('msg :' + upperText);

function updateSilent() {
switch (upperText) {
case "CONNECT ME":
return bot.setProp("silent", true);
case "DISCONNECT":
return bot.setProp("silent", false);
default:
return Promise.resolve();
}
}

function getSilent() {
return bot.getProp("silent");
}

function processMessage(isSilent) {
if (isSilent) {
return Promise.resolve("speak");
}

if (!_.has(scriptRules, upperText)) {
return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
}

var response = scriptRules[upperText];
var lines = response.split('\n');

var p = Promise.resolve();
_.each(lines, function(line) {
line = line.trim();
p = p.then(function() {
console.log(line);
return wait(50).then(function() {
return bot.say(line);
});
});
});

return p.then(() => 'speak');
}

return updateSilent()
.then(getSilent)
.then(processMessage);
}
}
});
<commit_msg>to bed<commit_after>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 12 )
{
groet = "Goeiemorgen";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17 && myDate.getHours() <= 24 )
{
groet = "Goedenavond";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({
processing: {
//prompt: (bot) => bot.say('...'),
receive: () => 'processing'
},

start: {
receive: (bot,message) => {
return bot.say(`${groet} - welkom bij Independer.`)
.then(() => 'askName');
}
},

bye: {
prompt: (bot) => bot.say('Geen probleem.'),
receive: () => 'processing'
},

/*
askName: {
prompt: (bot) => bot.say('Hoe heet je?'),
receive: (bot,message) => {
const name = message.text;
return bot.setProp('name', name)
.then(() => bot.say(`Ok ${name}, hoe kan ik je helpen? \n
%[Heb je schade](postback:schade) %[Zoek je een verzekering](postback:zoek)`))
.then(() => 'processing');
},
},
*/

askName: {
    prompt: (bot) => bot.say('Postback is working. What\'s your name?'),
    receive: (bot, message) => {
        const name = message.text;
        return bot.setProp('name', name)
            .then(() => bot.say(`Great! I\'ll call you ${name}`))
            .then(()=> bot.say('Is that OK? %[Yes](postback:bye) %[No](postback:nee)'))
            .then(() => 'speak');
    }
},

error: {
prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
receive: () => ''
},

finish: {
receive: () => 'finish'
},

speak: {
receive: (bot, message) => {

let upperText = message.text.trim().toUpperCase();

function updateSilent() {
switch (upperText) {
case "CONNECT ME":
return bot.setProp("silent", true);
case "DISCONNECT":
return bot.setProp("silent", false);
default:
return Promise.resolve();
}
}

function getSilent() {
return bot.getProp("silent");
}

function processMessage(isSilent) {
if (isSilent) {
return Promise.resolve("speak");
}

if (!_.has(scriptRules, upperText)) {
  console.log('msg :' + upperText);

return bot.say(`Blamoji and sentences still confuse me. Say 'boe' to chat about something else.`).then(() => 'speak');
}

var response = scriptRules[upperText];
var lines = response.split('\n');

var p = Promise.resolve();
_.each(lines, function(line) {
line = line.trim();
p = p.then(function() {
console.log(line);
return wait(50).then(function() {
return bot.say(line);
});
});
});

return p.then(() => 'speak');
}

return updateSilent()
.then(getSilent)
.then(processMessage);
}
}
});
<|endoftext|>


<commit_before>var displayTime = function(seconds) {
  var s = parseFloat(seconds);
  if (s > 0) {
    return (Math.floor(s / 60).toString() + 'm ' +
            (s % 60).toString() + 's');
  } else {
    return '...';
  }
};

var formatPredictionRow = function(prediction) {
  return '
 ' +
    '' +
    prediction.route + '' +
    '' +
    prediction.direction + ' ' +
    '' +
    displayTime(prediction.seconds) + '
';
};

var tickDown = function(time) {
  var match = /^(\d+)m\s+(\d+)s$/.exec(time);
  if (match) {
    var min = parseInt(match[1]);
    var sec = parseInt(match[2]);
    return displayTime((60 * min) + sec - 1);
  } else {
    return time;
  }
};

var parsePredictions = function(xhrResult) {
  var ret = [];
  $(xhrResult).find('predictions').each(function() {
    var route = $(this).attr('routeTitle');
    $(this).find('direction').each(function() {
      var direction = $(this).attr('title');
      $(this).find('prediction').each(function() {
        ret.push({
          route: route,
          direction: direction,
          seconds: $(this).attr('seconds')
        });
      });
    });
  });
  return _.sortBy(ret, function(p) {
    return parseFloat(p.seconds);
  });
};

var openStop = function(stop, xhrResult) {
  var $box = $('#predictions');
  var $head = $box.find('.panel-heading');
  var predictions = parsePredictions(xhrResult);
  var p;
  $head.find('.title').html(stop.title);
  $box.find('.list-group').html('');
  for (var i = 0; i < predictions.length; i++) {
    $box.find('.list-group').append(formatPredictionRow(predictions[i]));
  }
  $('#map').css('width', '70%');
  $box.show();
};

var loadStop = function(stop) {
  $('#predictions').find('.loading').css({ display: 'block' });
  $('#predictions').find('.refresh').hide();
  $.ajax({
    type: 'GET',
    url: 'http://webservices.nextbus.com/service/publicXMLFeed' +
      '?command=predictions&a=mbta&stopId=' + stop.id,
    dataType: 'xml',
    success: function(data) {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      openStop(stop, data);
    },
    error: function() {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      console.log('An Error occurred');
    }
  });
};

var autoReload = function() {
  if (currentStop) {
    loadStop(currentStop);
  }
  setTimeout(autoReload, 60 * 1000);
};

var currentStop;
var initialLocation;
var boston = { lat: 42.38, lng: -71.1, zoom: 12 };
var browserSupportFlag;
var map;
function setLocation(lat, lng, zoom) {
  map.setCenter(new google.maps.LatLng(lat, lng));
  map.setZoom(zoom);
}

function setLocationToNonGeolocatedDefault() {
  if (window.localStorage.getItem('zoom') &&
      window.localStorage.getItem('lat') &&
      window.localStorage.getItem('lng')) {
    setLocation(
      +window.localStorage.getItem('lat'),
      +window.localStorage.getItem('lng'),
      +window.localStorage.getItem('zoom'));
  } else {
    setLocation(boston.lat, boston.lng, boston.zoom);
  }
}

function initialize() {
  var myOptions = {
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map"), myOptions);
  setLocationToNonGeolocatedDefault();

  // Try W3C Geolocation (Preferred)
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      setLocation(position.coords.latitude, position.coords.longitude, 17);
    }, function() {
    }, {
      timeout: 7000
    });
  }

  google.maps.event.addListener(map, 'bounds_changed', function() {
    window.localStorage.setItem('zoom', map.getZoom());
    window.localStorage.setItem('lat', map.getCenter().lat());
    window.localStorage.setItem('lng', map.getCenter().lng());
  });

  for (var i = 0; i < stops.length; i++) {
    (function(stop) {
      var pos =  new google.maps.LatLng(stop.lat, stop.lon);
      var marker = new google.maps.Marker({
        position: pos,
        map: map,
        title: stop.title
      });
      google.maps.event.addListener(marker, 'click', function() {
        currentStop = stop;
        loadStop(stop);
      });
    }).call(this, stops[i]);
  }

  $('#predictions').find('.close').click(function() {
    $('#map').css('width', '100%');
    $('#predictions').hide();
  });

  $('#predictions').find('.refresh').click(function() {
    if (currentStop) {
      loadStop(currentStop);
    }
  });

  autoReload();
}

google.maps.event.addDomListener(window, 'load', initialize);

var countDownTimer;
var countDown = function() {
  $('.time').each(function() {
    var time = $(this).text();
    $(this).text(tickDown(time));
  });
  countDownTimer = setTimeout(countDown, 1000);
};
countDown();
<commit_msg>Improve time predictions & tick down<commit_after>var displayTime = function(seconds) {
  var s = parseFloat(seconds);
  if (s > 0) {
    return (Math.floor(s / 60).toString() + 'm ' +
            (s % 60).toString() + 's');
  } else {
    return '...';
  }
};
var displayUnixTimeOfArrival = function(time) {
  return displayTime(time - Math.round(Date.now() / 1000));
};

// epochTime is in milliseconds
var formatPredictionRow = function(prediction) {
  var $li = $('
');
  var $route = $('');
  $route.text(prediction.route);
  var $dir = $('');
  $dir.text(prediction.direction);
  var $time = $('');
  $time.attr('data-occurs', prediction.unixTimeOfArrival);
  $time.text(displayUnixTimeOfArrival(prediction.unixTimeOfArrival));
  $li.append(' ', $route, $dir, $time);
  return $li;
};

var parsePredictions = function(xhrResult) {
  var ret = [];
  $(xhrResult).find('predictions').each(function() {
    var route = $(this).attr('routeTitle');
    $(this).find('direction').each(function() {
      var direction = $(this).attr('title');
      $(this).find('prediction').each(function() {
        ret.push({
          route: route,
          direction: direction,
          unixTimeOfArrival: Math.round($(this).attr('epochTime') / 1000),
          affectedByLayover: $(this).attr('affectedByLayover')
        });
      });
    });
  });
  return _.sortBy(ret, function(p) {
    return parseFloat(p.seconds);
  });
};

var openStop = function(stop, xhrResult) {
  var $box = $('#predictions');
  var $head = $box.find('.panel-heading');
  var predictions = parsePredictions(xhrResult);
  var p;
  $head.find('.title').html(stop.title);
  $box.find('.list-group').html('');
  for (var i = 0; i < predictions.length; i++) {
    $box.find('.list-group').append(formatPredictionRow(predictions[i]));
  }
  $('#map').css('width', '70%');
  $box.show();
};

var loadStop = function(stop) {
  $('#predictions').find('.loading').css({ display: 'block' });
  $('#predictions').find('.refresh').hide();
  $.ajax({
    type: 'GET',
    url: 'http://webservices.nextbus.com/service/publicXMLFeed' +
      '?command=predictions&a=mbta&stopId=' + stop.id,
    dataType: 'xml',
    success: function(data) {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      openStop(stop, data);
    },
    error: function() {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      console.log('An Error occurred');
    }
  });
};

var autoReload = function() {
  if (currentStop) {
    loadStop(currentStop);
  }
  setTimeout(autoReload, 60 * 1000);
};

var currentStop;
var initialLocation;
var boston = { lat: 42.38, lng: -71.1, zoom: 12 };
var browserSupportFlag;
var map;
function setLocation(lat, lng, zoom) {
  map.setCenter(new google.maps.LatLng(lat, lng));
  map.setZoom(zoom);
}

function setLocationToNonGeolocatedDefault() {
  if (window.localStorage.getItem('zoom') &&
      window.localStorage.getItem('lat') &&
      window.localStorage.getItem('lng')) {
    setLocation(
      +window.localStorage.getItem('lat'),
      +window.localStorage.getItem('lng'),
      +window.localStorage.getItem('zoom'));
  } else {
    setLocation(boston.lat, boston.lng, boston.zoom);
  }
}

function initialize() {
  var myOptions = {
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map"), myOptions);
  setLocationToNonGeolocatedDefault();

  // Try W3C Geolocation (Preferred)
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      setLocation(position.coords.latitude, position.coords.longitude, 17);
    }, function() {
    }, {
      timeout: 7000
    });
  }

  google.maps.event.addListener(map, 'bounds_changed', function() {
    window.localStorage.setItem('zoom', map.getZoom());
    window.localStorage.setItem('lat', map.getCenter().lat());
    window.localStorage.setItem('lng', map.getCenter().lng());
  });

  for (var i = 0; i < stops.length; i++) {
    (function(stop) {
      var pos =  new google.maps.LatLng(stop.lat, stop.lon);
      var marker = new google.maps.Marker({
        position: pos,
        map: map,
        title: stop.title
      });
      google.maps.event.addListener(marker, 'click', function() {
        currentStop = stop;
        loadStop(stop);
      });
    }).call(this, stops[i]);
  }

  $('#predictions').find('.close').click(function() {
    $('#map').css('width', '100%');
    $('#predictions').hide();
  });

  $('#predictions').find('.refresh').click(function() {
    if (currentStop) {
      loadStop(currentStop);
    }
  });

  autoReload();
}

google.maps.event.addDomListener(window, 'load', initialize);

var countDownTimer;
var countDown = function() {
  $('.time').each(function() {
    var time = $(this).attr('data-occurs');
    $(this).text(displayUnixTimeOfArrival(time));
  });
  countDownTimer = setTimeout(countDown, 1000);
};
countDown();
<|endoftext|>


<commit_before>// set up ========================
var express  = require('express');
var app      = express();                               // create our app w/ express
var morgan = require('morgan');             // log requests to the console (express4)
var bodyParser = require('body-parser');    // pull information from HTML POST (express4)
var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)

// configuration =================

app.use(express.static(__dirname + '/public'));                 // set the static files location /public/img will be /img for users
app.use(morgan('dev'));                                         // log every request to the console
app.use(bodyParser.urlencoded({'extended':'true'}));            // parse application/x-www-form-urlencoded
app.use(bodyParser.json());                                     // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(methodOverride());

// api ---------------------------------------------------------------------
// get daily stats hubbit
app.get('/api/hubbit', function(req, res) {
  var http = require('https');

  var options = {
    host: 'hubbit.chalmers.it',
    path: '/get_stats.json?timeframe=day',
    port: '443',
    headers: {'Authorization': 'Token token=""'}
  };

  callback = function(response) {
    var str = '';

    //another chunk of data has been recieved, so append it to `str`
    response.on('data', function (chunk) {
      str += chunk;
    });

    //the whole response has been recieved, so we just print it out here
    response.on('end', function () {
      res.send(str);
    });
  }

  http.request(options, callback).end();
});

// application -------------------------------------------------------------
app.get('*', function(req, res) {
    res.sendfile('./public/index.html'); // load the single view file
});

// listen (start app with node server.js) ======================================
app.listen(3000);
console.log("App listening on port 3000");
<commit_msg>token is now a secret<commit_after>// set up ========================
//Secrets
var fs = require("fs")
var fileName = "./secrets.json"
var config
try {
  config = require(fileName)
}
catch (err) {
  config = {}
  console.log("unable to read file '" + fileName + "': ", err)
  console.log("see secret-config-sample.json for an example")
}
var express  = require('express');
var app      = express();                               // create our app w/ express
var morgan = require('morgan');             // log requests to the console (express4)
var bodyParser = require('body-parser');    // pull information from HTML POST (express4)
var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)

// configuration =================

app.use(express.static(__dirname + '/public'));                 // set the static files location /public/img will be /img for users
app.use(morgan('dev'));                                         // log every request to the console
app.use(bodyParser.urlencoded({'extended':'true'}));            // parse application/x-www-form-urlencoded
app.use(bodyParser.json());                                     // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(methodOverride());

// api ---------------------------------------------------------------------
// get daily stats hubbit
app.get('/api/hubbit', function(req, res) {
  var http = require('https');

  var options = {
    host: 'hubbit.chalmers.it',
    path: '/get_stats.json?timeframe=day',
    port: '443',
    headers: {'Authorization': 'Token token="'+config.hubbit+'"'}
  };

  callback = function(response) {
    var str = '';

    //another chunk of data has been recieved, so append it to `str`
    response.on('data', function (chunk) {
      str += chunk;
    });

    //the whole response has been recieved, so we just print it out here
    response.on('end', function () {
      res.send(str);
    });
  }

  http.request(options, callback).end();
});

// application -------------------------------------------------------------
app.get('*', function(req, res) {
    res.sendfile('./public/index.html'); // load the single view file
});

// listen (start app with node server.js) ======================================
app.listen(3000);
console.log("App listening on port 3000");
<|endoftext|>


<commit_before>/*
script.js for bresenham_line
author: thibaut voirand
*/

/*Declaring variables*******************************************************************************
***************************************************************************************************/

// canvas related variables
var canvas = document.getElementById('canvasId');
var canvasContext = canvas.getContext('2d');
var canvasData = canvasContext.getImageData(0, 0, canvas.width, canvas.height);

// pixel color and transparency
var rPixel = 255; // red
var gPixel = 0; // green
var bPixel = 0; // blue
var aPixel = 255; // transparency

// input coordinates
var x0;
var y0;
var x1;
var y1;

/*Functions*****************************************************************************************
***************************************************************************************************/

function drawPixel(x, y, r, g, b, a) {
  var index = (x + y * canvas.width) * 4;

  canvasData.data[index + 0] = r;
  canvasData.data[index + 1] = g;
  canvasData.data[index + 2] = b;
  canvasData.data[index + 3] = a;
}

function updateCanvas() {
  canvasContext.putImageData(canvasData, 0, 0);
}

function getOctant(dx, dy) {
  /*
  Returns the octant in which a line is, in the following scheme, with starting point at center:
  \2|1/
  3\|/0
 ---+---
  4/|\7
  /5|6\
  */
  var octant = 0;
  if (dx >= 0 && dy >= 0 && dx <= dy) {
    // octant 1
    octant = 1;
  } else if (dx <= 0 && dy >= 0 && -dx <= dy) {
    // octant 2
    octant = 2;
  } else if (dx <= 0 && dy >= 0 && -dx >= dy) {
    // octant 3
    octant = 3;
  } else if (dx <= 0 && dy <= 0 && -dx >= -dy) {
    // octant 4
    octant = 4;
  } else if (dx <= 0 && dy <= 0 && -dx <= -dy) {
    // octant 5
    octant = 5;
  } else if (dx >= 0 && dy <= 0 && dx <= -dy) {
    // octant 6
    octant = 6;
  } else if (dx >= 0 && dy <= 0 && dx >= -dy) {
    // octant 7
    octant = 7;
  }
  return octant;
}

function switchToOctantZeroFrom(octant, x, y) {
  /*
  Function to apply on starting and ending points coordinates, to move the line's from original
  octant to octant zero
  */
  if (octant == 0) {
    return [x, y];
  } else if (octant == 1) {
    return [y, x];
  } else if (octant == 2) {
    return [y, -x];
  } else if (octant == 3) {
    return [-x, y];
  } else if (octant == 4) {
    return [-x, -y];
  } else if (octant == 5) {
    return [-y, -x];
  } else if (octant == 6) {
    return [-y, x];
  } else if (octant == 7) {
    return [x, -y];
  }
}

function switchFromOctantZeroTo(octant, x, y) {
  /*
  Function to apply on starting and ending points coordinates, to move the line's from octant zero
  back to original octant
  */
  if (octant == 0) {
    return [x, y];
  } else if (octant == 1) {
    return [y, x];
  } else if (octant == 2) {
    return [-y, x];
  } else if (octant == 3) {
    return [-x, y];
  } else if (octant == 4) {
    return [-x, -y];
  } else if (octant == 5) {
    return [-y, -x];
  } else if (octant == 6) {
    return [y, -x];
  } else if (octant == 7) {
    return [x, -y];
  }
}

function drawBresenhamLine(x0, y0, x1, y1, octant){

  [x0, y0] = switchToOctantZeroFrom(octant, x0, y0);
  [x1, y1] = switchToOctantZeroFrom(octant, x1, y1);

  var dx = x1 - y0;
  var dy = y1 - y0;
  var D = 2 * dy - dx;
  var y = y0; //

  for (x = x0; x < x1; x++) {
    // switching back to starting octant and drawing pixels
    drawPixel(
      switchFromOctantZeroTo(octant, x, y)[0],
      switchFromOctantZeroTo(octant, x, y)[1],
      rPixel,
      gPixel,
      bPixel,
      aPixel
    );
    if (D > 0) {
      y = y + 1;
      D = D - 2 * dx;
    }
    D = D + 2 * dy;
  }
}

function getInputCoordinates(){
  /*
  This function assigns user-entered coordinates to the corresponding variables
  */
  x0 = parseInt(document.getElementById('x0Input').value);
  y0 = parseInt(document.getElementById('y0Input').value);
  x1 = parseInt(document.getElementById('x1Input').value);
  y1 = parseInt(document.getElementById('y1Input').value);
}

/*User-Interaction**********************************************************************************
***************************************************************************************************/

document.getElementById('drawButton').onclick = function drawButton() {

  getInputCoordinates();

  var dx = x1 - x0;
  var dy = y1 - y0;

  // case of a single point
  if (dx == 0 && dy == 0) {
    drawPixel(x0, y0, rPixel, gPixel, bPixel, aPixel);
    updateCanvas();
    break;
  }

  var octant = getOctant(dx, dy);

  drawBresenhamLine(x0, y0, x1, y1, octant);

  updateCanvas();
};
<commit_msg>clearCanvas function added<commit_after>/*
script.js for bresenham_line
author: thibaut voirand
*/

/*Declaring variables*******************************************************************************
***************************************************************************************************/

// canvas related variables
var canvas = document.getElementById('canvasId');
var canvasContext = canvas.getContext('2d');
var canvasData = canvasContext.getImageData(0, 0, canvas.width, canvas.height);

// pixel color and transparency
var rPixel = 255; // red
var gPixel = 0; // green
var bPixel = 0; // blue
var aPixel = 255; // transparency

// input coordinates
var x0;
var y0;
var x1;
var y1;

/*Functions*****************************************************************************************
***************************************************************************************************/

function drawPixel(x, y, r, g, b, a) {
  var index = (x + y * canvas.width) * 4;

  canvasData.data[index + 0] = r;
  canvasData.data[index + 1] = g;
  canvasData.data[index + 2] = b;
  canvasData.data[index + 3] = a;
}

function updateCanvas() {
  canvasContext.putImageData(canvasData, 0, 0);
}

function clearCanvas() {
  var j;
  for (j = 0; j < canvasData.data.length; j++) {
    canvasData.data[j] = 0;
  }

  updateCanvas();
}

function getOctant(dx, dy) {
  /*
  Returns the octant in which a line is, in the following scheme, with starting point at center:
  \2|1/
  3\|/0
 ---+---
  4/|\7
  /5|6\
  */
  var octant = 0;
  if (dx >= 0 && dy >= 0 && dx <= dy) {
    // octant 1
    octant = 1;
  } else if (dx <= 0 && dy >= 0 && -dx <= dy) {
    // octant 2
    octant = 2;
  } else if (dx <= 0 && dy >= 0 && -dx >= dy) {
    // octant 3
    octant = 3;
  } else if (dx <= 0 && dy <= 0 && -dx >= -dy) {
    // octant 4
    octant = 4;
  } else if (dx <= 0 && dy <= 0 && -dx <= -dy) {
    // octant 5
    octant = 5;
  } else if (dx >= 0 && dy <= 0 && dx <= -dy) {
    // octant 6
    octant = 6;
  } else if (dx >= 0 && dy <= 0 && dx >= -dy) {
    // octant 7
    octant = 7;
  }
  return octant;
}

function switchToOctantZeroFrom(octant, x, y) {
  /*
  Function to apply on starting and ending points coordinates, to move the line's from original
  octant to octant zero
  */
  if (octant == 0) {
    return [x, y];
  } else if (octant == 1) {
    return [y, x];
  } else if (octant == 2) {
    return [y, -x];
  } else if (octant == 3) {
    return [-x, y];
  } else if (octant == 4) {
    return [-x, -y];
  } else if (octant == 5) {
    return [-y, -x];
  } else if (octant == 6) {
    return [-y, x];
  } else if (octant == 7) {
    return [x, -y];
  }
}

function switchFromOctantZeroTo(octant, x, y) {
  /*
  Function to apply on starting and ending points coordinates, to move the line's from octant zero
  back to original octant
  */
  if (octant == 0) {
    return [x, y];
  } else if (octant == 1) {
    return [y, x];
  } else if (octant == 2) {
    return [-y, x];
  } else if (octant == 3) {
    return [-x, y];
  } else if (octant == 4) {
    return [-x, -y];
  } else if (octant == 5) {
    return [-y, -x];
  } else if (octant == 6) {
    return [y, -x];
  } else if (octant == 7) {
    return [x, -y];
  }
}

function drawBresenhamLine(x0, y0, x1, y1, octant) {
  [x0, y0] = switchToOctantZeroFrom(octant, x0, y0);
  [x1, y1] = switchToOctantZeroFrom(octant, x1, y1);

  var dx = x1 - y0;
  var dy = y1 - y0;
  var D = 2 * dy - dx;
  var y = y0; //

  for (x = x0; x < x1; x++) {
    // switching back to starting octant and drawing pixels
    drawPixel(
      switchFromOctantZeroTo(octant, x, y)[0],
      switchFromOctantZeroTo(octant, x, y)[1],
      rPixel,
      gPixel,
      bPixel,
      aPixel
    );
    if (D > 0) {
      y = y + 1;
      D = D - 2 * dx;
    }
    D = D + 2 * dy;
  }
}

function getInputCoordinates() {
  /*
  This function assigns user-entered coordinates to the corresponding variables
  */
  x0 = parseInt(document.getElementById('x0Input').value);
  y0 = parseInt(document.getElementById('y0Input').value);
  x1 = parseInt(document.getElementById('x1Input').value);
  y1 = parseInt(document.getElementById('y1Input').value);
}

/*User-Interaction**********************************************************************************
***************************************************************************************************/

document.getElementById('drawButton').onclick = function drawButton() {
  getInputCoordinates();

  var dx = x1 - x0;
  var dy = y1 - y0;

  // case of a single point
  if (dx == 0 && dy == 0) {
    drawPixel(x0, y0, rPixel, gPixel, bPixel, aPixel);
    updateCanvas();
    return;
  }

  var octant = getOctant(dx, dy);

  drawBresenhamLine(x0, y0, x1, y1, octant);

  updateCanvas();
};

document.getElementById('clearButton').onclick = function() {
  clearCanvas();
};
<|endoftext|>


<commit_before>
/**
 * Preflight-checks
 */

if ( !process.env.NODE_ENV ) {
  process.env.NODE_ENV = 'development';
}

/**
 * Module dependencies.
 */

nconf       = require('nconf'); // global

var path    = require('path');
var restify = require('restify');
var bunyan  = require('bunyan');

/**
 * Config
 */

nconf.file({
  file : path.join( __dirname, 'config', 'global.json' )
});

/**
 * Logging
 */

var LogglyStream = require( path.join(__dirname, 'helpers', 'logglyStream.js') );
var Logger = bunyan.createLogger({
  name: nconf.get('Logging:Name'),
  serializers: {
    req: bunyan.stdSerializers.req,
    res: bunyan.stdSerializers.res
  },
  streams: [
    { path: path.join(nconf.get('Logging:Dir'),process.env.NODE_ENV+'-'+nconf.get('Server:Name')+'.log') },
    { type: 'raw', stream: new LogglyStream() }
  ]
});

/**
 * Server
 */

var server = restify.createServer({
  name       : nconf.get('Server:Name'),
  version    : nconf.get('Server:DefaultVersion'),
  acceptable : nconf.get('Server:Acceptable'),
  log        : Logger
});

/**
 * Server plugins
 */

var throttleOptions = {
  rate: nconf.get('Server:ThrottleRate'),
  burst: nconf.get('Server:ThrottleBurst'),
  ip: false,
  username: true
};

var corsOptions = {
  origins: nconf.get('CORS:Origins'),
  credentials: nconf.get('CORS:Credentials'),
  headers: nconf.get('CORS:Headers'),
};

var plugins = [
  restify.acceptParser( server.acceptable ),
  restify.throttle( throttleOptions ),
  restify.dateParser(),
  restify.queryParser(),
  restify.fullResponse()
];

if ( process.env.NODE_ENV === 'production' ) {
  plugins.push( restify.CORS(corsOptions) );
  plugins.push( require( path.join(__dirname, 'plugins', 'customAuthorizationParser') )( restify.InvalidHeaderError, restify.NotAuthorizedError ) );
}

plugins.push( restify.bodyParser() );
plugins.push( restify.gzipResponse() );

server.use( plugins );

/**
 * Request / Response Logging
 */

server.on('after', restify.auditLogger({
  log: Logger
}));

/**
 * Server routes
 */

var middlewareList = [
  'root'
].map(function ( middlewareName ) {
  var middleware;
  middleware = require( path.join(__dirname, 'middleware', middlewareName) );
  return middleware.setup( server );
});

/**
 * Listen
 */

server.listen( nconf.get('Server:Port'), function() {
  console.log();
  console.log( '%s now listening on %s', nconf.get('App:Name'), server.url );
  console.log();
});
<commit_msg>Update: Register CORS plugin via server.pre() to make sure it runs before any routes<commit_after>
/**
 * Preflight-checks
 */

if ( !process.env.NODE_ENV ) {
  process.env.NODE_ENV = 'development';
}

/**
 * Module dependencies.
 */

nconf       = require('nconf'); // global

var path    = require('path');
var restify = require('restify');
var bunyan  = require('bunyan');

/**
 * Config
 */

nconf.file({
  file : path.join( __dirname, 'config', 'global.json' )
});

/**
 * Logging
 */

var LogglyStream = require( path.join(__dirname, 'helpers', 'logglyStream.js') );
var Logger = bunyan.createLogger({
  name: nconf.get('Logging:Name'),
  serializers: {
    req: bunyan.stdSerializers.req,
    res: bunyan.stdSerializers.res
  },
  streams: [
    { path: path.join(nconf.get('Logging:Dir'),process.env.NODE_ENV+'-'+nconf.get('Server:Name')+'.log') },
    { type: 'raw', stream: new LogglyStream() }
  ]
});

/**
 * Server
 */

var server = restify.createServer({
  name       : nconf.get('Server:Name'),
  version    : nconf.get('Server:DefaultVersion'),
  acceptable : nconf.get('Server:Acceptable'),
  log        : Logger
});

/**
 * Server plugins
 */

var throttleOptions = {
  rate: nconf.get('Server:ThrottleRate'),
  burst: nconf.get('Server:ThrottleBurst'),
  ip: false,
  username: true
};

var corsOptions = {
  origins: nconf.get('CORS:Origins'),
  credentials: nconf.get('CORS:Credentials'),
  headers: nconf.get('CORS:Headers'),
};

var plugins = [
  restify.acceptParser( server.acceptable ),
  restify.throttle( throttleOptions ),
  restify.dateParser(),
  restify.queryParser(),
  restify.fullResponse()
];

if ( process.env.NODE_ENV === 'production' ) {
  plugins.push( require( path.join(__dirname, 'plugins', 'customAuthorizationParser') )( restify.InvalidHeaderError, restify.NotAuthorizedError ) );
}

plugins.push( restify.bodyParser() );
plugins.push( restify.gzipResponse() );

server.pre( restify.CORS(corsOptions) );
server.use( plugins );

/**
 * Request / Response Logging
 */

server.on('after', restify.auditLogger({
  log: Logger
}));

/**
 * Server routes
 */

var middlewareList = [
  'root'
].map(function ( middlewareName ) {
  var middleware;
  middleware = require( path.join(__dirname, 'middleware', middlewareName) );
  return middleware.setup( server );
});

/**
 * Listen
 */

server.listen( nconf.get('Server:Port'), function() {
  console.log();
  console.log( '%s now listening on %s', nconf.get('App:Name'), server.url );
  console.log();
});
<|endoftext|>


<commit_before>var out;

$( document ).ready(function() {
	var $form = $("form#wiki");
	var $output = $('#articles');
	var $outputElement = $('
');

	var pageids = [];
	$form.submit(function( event ) {
		event.preventDefault();
		var start_article = $(this).find("input[type=text]").val();
		console.log( "Start: ", start_article );
		pageids = [];
		$output.empty();
		getWikiSentence(start_article);
	});

	/* Returns the query URL for the Wikipedia API of a given page */
	function wikiApiUrl(page) {
		var wiki_api_base = "https://en.wikipedia.org/w/api.php?"
		params = {
			action: "parse",
			format: "json",
			page: page,
			redirects: 1,
			prop: "text",
			section: 0,
			disablelimitreport: 1,
			disableeditsection: 1,
			disabletoc: 1,
			noimages: 1
		}
		/* "callback=?" makes jquery pick a custom name for the callback.
		JQuery then knows to set the datatype to JSONP.
		The server wraps the requested JSON in a function call with the callback's name.*/
		var query_url = wiki_api_base + $.param(params) + "&callback=?";
		console.log(query_url);
		return query_url
	}

	/* Returns a parsed structure queryable with JQuery from an HTML string */
	function parseToDOM(html_string) {
		return $($.parseHTML('
' + html_string + '
'));
	}

	/* Return HTML without elements that should not be rendered */
	function cleanWikiHTML(html_string) {
		temp_dom = parseToDOM(html_string);
		temp_dom = temp_dom.children('p');
		// Remove References of the form '[1]''
		temp_dom.children('sup').remove();
		// The box showing coordinates is part of the main html
		temp_dom.find('span#coordinates').remove();
		var html = '';
		temp_dom.each(function() { html += $(this).html() + ' '; });
		return html
	}

	/* Returns a text up to a sentence that ends with an  tag */
	function parseForSentence(html_string) {
		var divider = '.';
		split = html_string.split(divider);
		if ( split.length == 1 ) {
			divider = ').';
			split = html_string.split(divider);
			if ( split.length == 1 ) {
				console.log('No link at the end of a sentence found.')
				return null
			}
		}
		//TODO make "ADD-level" configurable, e.g. use last possible link
		return split[0] + divider;
	}

	/* Return the name of the page linked to from the last  tag */
	function getNextEntryName(sentence_dom) {
		var last_a = sentence_dom.children('a:last');
		var next_entry = last_a.attr('href').split('/wiki/')[1];
		console.log('Next: ', last_a.attr('title'));
		return next_entry
	}

	/* Append text to the page */
	function appendSentences(sentence_dom, include_markup) {
		if ( include_markup ) {
			sentence = sentence_dom.html();
		} else {
			sentence = sentence_dom.text();
		}
		$output.append(
			$outputElement.clone().html(sentence)
		);
	}

	/* Return whether the id was already queried, also stores passed ids */
	function isRepetition(page_id) {
		if ( pageids.indexOf(page_id) > -1 ) {
			console.log('Repetition detected.');
			return true
		}
		pageids.push(page_id);
		return false
	}

	function getWikiSentence(page_title){
		$.getJSON( wikiApiUrl(page_title) )
			.done(function(data) {
				console.log("GET success");
				if ( isRepetition(data.parse.pageid) ) { return }
				var html = cleanWikiHTML(data.parse.text["*"]);
				var sentence = parseForSentence(html);
				if (sentence === null) { return }
				var sentence_dom = parseToDOM(sentence);
				// TODO checkbox for include_markup
				appendSentences(sentence_dom, true);
				var next_entry = getNextEntryName(sentence_dom);
				getWikiSentence(next_entry);
			})
			.fail(function() {
				console.log("Error: ", query);
			});
	}
});

<commit_msg>Minor cleanups and TODOs<commit_after>$( document ).ready(function() {
	var $form = $("form#wiki");
	var $output = $('#articles');
	var $outputElement = $('
');
	var pageids = [];

	/* Setup button handler */
	$form.submit(function( event ) {
		event.preventDefault();
		var start_article = $(this).find("input[type=text]").val();
		console.log( "Start: ", start_article );
		pageids = [];
		$output.empty();
		getWikiSentence(start_article);
	});

	/* Returns the query URL for the Wikipedia API of a given page */
	function wikiApiUrl(page) {
		var wiki_api_base = "https://en.wikipedia.org/w/api.php?"
		params = {
			action: "parse",
			format: "json",
			page: page,
			redirects: 1,
			prop: "text",
			section: 0,
			disablelimitreport: 1,
			disableeditsection: 1,
			disabletoc: 1,
			noimages: 1
		}
		/* "callback=?" makes jquery pick a custom name for the callback.
		JQuery then knows to set the datatype to JSONP.
		The server wraps the requested JSON in a function call with the callback's name.*/
		return wiki_api_base + $.param(params) + "&callback=?";
	}

	/* Returns a parsed structure queryable with JQuery from an HTML string */
	function parseToDOM(html_string) {
		// http://stackoverflow.com/questions/15403600
		return $($.parseHTML('
' + html_string + '
'));
	}

	/* Return HTML without elements that should not be rendered */
	function cleanWikiHTML(html_string) {
		temp_dom = parseToDOM(html_string);
		temp_dom = temp_dom.children('p');
		// Remove References of the form '[1]''
		temp_dom.children('sup').remove();
		// The box showing coordinates is part of the main html
		temp_dom.find('span#coordinates').remove();
		var html = '';
		temp_dom.each(function() { html += $(this).html() + ' '; });
		return html
	}

	/* Returns a text up to a sentence that ends with an  tag */
	function parseForSentence(html_string) {
		var divider = '.';
		split = html_string.split(divider);
		if ( split.length == 1 ) {
			divider = ').';
			split = html_string.split(divider);
			if ( split.length == 1 ) {
				console.log('No link at the end of a sentence found.')
				return null
			}
		}
		//TODO make "ADD-level" configurable, e.g. use last possible link
		return split[0] + divider;
	}

	/* Return the name of the page linked to from the last  tag */
	function getNextEntryName(sentence_dom) {
		//TODO use first link and cut of the sentence to make it properly ADD.
		var last_a = sentence_dom.children('a:last');
		var next_entry = last_a.attr('href').split('/wiki/')[1];
		console.log('Next: ', last_a.attr('title'));
		return next_entry
	}

	/* Append text to the page */
	function appendSentences(sentence_dom, include_markup) {
		if ( include_markup ) {
			sentence = sentence_dom.html();
		} else {
			sentence = sentence_dom.text();
		}
		$output.append(
			$outputElement.clone().html(sentence)
		);
	}

	/* Return whether the id was already queried, also stores passed ids */
	function isRepetition(page_id) {
		if ( pageids.indexOf(page_id) > -1 ) {
			console.log('Repetition detected.');
			return true
		}
		pageids.push(page_id);
		return false
	}

	function getWikiSentence(page_title){
		var query_url = wikiApiUrl(page_title);
		console.log(query_url);
		//TODO save API results to localStorage for caching
		$.getJSON( query_url )
			.done(function(data){
				if ( isRepetition(data.parse.pageid) ) { return }
				var html = cleanWikiHTML(data.parse.text["*"]);
				var sentence = parseForSentence(html);
				if (sentence === null) { return }
				var sentence_dom = parseToDOM(sentence);
				// TODO checkbox for include_markup
				appendSentences(sentence_dom, true);
				var next_entry = getNextEntryName(sentence_dom);
				getWikiSentence(next_entry);
			})
			.fail(function() { console.log("Error: ", query_url); });
	}
});

<|endoftext|>


<commit_before>'use strict';

var colors = require('colors');
var net = require('net');
var fs = require('fs');
var tbox = require('tbox');
var ip = require('ip');

var createPath = tbox.tutils.createPath;
var encoder = new tbox.Encoder('key');
var protocol = new tbox.Protocol();
var userDB = new tbox.UserDB(createPath('userDB.json'));
var serverConfig = new tbox.Config(createPath('config.json'));
var pool = new tbox.ClientPool();

initialize();

var server = net.createServer(function(sock) {
  var chatClient = new tbox.Client(sock);
  sock.write(protocol.motd(serverConfig.getProperty('MOTD')), 'utf8'); //TODO temp
  sock.setEncoding('utf8');
  sock.setTimeout(0);
  sock.on('data', function(data) {
    var msgObj = processMessage(data);

    console.log('<' + sock.remoteAddress.white + ':' + sock.remotePort + '> ' + data.white); // debug

    var userObj = {};
    if(msgObj.cmd === 'REGISTER') { //TODO проверять на целостность и валидность сообщения с данной коммандой

      //TODO проверить зарегистрирован ли уже пользователь с таким id  в pool и если да то...
      if(userDB.checkForUser(msgObj.id)) { //если пользователь есть в базе
        userObj = userDB.getUser(msgObj.id);// получаем пользователя из базы
        chatClient.importUserFromDB(userObj); // импортируем данные пользователя из базы в клиент сервера
        chatClient.register();
        pool.addClient(chatClient);
      } else { // если юзера нет в базе
        console.log('User : ' + msgObj.id.white + ' is not available in DB...');
        userObj = userDB.createUser(msgObj.id, msgObj.prm[0]);
        userDB.addUser(userObj); // добавляем пользователя в базу
        userDB.saveDB();
        chatClient.importUserFromDB(userObj);
        chatClient.register();
        pool.addClient(chatClient);
      }
      console.log('client ' + chatClient.getId().white + ' as ' + chatClient.getNick().red + ' is connected to server');
    }

    //check client for registration on server
    if(chatClient.isRegistered()) {
      processMsgString(msgObj);
    } else {
      sock.write(protocol.error('Client id: ' + msgObj.id + ' is not registered on server'), 'utf8');
    }

  });

  sock.on('close', function() {
    if(pool.checkForClient(chatClient)) {
      console.log('<' + chatClient.getIP().white + ':' + chatClient.getPort() + '> is disconnected from server');
      pool.removeClient(chatClient);
    } else {
      console.log('[server] Anonymous connection closed...');// not need to show
    }
  });

  sock.on('error', function(e) {
    console.log(e);
  });
});

function initialize() {
  console.log('[server] Initializing...');
  serverConfig.load();
  userDB.loadDB();
}

function processMessage(data) {
  //TODO unwrap
  //TODO decode
  return protocol.parseString(data);
}

function processMsgString(msg) {
  var command = msg.cmd;
  var id = msg.id;
  var prm = msg.prm;

  switch (command) {
    case 'REGISTER': //TODO провека на состояние клиента pending, active or banned
      var nick = prm[0];
      if(!userDB.checkForUser(id)) {
        sendTo(id, protocol.registered('Hello ' + nick.white + '! You are registered on server, please wait activation. =)'));
      } else {
        sendTo(id, protocol.registered(nick + ' welcome to trollbox chat!'));
      }
      break;
    case 'TEXT':
      if(prm[0] !== '*') {
        sendTo(prm[0], protocol.text(id, '', prm[1]));
      } else {
        sendToAll(protocol.text(id, '*', prm[1]));
      }
      break;
    case 'ERROR':
      console.log('[server] ERROR %s', param);
    default:
      //TODO обрабатываем как !неверная комманда протокола!
  }
}

function sendTo(userId, str) {
  var client = pool.getClientById(userId);
  try {
    var sock = client.getSocket();
    sock.write(str, 'utf8');
    console.log('[server] string to send: ', str);
  } catch (err) {
    console.log(err.message);
    console.log('[server] Cannot send message: Client is not found.');
  }
}

function sendToAll(str) {
  for (var i = 0; i < pool.getLength(); i++) {
    var client = pool.getClientByIndex(i);
    sendTo(client.getId(), str);
  }
}

server.listen({
  host: 'localhost',
  port: 6666
  }, function() {
    console.log('[server] Starting server listening at: %s:%s', ip.address(), serverConfig.getProperty('Port'));
});
<commit_msg>server now use new utils system<commit_after>'use strict';

var colors = require('colors');
var net = require('net');
var fs = require('fs');
var tbox = require('tbox');
var ip = require('ip');
var createPath = require('tbox/utils/create_path').createPath;

var encoder = new tbox.Encoder('key');
var protocol = new tbox.Protocol();
var userDB = new tbox.UserDB(createPath('userDB.json'));
var serverConfig = new tbox.Config(createPath('config.json'));
var pool = new tbox.ClientPool();

initialize();

var server = net.createServer(function(sock) {
  var chatClient = new tbox.Client(sock);
  sock.write(protocol.motd(serverConfig.getProperty('MOTD')), 'utf8'); //TODO temp
  sock.setEncoding('utf8');
  sock.setTimeout(0);
  sock.on('data', function(data) {
    var msgObj = processReceivedData(data); // msgObj - command in JSON {cmd:'EXAMPLE', prm:'parameter'}

    console.log('<' + sock.remoteAddress.white + ':' + sock.remotePort + '> ' + data.white); // debug

    var userObj = {};
    if(msgObj.cmd === 'REGISTER') { //TODO проверять на целостность и валидность сообщения с данной коммандой

      //TODO проверить зарегистрирован ли уже пользователь с таким id  в pool и если да то не позволять подсоедениться
      if(userDB.checkForUser(msgObj.id)) { //если пользователь есть в базе
        userObj = userDB.getUser(msgObj.id);// получаем пользователя из базы
        chatClient.importUserFromDB(userObj); // импортируем данные пользователя из базы в клиент сервера
        chatClient.register();
        pool.addClient(chatClient);
      } else { // если юзера нет в базе
        console.log('User : ' + msgObj.id.white + ' is not available in DB...');
        userObj = userDB.createUser(msgObj.id, msgObj.prm[0]);
        userDB.addUser(userObj); // добавляем пользователя в базу
        userDB.saveDB();
        chatClient.importUserFromDB(userObj); //TODO
        chatClient.register();                //TODO repeating code
        pool.addClient(chatClient);           //TODO
      }
      console.log('client ' + chatClient.getId().white + ' as ' + chatClient.getNick().red + ' is connected to server');
    }

    //check client for registration on server
    if(chatClient.isRegistered()) {
      processCommand(msgObj);
    } else {
    //TODO добавить шифрование и т.п.
      sock.write(protocol.error('Client id: ' + msgObj.id + ' is not registered on server'), 'utf8');
    }

  });

  sock.on('close', function() {
    if(pool.checkForClient(chatClient)) {
      console.log('<' + chatClient.getIP().white + ':' + chatClient.getPort() + '> is disconnected from server');
      pool.removeClient(chatClient);
    } else {
      console.log('[server] Anonymous connection closed...');// not need to show
    }
  });

  sock.on('error', function(e) {
    console.log(e);
  });
});

function initialize() {
  console.log('[server] Initializing...');
  serverConfig.load();
  userDB.loadDB();
}

function processReceivedData(data) {
  //TODO unwrap
  //TODO decode
  return protocol.parseString(data);
}

function processCommand(msg) {
  var command = msg.cmd;
  var id = msg.id;
  var prm = msg.prm;

  switch (command) {
    case 'REGISTER': //TODO провека на состояние клиента pending, active or banned, make greeting of client to all users
      var nick = prm[0];
      if(!userDB.checkForUser(id)) {
        sendTo(id, protocol.registered('Hello ' + nick.white + '! You are registered on server, please wait activation. =)'));
      } else {
        sendTo(id, protocol.registered(nick + ' welcome to trollbox chat!'));
      }
      break;
    case 'TEXT':
      if(prm[0] !== '*') {
        sendTo(prm[0], protocol.text(id, '', prm[1]));
      } else {
        sendToAll(protocol.text(id, '*', prm[1]));
      }
      break;
    case 'ERROR':
      console.log('[server] ERROR %s', param);
    default:
      //TODO обрабатываем как !неверная комманда протокола!
  }
}

function sendTo(userId, str) {
  var client = pool.getClientById(userId);
  try {
    var sock = client.getSocket();
    sock.write(str, 'utf8');
    console.log('[server] string to send: ', str);
  } catch (err) {
    console.log(err.message);
    console.log('[server] Cannot send message: Client is not found.');
  }
}

function sendToAll(str) {
  for (var i = 0; i < pool.getLength(); i++) {
    var client = pool.getClientByIndex(i);
    sendTo(client.getId(), str);
  }
}

server.listen({
  host: 'localhost',
  port: 6666
  }, function() {
    console.log('[server] Starting server listening at: %s:%s', ip.address(), serverConfig.getProperty('Port'));
});
<|endoftext|>


<commit_before>import apexAddToCaptureGroup from '@salesforce/apex/GE_GiftEntryController.addToCaptureGroup';
import apexCreateCaptureGroup from '@salesforce/apex/GE_GiftEntryController.createCaptureGroup';

jest.mock('@salesforce/apex/GE_GiftEntryController.addToCaptureGroup',
    () => ({ default : jest.fn() }),
    { virtual: true }
);
jest.mock('@salesforce/apex/GE_GiftEntryController.createCaptureGroup',
    () => ({ default : jest.fn() }),
    { virtual: true }
);

import ElevateCaptureGroup from "../elevateCaptureGroup";
import ElevateTokenizeableGift from "../elevateTokenizeableGift";

describe('elevate-capture-group', () => {

    afterEach(() => {
        jest.clearAllMocks();
    });

    it('create capture group returns id of a new capture group', async () => {
        apexCreateCaptureGroup.mockResolvedValue({
            "groupId" : "fake-capture-group-id"
        });

        const captureGroup = new ElevateCaptureGroup();
        const elevateBatchId = await captureGroup.create();

        expect(elevateBatchId).toBe('fake-capture-group-id');
    });

    it('new capture group without id when adding gift then group has id', async () => {
        apexCreateCaptureGroup.mockResolvedValue({
            "groupId" : "fake-capture-group-id"
        });

        const tokenizableGift = getDummyGift();

        const captureGroup = new ElevateCaptureGroup();
        await captureGroup.add(tokenizableGift);

        expect(apexAddToCaptureGroup).toHaveBeenLastCalledWith({
            "groupId": "fake-capture-group-id",
            tokenizedGift: tokenizableGift
        });
    });

    it('capture group with existing id when adding gift then id is unchanged', async () => {
        const captureGroup = new ElevateCaptureGroup('fakeId');

        const tokenizableGift = getDummyGift();

        const authorizedGift = await captureGroup.add(tokenizableGift);

        expect(apexAddToCaptureGroup).toHaveBeenCalledTimes(1);
        expect(apexCreateCaptureGroup).toHaveBeenCalledTimes(0);
    });
});

const getDummyGift = () => {
    return new ElevateTokenizeableGift(
        'DummyFirstName',
        'DummyLastName',
        5.00,
        'USD'
    );
}

describe('elevate-tokenizable-gift', () => {
    afterEach(() => {
        clearDOM();
        jest.clearAllMocks();
    });
});
<commit_msg>elevate tests - existing capture group id mock, stub for retry test<commit_after>import apexAddToCaptureGroup from '@salesforce/apex/GE_GiftEntryController.addToCaptureGroup';
import apexCreateCaptureGroup from '@salesforce/apex/GE_GiftEntryController.createCaptureGroup';

jest.mock('@salesforce/apex/GE_GiftEntryController.addToCaptureGroup',
    () => ({ default : jest.fn() }),
    { virtual: true }
);
jest.mock('@salesforce/apex/GE_GiftEntryController.createCaptureGroup',
    () => ({ default : jest.fn() }),
    { virtual: true }
);

import ElevateCaptureGroup from "../elevateCaptureGroup";
import ElevateTokenizeableGift from "../elevateTokenizeableGift";

describe('elevate-capture-group', () => {

    afterEach(() => {
        jest.clearAllMocks();
    });

    it('create capture group returns id of a new capture group', async () => {
        apexCreateCaptureGroup.mockResolvedValue({
            "groupId" : "fake-capture-group-id"
        });

        const captureGroup = new ElevateCaptureGroup();
        const elevateBatchId = await captureGroup.create();

        expect(elevateBatchId).toBe('fake-capture-group-id');
    });

    it('new capture group without id when adding gift then group has id', async () => {
        apexCreateCaptureGroup.mockResolvedValue({
            "groupId" : "fake-capture-group-id"
        });

        const tokenizableGift = getDummyGift();

        const captureGroup = new ElevateCaptureGroup();
        await captureGroup.add(tokenizableGift);

        expect(apexAddToCaptureGroup).toHaveBeenLastCalledWith({
            "groupId": "fake-capture-group-id",
            tokenizedGift: tokenizableGift
        });

    });

    it('capture group with existing id when adding gift then id is unchanged', async () => {
        // TODO: mock resolved value
        apexAddToCaptureGroup.mockResolvedValue({

        });

        const captureGroup = new ElevateCaptureGroup('fakeId');

        const tokenizableGift = getDummyGift();

        const authorizedGift = await captureGroup.add(tokenizableGift);

        expect(apexAddToCaptureGroup).toHaveBeenCalledTimes(1);
        expect(apexCreateCaptureGroup).toHaveBeenCalledTimes(0);

        // TODO: assert shape/contents of authorized gift
        expect(authorizedGift).toMatchObject({
        //    tokenizedGift: '',
        //    paymentId: '',
        //    authExpiration: '',
        //    status: '',
        //    gatewayTransactionId: '',
        //    paymentMethod: '',
        //    originalTransactionId: '',
        //    groupId: ''
        });
    });

    it('capture group when add fails and retry fails then exception thrown', () => {
        // TODO
    });

});

const getDummyGift = () => {
    return new ElevateTokenizeableGift(
        'DummyFirstName',
        'DummyLastName',
        5.00,
        'USD'
    );
}

describe('elevate-tokenizable-gift', () => {
    afterEach(() => {
        clearDOM();
        jest.clearAllMocks();
    });
});
<|endoftext|>


<commit_before>var express = require('express');
var login = require('./login');
express()
	.set('view engine', 'ejs')
	.use(express.static('./public'))
	.use(login.routes)
	.get('*',function(req,res){
		res.render('index');
	})
	// .listen(3000);<commit_msg>Setting PORT<commit_after>var express = require('express');
var login = require('./login');
var port = process.env.PORT || 3000;
express()
	.set('view engine', 'ejs')
	.use(express.static('./public'))
	.use(login.routes)
	.get('*',function(req,res){
		res.render('index');
	})
	.listen(port);

console.log("Listening on port " + port);<|endoftext|>


<commit_before>var MessageDefinitions = {
    client: {
        /**
         *  Message routing: vk ---> bot ( ---> node ----->am)
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      AgentId: String
         *      Command: 'start'
         *      Intention: String 'register' | 'login'
         *      Mode: 'trusted' | 'untrusted'
         *      Nickname: String  ONLY applicable if Mode is untrusted
         *      Sex: 0 1 2        ONLY applicable if Mode is untrusted
         *      Region:           ONLY applicable if Mode is untrusted
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      AgentId: String
         *      Command: 'stop'
         *      Mode: 'graceful' | 'ungraceful'
         *          graceful means stop until all action messages,
         *          ungraceful means stop it right now whatever unhandled action messages there.
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      AgentId: String
         *      Command: 'reload'
         *      Mode: 'graceful' | 'ungraceful'
         *          graceful means reload until all action messages,
         *          ungraceful means reload it right now whatever unhandled action messages there.
         *  }
         *
         */
        command: {
            eventName: 'command',
            queueName: 'command-vk',
            queueOptions: {durable: true},
            produceOptions: {persistent: true},
            consumeOptions: {noAck: false}
        },

        /**
         *  Message routing: vk ---> bot (----->agent)
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'profile-request' reference action definitions
         *      AgentId: String
         *  }
         *
         *  TODO: coming soon
         *
         *
         *
         *
         *
         */
        actionOut: {
            eventName: 'action-out-client',
            queueName: 'action-out-client',
            queueOptions: {durable: true},
            produceOptions: {persistent: true},
            consumeOptions: {noAck: false}
        }
    }

};

module.exports = MessageDefinitions;<commit_msg>update<commit_after>var MessageDefinitions = {
    client: {
        /**
         *  Message routing: vk ---> bot ( ---> node ----->am)
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      AgentId: String
         *      Command: 'start'
         *      Intention: String 'register' | 'login'
         *      Mode: 'trusted' | 'untrusted'
         *      Nickname: String  ONLY applicable if Mode is untrusted
         *      Sex: 0 1 2        ONLY applicable if Mode is untrusted
         *      Region:           ONLY applicable if Mode is untrusted
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      AgentId: String
         *      Command: 'stop'
         *      Mode: 'graceful' | 'ungraceful'
         *          graceful means stop until all action messages,
         *          ungraceful means stop it right now whatever unhandled action messages there.
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      AgentId: String
         *      Command: 'reload'
         *      Mode: 'graceful' | 'ungraceful'
         *          graceful means reload until all action messages,
         *          ungraceful means reload it right now whatever unhandled action messages there.
         *  }
         *
         */
        command: {
            eventName: 'command',
            queueName: 'command-vk',
            queueOptions: {durable: true},
            produceOptions: {persistent: true},
            consumeOptions: {noAck: false}
        },

        /**
         *  Message routing: vk ---> bot (----->agent)
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'profile-request' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'sync-contacts' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'sync-groups' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'broadcast-txt-contacts' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'broadcast-txt-groups' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'broadcast-img-contacts' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'broadcast-img-groups' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'send-txt-contact' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'send-txt-group' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'send-img-contact' reference action definitions
         *      AgentId: String
         *  }
         *
         *  msg: {
         *      CreateTime: Number: Date#getTime() milliseconds
         *      Action: 'send-img-group' reference action definitions
         *      AgentId: String
         *  }
         *
         */
        actionOut: {
            eventName: 'action-out-client',
            queueName: 'action-out-client',
            queueOptions: {durable: true},
            produceOptions: {persistent: true},
            consumeOptions: {noAck: false}
        }
    }

};

module.exports = MessageDefinitions;<|endoftext|>