<commit_before>define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color",
		"dojox/gfx", "dojox/lang/functional", "../scaler/common"],
	function(lang, arr, Color, g, df, sc){

	var common = lang.getObject("dojox.charting.plot2d.common", true);

	return lang.mixin(common, {
		doIfLoaded: sc.doIfLoaded,
		makeStroke: function(stroke){
			if(!stroke){ return stroke; }
			if(typeof stroke == "string" || stroke instanceof Color){
				stroke = {color: stroke};
			}
			return g.makeParameters(g.defaultStroke, stroke);
		},
		augmentColor: function(target, color){
			var t = new Color(target),
				c = new Color(color);
			c.a = t.a;
			return c;
		},
		augmentStroke: function(stroke, color){
			var s = common.makeStroke(stroke);
			if(s){
				s.color = common.augmentColor(s.color, color);
			}
			return s;
		},
		augmentFill: function(fill, color){
			var fc, c = new Color(color);
			if(typeof fill == "string" || fill instanceof Color){
				return common.augmentColor(fill, color);
			}
			return fill;
		},

		defaultStats: {
			vmin: Number.POSITIVE_INFINITY, vmax: Number.NEGATIVE_INFINITY,
			hmin: Number.POSITIVE_INFINITY, hmax: Number.NEGATIVE_INFINITY
		},

		collectSimpleStats: function(series){
			var stats = lang.delegate(common.defaultStats);
			for(var i = 0; i < series.length; ++i){
				var run = series[i];
				for(var j = 0; j < run.data.length; j++){
					if(run.data[j] !== null){
						if(typeof run.data[j] == "number"){
							// 1D case
							var old_vmin = stats.vmin, old_vmax = stats.vmax;
							if(!("ymin" in run) || !("ymax" in run)){
								arr.forEach(run.data, function(val, i){
									if(val !== null){
										var x = i + 1, y = val;
										if(isNaN(y)){ y = 0; }
										stats.hmin = Math.min(stats.hmin, x);
										stats.hmax = Math.max(stats.hmax, x);
										stats.vmin = Math.min(stats.vmin, y);
										stats.vmax = Math.max(stats.vmax, y);
									}
								});
							}
							if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
							if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
						}else{
							// 2D case
							var old_hmin = stats.hmin, old_hmax = stats.hmax,
								old_vmin = stats.vmin, old_vmax = stats.vmax;
							if(!("xmin" in run) || !("xmax" in run) || !("ymin" in run) || !("ymax" in run)){
								arr.forEach(run.data, function(val, i){
									if(val !== null){
										var x = "x" in val ? val.x : i + 1, y = val.y;
										if(isNaN(x)){ x = 0; }
										if(isNaN(y)){ y = 0; }
										stats.hmin = Math.min(stats.hmin, x);
										stats.hmax = Math.max(stats.hmax, x);
										stats.vmin = Math.min(stats.vmin, y);
										stats.vmax = Math.max(stats.vmax, y);
									}
								});
							}
							if("xmin" in run){ stats.hmin = Math.min(old_hmin, run.xmin); }
							if("xmax" in run){ stats.hmax = Math.max(old_hmax, run.xmax); }
							if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
							if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
						}

						break;
					}
				}
			}
			return stats;
		},

		calculateBarSize: function(/* Number */ availableSize, /* Object */ opt, /* Number? */ clusterSize){
			if(!clusterSize){
				clusterSize = 1;
			}
			var gap = opt.gap, size = (availableSize - 2 * gap) / clusterSize;
			if("minBarSize" in opt){
				size = Math.max(size, opt.minBarSize);
			}
			if("maxBarSize" in opt){
				size = Math.min(size, opt.maxBarSize);
			}
			size = Math.max(size, 1);
			gap = (availableSize - size * clusterSize) / 2;
			return {size: size, gap: gap};	// Object
		},

		collectStackedStats: function(series){
			// collect statistics
			var stats = lang.clone(common.defaultStats);
			if(series.length){
				// 1st pass: find the maximal length of runs
				stats.hmin = Math.min(stats.hmin, 1);
				stats.hmax = df.foldl(series, "seed, run -> Math.max(seed, run.data.length)", stats.hmax);
				// 2nd pass: stack values
				for(var i = 0; i < stats.hmax; ++i){
					var v = series[0].data[i];
					v = v && (typeof v == "number" ? v : v.y);
					if(isNaN(v)){ v = 0; }
					stats.vmin = Math.min(stats.vmin, v);
					for(var j = 1; j < series.length; ++j){
						var t = series[j].data[i];
						t = t && (typeof t == "number" ? t : t.y);
						if(isNaN(t)){ t = 0; }
						v += t;
					}
					stats.vmax = Math.max(stats.vmax, v);
				}
			}
			return stats;
		},

		curve: function(/* Number[] */a, /* Number|String */tension){
			//	FIX for #7235, submitted by Enzo Michelangeli.
			//	Emulates the smoothing algorithms used in a famous, unnamed spreadsheet
			//		program ;)
			var array = a.slice(0);
			if(tension == "x") {
				array[array.length] = array[0];   // add a last element equal to the first, closing the loop
			}
			var p=arr.map(array, function(item, i){
				if(i==0){ return "M" + item.x + "," + item.y; }
				if(!isNaN(tension)) { // use standard Dojo smoothing in tension is numeric
					var dx=item.x-array[i-1].x, dy=array[i-1].y;
					return "C"+(item.x-(tension-1)*(dx/tension))+","+dy+" "+(item.x-(dx/tension))+","+item.y+" "+item.x+","+item.y;
				} else if(tension == "X" || tension == "x" || tension == "S") {
					// use Excel "line smoothing" algorithm (http://xlrotor.com/resources/files.shtml)
					var p0, p1 = array[i-1], p2 = array[i], p3;
					var bz1x, bz1y, bz2x, bz2y;
					var f = 1/6;
					if(i==1) {
						if(tension == "x") {
							p0 = array[array.length-2];
						} else { // "tension == X || tension == "S"
							p0 = p1;
						}
						f = 1/3;
					} else {
						p0 = array[i-2];
					}
					if(i==(array.length-1)) {
						if(tension == "x") {
							p3 = array[1];
						} else { // "tension == X || tension == "S"
							p3 = p2;
						}
						f = 1/3;
					} else {
						p3 = array[i+1];
					}
					var p1p2 = Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
					var p0p2 = Math.sqrt((p2.x-p0.x)*(p2.x-p0.x)+(p2.y-p0.y)*(p2.y-p0.y));
					var p1p3 = Math.sqrt((p3.x-p1.x)*(p3.x-p1.x)+(p3.y-p1.y)*(p3.y-p1.y));

					var p0p2f = p0p2 * f;
					var p1p3f = p1p3 * f;

					if(p0p2f > p1p2/2 && p1p3f > p1p2/2) {
						p0p2f = p1p2/2;
						p1p3f = p1p2/2;
					} else if(p0p2f > p1p2/2) {
						p0p2f = p1p2/2;
						p1p3f = p1p2/2 * p1p3/p0p2;
					} else if(p1p3f > p1p2/2) {
						p1p3f = p1p2/2;
						p0p2f = p1p2/2 * p0p2/p1p3;
					}

					if(tension == "S") {
						if(p0 == p1) { p0p2f = 0; }
						if(p2 == p3) { p1p3f = 0; }
					}

					bz1x = p1.x + p0p2f*(p2.x - p0.x)/p0p2;
					bz1y = p1.y + p0p2f*(p2.y - p0.y)/p0p2;
					bz2x = p2.x - p1p3f*(p3.x - p1.x)/p1p3;
					bz2y = p2.y - p1p3f*(p3.y - p1.y)/p1p3;
				}
				return "C"+(bz1x+","+bz1y+" "+bz2x+","+bz2y+" "+p2.x+","+p2.y);
			});
			return p.join(" ");
		},

		getLabel: function(/*Number*/number, /*Boolean*/fixed, /*Number*/precision){
			return sc.doIfLoaded("dojo/number", function(numberLib){
				return (fixed ? numberLib.format(number, {places : precision}) :
					numberLib.format(number)) || "";
			}, function(){
				return fixed ? number.toFixed(precision) : number.toString();
			});
		}
	});
});
<commit_msg>fixes #17126. Fix computation of xmin/xmax when ymin/ymax is present on indexed series. !strict<commit_after>define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color",
		"dojox/gfx", "dojox/lang/functional", "../scaler/common"],
	function(lang, arr, Color, g, df, sc){

	var common = lang.getObject("dojox.charting.plot2d.common", true);

	return lang.mixin(common, {
		doIfLoaded: sc.doIfLoaded,
		makeStroke: function(stroke){
			if(!stroke){ return stroke; }
			if(typeof stroke == "string" || stroke instanceof Color){
				stroke = {color: stroke};
			}
			return g.makeParameters(g.defaultStroke, stroke);
		},
		augmentColor: function(target, color){
			var t = new Color(target),
				c = new Color(color);
			c.a = t.a;
			return c;
		},
		augmentStroke: function(stroke, color){
			var s = common.makeStroke(stroke);
			if(s){
				s.color = common.augmentColor(s.color, color);
			}
			return s;
		},
		augmentFill: function(fill, color){
			var fc, c = new Color(color);
			if(typeof fill == "string" || fill instanceof Color){
				return common.augmentColor(fill, color);
			}
			return fill;
		},

		defaultStats: {
			vmin: Number.POSITIVE_INFINITY, vmax: Number.NEGATIVE_INFINITY,
			hmin: Number.POSITIVE_INFINITY, hmax: Number.NEGATIVE_INFINITY
		},

		collectSimpleStats: function(series){
			var stats = lang.delegate(common.defaultStats);
			for(var i = 0; i < series.length; ++i){
				var run = series[i];
				for(var j = 0; j < run.data.length; j++){
					if(run.data[j] !== null){
						if(typeof run.data[j] == "number"){
							// 1D case
							var old_vmin = stats.vmin, old_vmax = stats.vmax;
							arr.forEach(run.data, function(val, i){
								if(val !== null){
									var x = i + 1, y = val;
									if(isNaN(y)){ y = 0; }
									stats.hmin = Math.min(stats.hmin, x);
									stats.hmax = Math.max(stats.hmax, x);
									stats.vmin = Math.min(stats.vmin, y);
									stats.vmax = Math.max(stats.vmax, y);
								}
							});
							if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
							if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
						}else{
							// 2D case
							var old_hmin = stats.hmin, old_hmax = stats.hmax,
								old_vmin = stats.vmin, old_vmax = stats.vmax;
							if(!("xmin" in run) || !("xmax" in run) || !("ymin" in run) || !("ymax" in run)){
								arr.forEach(run.data, function(val, i){
									if(val !== null){
										var x = "x" in val ? val.x : i + 1, y = val.y;
										if(isNaN(x)){ x = 0; }
										if(isNaN(y)){ y = 0; }
										stats.hmin = Math.min(stats.hmin, x);
										stats.hmax = Math.max(stats.hmax, x);
										stats.vmin = Math.min(stats.vmin, y);
										stats.vmax = Math.max(stats.vmax, y);
									}
								});
							}
							if("xmin" in run){ stats.hmin = Math.min(old_hmin, run.xmin); }
							if("xmax" in run){ stats.hmax = Math.max(old_hmax, run.xmax); }
							if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
							if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
						}

						break;
					}
				}
			}
			return stats;
		},

		calculateBarSize: function(/* Number */ availableSize, /* Object */ opt, /* Number? */ clusterSize){
			if(!clusterSize){
				clusterSize = 1;
			}
			var gap = opt.gap, size = (availableSize - 2 * gap) / clusterSize;
			if("minBarSize" in opt){
				size = Math.max(size, opt.minBarSize);
			}
			if("maxBarSize" in opt){
				size = Math.min(size, opt.maxBarSize);
			}
			size = Math.max(size, 1);
			gap = (availableSize - size * clusterSize) / 2;
			return {size: size, gap: gap};	// Object
		},

		collectStackedStats: function(series){
			// collect statistics
			var stats = lang.clone(common.defaultStats);
			if(series.length){
				// 1st pass: find the maximal length of runs
				stats.hmin = Math.min(stats.hmin, 1);
				stats.hmax = df.foldl(series, "seed, run -> Math.max(seed, run.data.length)", stats.hmax);
				// 2nd pass: stack values
				for(var i = 0; i < stats.hmax; ++i){
					var v = series[0].data[i];
					v = v && (typeof v == "number" ? v : v.y);
					if(isNaN(v)){ v = 0; }
					stats.vmin = Math.min(stats.vmin, v);
					for(var j = 1; j < series.length; ++j){
						var t = series[j].data[i];
						t = t && (typeof t == "number" ? t : t.y);
						if(isNaN(t)){ t = 0; }
						v += t;
					}
					stats.vmax = Math.max(stats.vmax, v);
				}
			}
			return stats;
		},

		curve: function(/* Number[] */a, /* Number|String */tension){
			//	FIX for #7235, submitted by Enzo Michelangeli.
			//	Emulates the smoothing algorithms used in a famous, unnamed spreadsheet
			//		program ;)
			var array = a.slice(0);
			if(tension == "x") {
				array[array.length] = array[0];   // add a last element equal to the first, closing the loop
			}
			var p=arr.map(array, function(item, i){
				if(i==0){ return "M" + item.x + "," + item.y; }
				if(!isNaN(tension)) { // use standard Dojo smoothing in tension is numeric
					var dx=item.x-array[i-1].x, dy=array[i-1].y;
					return "C"+(item.x-(tension-1)*(dx/tension))+","+dy+" "+(item.x-(dx/tension))+","+item.y+" "+item.x+","+item.y;
				} else if(tension == "X" || tension == "x" || tension == "S") {
					// use Excel "line smoothing" algorithm (http://xlrotor.com/resources/files.shtml)
					var p0, p1 = array[i-1], p2 = array[i], p3;
					var bz1x, bz1y, bz2x, bz2y;
					var f = 1/6;
					if(i==1) {
						if(tension == "x") {
							p0 = array[array.length-2];
						} else { // "tension == X || tension == "S"
							p0 = p1;
						}
						f = 1/3;
					} else {
						p0 = array[i-2];
					}
					if(i==(array.length-1)) {
						if(tension == "x") {
							p3 = array[1];
						} else { // "tension == X || tension == "S"
							p3 = p2;
						}
						f = 1/3;
					} else {
						p3 = array[i+1];
					}
					var p1p2 = Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
					var p0p2 = Math.sqrt((p2.x-p0.x)*(p2.x-p0.x)+(p2.y-p0.y)*(p2.y-p0.y));
					var p1p3 = Math.sqrt((p3.x-p1.x)*(p3.x-p1.x)+(p3.y-p1.y)*(p3.y-p1.y));

					var p0p2f = p0p2 * f;
					var p1p3f = p1p3 * f;

					if(p0p2f > p1p2/2 && p1p3f > p1p2/2) {
						p0p2f = p1p2/2;
						p1p3f = p1p2/2;
					} else if(p0p2f > p1p2/2) {
						p0p2f = p1p2/2;
						p1p3f = p1p2/2 * p1p3/p0p2;
					} else if(p1p3f > p1p2/2) {
						p1p3f = p1p2/2;
						p0p2f = p1p2/2 * p0p2/p1p3;
					}

					if(tension == "S") {
						if(p0 == p1) { p0p2f = 0; }
						if(p2 == p3) { p1p3f = 0; }
					}

					bz1x = p1.x + p0p2f*(p2.x - p0.x)/p0p2;
					bz1y = p1.y + p0p2f*(p2.y - p0.y)/p0p2;
					bz2x = p2.x - p1p3f*(p3.x - p1.x)/p1p3;
					bz2y = p2.y - p1p3f*(p3.y - p1.y)/p1p3;
				}
				return "C"+(bz1x+","+bz1y+" "+bz2x+","+bz2y+" "+p2.x+","+p2.y);
			});
			return p.join(" ");
		},

		getLabel: function(/*Number*/number, /*Boolean*/fixed, /*Number*/precision){
			return sc.doIfLoaded("dojo/number", function(numberLib){
				return (fixed ? numberLib.format(number, {places : precision}) :
					numberLib.format(number)) || "";
			}, function(){
				return fixed ? number.toFixed(precision) : number.toString();
			});
		}
	});
});
<|endoftext|>


<commit_before>var format = require('util').format;

module.exports = {

  forSeeds: function(opts) {
    return Post.query(function(qb) {

      qb.limit(opts.limit);
      qb.offset(opts.offset);
      qb.where({active: true});

      if (opts.users) {
        qb.whereIn('post.creator_id', opts.users);
      }

      if (opts.communities) {
        qb.join('post_community', 'post_community.post_id', '=', 'post.id');
        qb.whereIn('post_community.community_id', opts.communities);
      }

      if (opts.term) {
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['post.name', 'post.description']
        });
      }

      if (opts.type && opts.type != 'all') {
        qb.where({type: opts.type});
      }

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('((post.creation_date between ? and ?) or (post.last_updated between ? and ?))',
          [opts.start_time, opts.end_time, opts.start_time, opts.end_time]);
      }

      if (opts.sort) {
        qb.orderBy(opts.sort, 'desc');
      }

    });
  },

  forUsers: function(opts) {
    return User.query(function(qb) {

      qb.limit(opts.limit || 1000);
      qb.offset(opts.offset || 0);
      qb.distinct('users.id');
      qb.where("users.active", "=", true);

      if (opts.communities) {
        qb.join('users_community', 'users_community.users_id', '=', 'users.id');
        qb.whereIn('users_community.community_id', opts.communities);
      }

      if (opts.term) {
        qb.leftJoin('users_skill', 'users_skill.user_id', '=', 'users.id');
        qb.leftJoin('users_org', 'users_org.user_id', '=', 'users.id');
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['users.name', 'users.bio', 'users_skill.skill_name', 'users_org.org_name']
        });
      }

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('users.date_created between ? and ?', [opts.start_time, opts.end_time]);
      }

    });
  },

  addTermToQueryBuilder: function(term, qb, opts) {
    var query = _.chain(term.split(/\s*\s/)) // split on whitespace
      .map(function(word) {
        // remove any invalid characters
        return word.replace(/[,;'|:&()!]+/, '');
      })
      .reject(_.isEmpty)
      .reduce(function(result, word, key) {
        // build the tsquery string using logical | (OR) operands
        result += " | " + word;
        return result;
      }).value(),

      statement = '(' + opts.columns.map(function(col) {
      return format("(to_tsvector('english', %s) @@ to_tsquery(?))", col);
    }).join(' or ') + ')',

      values = _.times(opts.columns.length, function() { return query });

    qb.where(function() {
      this.whereRaw(statement, values);
    });
  }

}<commit_msg>remove ambiguity<commit_after>var format = require('util').format;

module.exports = {

  forSeeds: function(opts) {
    return Post.query(function(qb) {

      qb.limit(opts.limit);
      qb.offset(opts.offset);
      qb.where({'post.active': true});

      if (opts.users) {
        qb.whereIn('post.creator_id', opts.users);
      }

      if (opts.communities) {
        qb.join('post_community', 'post_community.post_id', '=', 'post.id');
        qb.whereIn('post_community.community_id', opts.communities);
      }

      if (opts.term) {
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['post.name', 'post.description']
        });
      }

      if (opts.type && opts.type != 'all') {
        qb.where({type: opts.type});
      }

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('((post.creation_date between ? and ?) or (post.last_updated between ? and ?))',
          [opts.start_time, opts.end_time, opts.start_time, opts.end_time]);
      }

      if (opts.sort) {
        qb.orderBy(opts.sort, 'desc');
      }

    });
  },

  forUsers: function(opts) {
    return User.query(function(qb) {

      qb.limit(opts.limit || 1000);
      qb.offset(opts.offset || 0);
      qb.distinct('users.id');
      qb.where("users.active", "=", true);

      if (opts.communities) {
        qb.join('users_community', 'users_community.users_id', '=', 'users.id');
        qb.whereIn('users_community.community_id', opts.communities);
      }

      if (opts.term) {
        qb.leftJoin('users_skill', 'users_skill.user_id', '=', 'users.id');
        qb.leftJoin('users_org', 'users_org.user_id', '=', 'users.id');
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['users.name', 'users.bio', 'users_skill.skill_name', 'users_org.org_name']
        });
      }

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('users.date_created between ? and ?', [opts.start_time, opts.end_time]);
      }

    });
  },

  addTermToQueryBuilder: function(term, qb, opts) {
    var query = _.chain(term.split(/\s*\s/)) // split on whitespace
      .map(function(word) {
        // remove any invalid characters
        return word.replace(/[,;'|:&()!]+/, '');
      })
      .reject(_.isEmpty)
      .reduce(function(result, word, key) {
        // build the tsquery string using logical | (OR) operands
        result += " | " + word;
        return result;
      }).value(),

      statement = '(' + opts.columns.map(function(col) {
      return format("(to_tsvector('english', %s) @@ to_tsquery(?))", col);
    }).join(' or ') + ')',

      values = _.times(opts.columns.length, function() { return query });

    qb.where(function() {
      this.whereRaw(statement, values);
    });
  }

}<|endoftext|>


<commit_before>import '/imports/startup/client';
import '/imports/startup/both';
import '/imports/ui/layouts';
import '/imports/ui/pages';
import '/imports/ui/stylesheets/style.css';
<commit_msg>Migrated to 1.4 and use of imports/ directory.<commit_after>import '/imports/startup/client';
import '/imports/startup/both';
import '/imports/ui/layouts';
import '/imports/ui/pages';
import '/imports/ui/stylesheets/style.css';

// The following is a hack for autoform. Remove it once autoform is removed.
import { Stuff } from '../imports/api/stuff/Stuff.js';
window.Stuff = Stuff;
<|endoftext|>


<commit_before>'use strict';

import WebSocket from 'ws';
import EventEmitter from 'events';

export default class DaemonInterface extends EventEmitter {

  constructor() {
    super();
    console.log("DaemonInterface constructor start");
    this.ws = new WebSocket('ws://localhost:8888');
    this.wsOpen = false;
    this.useTestNet = true;
    this.identities = []; // looks like this: [currentIdentity, [list, of, identities]]
    this.pockets = []; //Only remember the pockets of the current identity.
    this.pendingRequests = []; //Requests sent to the daemon to be handled on message
  }

  /* ***************** */
  /* Utility functions */
  /* ***************** */

  init() {
    console.log("DaemonInterface init");

    this.ws.on("open", () => {
      this.wsOpen = true;
      this.dwGetAccounts();
    });

    this.ws.on('message', (data, flags) => {
      // flags.binary will be set if a binary data is received.
      // flags.masked will be set if the data was masked.
      // Handle the message (show success or failure message in the UI, etc)
      let message = JSON.parse(data);
      this.handleDaemonMessage(message);
      console.log(message.id);
      delete this.pendingRequests[message.id]; //Remove the request from the pending array
      console.log(this.pendingRequests);
    });

    console.log("DaemonInterface init complete")
  }

  sendMessage = (message) => { //Sends a message to the daemon
    if(this.wsOpen){
      this.pendingRequests[message.id] = (message);
      try {
        this.ws.send(JSON.stringify(message));
      } catch(e) {
        console.log(e.name);
        if(e.name == "Error") {
          this.emit("daemonMessage", {
            name: "daemonDisconnected",
            type: "error",
            text: "Disconnected (try ctrl+r)",
          });
          this.emit("deleteDaemonMessage", "loggingIn");
        }
      }
    } else {
      //TODO: Throw an error / restart the daemon
      console.log("WebSocket Not Open Yet!");
      this.emit("daemonMessage", {
        name: "daemonDisconnected",
        type: "error",
        text: "Disconnected (try ctrl+r)",
      });
    }
  };

  shouldEmitPocketsReady(messageId){
    for(let id in this.pendingRequests) {
      let request = this.pendingRequests[id];
      if(request.id != messageId && (
          request.command == "dw_receive" ||
          request.command == "dw_balance" ||
          request.command == "dw_history" ||
          request.command == "dw_stealth" )
        ) {
        return; //There are other pending pocket requests Don't emit an event.
      }
    }
    //This was the last pocket-related query request. Emit a ready event.
    this.emit("pocketsListReady", this.pockets);
  }

  generateTransactionId() { //Used for transaction IDs
    return parseInt(Math.random() * 4294967295);
  }

  /* ************** */
  /* Public Methods */
  /* ************** */

  startLogin = (accountName, password) => {
      this.emit("daemonMessageDelete", "wrongPassword");
      this.emit("daemonMessage", {
        name: "loggingIn",
        type: "info",
        text: "Logging In...",
      });
      this.dwSetAccount(accountName, password);
  };

  createIdentity = (identityName, password, useTestNet) => {
    this.emit("daemonMessageDelete", "passwordMismatch");
    this.emit('daemonMessage', {
        name: "creatingIdentity",
        type: "info",
        text: "Creating Identity...",
    });
    this.dwCreateAccount(identityName, password, useTestNet);
  }

  restoreIdentity = (identityName, password, brainwallet, useTestNet) => {
    this.emit('daemonMessage', {
        name: "restoringIdentity",
        type: "info",
        text: "Restoring Identity...",
    });
    this.dwRestoreAccount(identityName, password, brainwallet, useTestNet);
  }

  deleteIdentity = (identityName) => {
    this.dwDeleteAccount(identityName);
  }

  createPocket = (pocketName) => {
    this.emit('daemonMessage', {
        name: "creatingPocket",
        type: "info",
        text: "Creating Pocket...",
    });
    this.dwCreatePocket(pocketName);
  }

  validateAddress = (address) => {
    this.dwValidateAddress(address);
  }

  sendCoins = (address, amount, pocket, fee) => {
    this.dwSend(address, amount, pocket, fee);
  }

  backupIdentity = () => {
    this.dwSeed();
  }

  /* **************** */
  /* Message Handlers */
  /* **************** */

  handleDaemonMessage = (message) => {
    if(message.error != null) {
      console.log(message.error);

      if(message.error == "wrong_password"){
        this.emit("daemonMessageDelete", "loggingIn");
        this.emit("daemonMessage", {
          name: "wrongPassword",
          type: "error",
          text: "Wrong password!",
        });
      }
      if(message.error == "invalid_brainwallet"){
        this.emit("daemonMessageDelete", "restoringIdentity");
        this.emit("daemonMessage", {
          name: "invalidBrainwallet",
          type: "error",
          text: "Invalid Brainwallet!",
        });
      }
      if(message.error =="passwords do not match"){
        this.emit("daemonMessageDelete", "creatingIdentity");
        this.emit("daemonMessage", {
          name: "passwordMismatch",
          type: "error",
          text: "Passwords do not match!",
        });
      }
      return;
    }

    if(typeof this.pendingRequests[message.id] == "undefined" || this.pendingRequests[message.id].command == "undefined") {
      console.log("Error handling message " + message.id);
      console.log(this.pendingRequests);
    }

    switch(this.pendingRequests[message.id].command) {
      case "dw_list_accounts" : this.handleListAccounts(message);
        break;
      case "dw_create_account" : this.handleCreateAccount(message);
        break;
      case "dw_restore_account" : this.handleRestoreAccount(message);
        break;
      case "dw_set_account" : this.handleSetAccount(message);
        break;
      case "dw_delete_account" : this.handleDeleteAccount(message);
        break;
      case "dw_list_pockets" : this.handleListPockets(message);
        break;
      case "dw_balance" : this.handleBalance(message);
        break;
      case "dw_create_pocket" : this.handleCreatePocket(message);
        break;
      case "dw_receive" : this.handleReceive(message);
        break;
      case "dw_validate_address" : this.handleValidate(message);
        break;
      case "dw_stealth" : this.handleStealth(message);
        break;
      case "dw_history" : this.handleHistory(message);
        break;
      case "dw_send" : this.handleSendCoins(message);
        break;
      case "dw_seed" : this.handleBackup(message);
        break;
      default: console.log("Warning: DaemonInterface: Unknown command");
        break;
    }
  };

  handleListAccounts = (message) => {
    //Take list of accounts and turn them into a list of identities
    //identities include a name and a balance
    var accounts = message.result;
    this.identities.identitiesList = accounts[1].map((accountName, index) => {
      //TODO: We want to see if we already know about this account to carry over the balance.
      return {
        name: accountName,
        balance: -1,
      }
    })
    this.identities.currentIdentity = accounts[0];
    if (this.identities.currentIdentity != null) {
      this.dwGetPockets();
    }
    this.emit("identitiesListReady", this.identities);
  };

  handleCreateAccount = (message) => {
    this.emit("daemonMessageDelete", "creatingIdentity");

    this.identities.identitiesList.push({
      name: this.pendingRequests[message.id].params[0],
      balance: 0,
      pockets: [],
    });

    this.emit("identitiesListReady", this.identities);
  };

  handleRestoreAccount = (message) => {
    this.emit("daemonMessageDelete", "restoringIdentity");

    this.identities.identitiesList.push({
      name: this.pendingRequests[message.id].params[0],
      balance: 0,
      pockets: [],
    });

    this.emit("identitiesListReady", this.identities);
  };

  handleSetAccount = (message) => {
    this.emit("daemonMessageDelete", "loggingIn");
    this.pockets = [];
    this.identities.currentIdentity = this.pendingRequests[message.id].params[0];
    this.dwGetPockets();
    this.emit("currentAccountReady", this.identities.currentIdentity);
  };

  handleDeleteAccount = (message) => {
    let identitiesList = this.identities.identitiesList;

    for(let i in identitiesList) {
      console.log(identitiesList[i]);
      if(identitiesList[i].name == this.pendingRequests[message.id].params[0]) {
        delete identitiesList[i];
      }
    }
    this.emit("identitiesListReady", this.identities);
    console.log(this.identities);
  };

  handleListPockets = (message) => {
    var pocketList = message.result[0]

    if(pocketList.length <= 0) {
      console.log("Empty Pocket List from Daemon");
      return;
    }

    for(let i = 0; i < pocketList.length; i++) {
      this.dwGetPocketBalance(pocketList[i]);
      this.dwGetPocketAddresses(pocketList[i]);
      this.dwGetPocketHistory(pocketList[i]);
      this.dwGetPocketStealthAddress(pocketList[i])
      this.pockets[i] = {
        name: pocketList[i],
        balance: -1,
        addresses: [],
      }
    }
    this.emit("pocketsListReady", this.pockets)
  };

  handleBalance = (message) => {
    let pocketName = this.pendingRequests[message.id].params[0]
    for(let i = 0; i < this.pockets.length; i++) {
      if(this.pockets[i].name == pocketName) {
        this.pockets[i] = {
          name: pocketName,
          balance: message.result[0],
        };
      }
    }

    this.shouldEmitPocketsReady(message.id);
  };

  handleCreatePocket = (message) => {
    this.emit("daemonMessageDelete", "creatingPocket");

/*    this.pockets.push({
      name: this.pendingRequests[message.id].params[0],
      balance: 0,
      addresses: [],
      history: [],
    }); */

    this.dwGetPockets();
  };

  handleReceive = (message) => {
    let addresses = message.result[0];
    let currentPocketName = this.pendingRequests[message.id].params[0];
    for(let id in this.pockets) {
      let pocket = this.pockets[id];
      if(pocket.name == currentPocketName) {
        pocket.addresses = addresses;
      }
    }
    this.shouldEmitPocketsReady(message.id);
  }

  handleValidate = (message) => {
    if(message.result[0] != "invalid") {
      this.emit("validAddress", message.result[0]);
      return;
    }
    this.emit("invalidAddress");
  }

  handleStealth = (message) => {
    let stealthAddress = message.result[0];
    let currentPocketName = this.pendingRequests[message.id].params[0];
    for(let id in this.pockets) {
      let pocket = this.pockets[id];
      if(pocket.name == currentPocketName) {
        pocket.stealthAddress = stealthAddress;
      }
    }
    this.shouldEmitPocketsReady(message.id);
  }

  handleHistory = (message) => {
    let history = message.result;
    let currentPocketName = this.pendingRequests[message.id].params[0];
    for(let id in this.pockets) {
      let pocket = this.pockets[id];
      if(pocket.name == currentPocketName) {
        pocket.history = history;
        if(typeof pocket.history == 'undefined') {
          pocket.history = [];
        }
      }
    }

    this.shouldEmitPocketsReady(message.id);
  }

  handleSendCoins = (message) => {
    // what do we do to handle this?
  }

  handleBackup = (message) => {
    // best function in here
    alert("Backup: \n\n" + message.result.join(" "));
  }

  /*************/
  /*  DW calls */
  /*  Accounts */
  /*************/
  dwCreateAccount(accountName, accountPassword, useTestNet){
    this.sendMessage({
      "command":"dw_create_account",
      "id": this.generateTransactionId(),
      "params": [accountName, accountPassword, useTestNet]});
  }

  /* Restore wallet from Seed */
  dwRestoreAccount(accountName, brainwallet, accountPassword, useTestNet) {
    this.sendMessage({
      "command":"dw_restore_account",
      "id": this.generateTransactionId(),
      "params": [accountName, brainwallet, accountPassword, useTestNet],
    });
  }

  dwSetAccount(accountName, accountPassword){
    this.sendMessage({
      "command": "dw_set_account",
      "id": this.generateTransactionId(),
      "params" : [accountName, accountPassword]
    });
  }

  dwGetAccounts(){
    this.sendMessage({
      "command":"dw_list_accounts",
      "id": this.generateTransactionId(),
      "params": []
    });
  }

  dwDeleteAccount(accountName){
    this.sendMessage({
      "command": "dw_delete_account",
      "id": this.generateTransactionId(),
      "params": [accountName],
    });
  }

  /* Pockets */
  dwCreatePocket(pocket){
    this.sendMessage({
      "command": "dw_create_pocket",
      "id": this.generateTransactionId(),
      "params": [pocket],
    });
  }

  dwGetPockets(){
    this.sendMessage({
      "command": "dw_list_pockets",
      "id": this.generateTransactionId(),
      "params": []
    });
  }

  dwGetPocketBalance(pocket) {
    this.sendMessage({
      "command": "dw_balance",
      "id": this.generateTransactionId(),
      "params": [pocket]
    });
  }

  dwGetPocketAddresses(pocket){
    this.sendMessage({
      "command": "dw_receive",
      "id": this.generateTransactionId(),
      "params": [pocket],
    });
  }

  dwValidateAddress(address){
    this.sendMessage({
      "command": "dw_validate_address",
      "id": this.generateTransactionId(),
      "params": [address],
    });
  }

  dwGetPocketStealthAddress(pocket) {
    this.sendMessage({
      "command": "dw_stealth",
      "id": this.generateTransactionId(),
      "params": [pocket],
    });
  }

  dwGetPocketHistory(pocket) {
    this.sendMessage({
      "command": "dw_history",
      "id": this.generateTransactionId(),
      "params": [pocket],
    })
  }
  dwDeletePocket(pocket){}

  /* Send Bitcoin */
  dwSend(address, amount, pocket, fee){
    this.sendMessage({
      "command": "dw_send",
      "id": this.generateTransactionId(),
      "params": [[[address , parseInt(amount)]], pocket, parseInt(fee)],
    });
  }

  /* Get Backup Seed */
  dwSeed(){
    this.sendMessage({
      "command": "dw_seed",
      "id": this.generateTransactionId(),
      "params": [],
    });
  }
}
<commit_msg>added logging output for daemon requests<commit_after>'use strict';

import WebSocket from 'ws';
import EventEmitter from 'events';

export default class DaemonInterface extends EventEmitter {

  constructor() {
    super();
    console.log("DaemonInterface constructor start");
    this.ws = new WebSocket('ws://localhost:8888');
    this.wsOpen = false;
    this.useTestNet = true;
    this.identities = []; // looks like this: [currentIdentity, [list, of, identities]]
    this.pockets = []; //Only remember the pockets of the current identity.
    this.pendingRequests = []; //Requests sent to the daemon to be handled on message
  }

  /* ***************** */
  /* Utility functions */
  /* ***************** */

  init() {
    console.log("DaemonInterface init");

    this.ws.on("open", () => {
      this.wsOpen = true;
      this.dwGetAccounts();
    });

    this.ws.on('message', (data, flags) => {
      // flags.binary will be set if a binary data is received.
      // flags.masked will be set if the data was masked.
      // Handle the message (show success or failure message in the UI, etc)
      let message = JSON.parse(data);
      this.handleDaemonMessage(message);
      console.log(message.id);
      delete this.pendingRequests[message.id]; //Remove the request from the pending array
      console.log(this.pendingRequests);
    });

    console.log("DaemonInterface init complete")
  }

  sendMessage = (message) => { //Sends a message to the daemon
    console.log("Sending Message to Daemon:");
    console.log(message);

    if(this.wsOpen){
      this.pendingRequests[message.id] = (message);
      try {
        this.ws.send(JSON.stringify(message));
      } catch(e) {
        console.log(e.name);
        if(e.name == "Error") {
          this.emit("daemonMessage", {
            name: "daemonDisconnected",
            type: "error",
            text: "Disconnected (try ctrl+r)",
          });
          this.emit("deleteDaemonMessage", "loggingIn");
        }
      }
    } else {
      //TODO: Throw an error / restart the daemon
      console.log("WebSocket Not Open Yet!");
      this.emit("daemonMessage", {
        name: "daemonDisconnected",
        type: "error",
        text: "Disconnected (try ctrl+r)",
      });
    }
  };

  shouldEmitPocketsReady(messageId){
    for(let id in this.pendingRequests) {
      let request = this.pendingRequests[id];
      if(request.id != messageId && (
          request.command == "dw_receive" ||
          request.command == "dw_balance" ||
          request.command == "dw_history" ||
          request.command == "dw_stealth" )
        ) {
        return; //There are other pending pocket requests Don't emit an event.
      }
    }
    //This was the last pocket-related query request. Emit a ready event.
    this.emit("pocketsListReady", this.pockets);
  }

  generateTransactionId() { //Used for transaction IDs
    return parseInt(Math.random() * 4294967295);
  }

  /* ************** */
  /* Public Methods */
  /* ************** */

  startLogin = (accountName, password) => {
      this.emit("daemonMessageDelete", "wrongPassword");
      this.emit("daemonMessage", {
        name: "loggingIn",
        type: "info",
        text: "Logging In...",
      });
      this.dwSetAccount(accountName, password);
  };

  createIdentity = (identityName, password, useTestNet) => {
    this.emit("daemonMessageDelete", "passwordMismatch");
    this.emit('daemonMessage', {
        name: "creatingIdentity",
        type: "info",
        text: "Creating Identity...",
    });
    this.dwCreateAccount(identityName, password, useTestNet);
  }

  restoreIdentity = (identityName, password, brainwallet, useTestNet) => {
    this.emit('daemonMessage', {
        name: "restoringIdentity",
        type: "info",
        text: "Restoring Identity...",
    });
    this.dwRestoreAccount(identityName, password, brainwallet, useTestNet);
  }

  deleteIdentity = (identityName) => {
    this.dwDeleteAccount(identityName);
  }

  createPocket = (pocketName) => {
    this.emit('daemonMessage', {
        name: "creatingPocket",
        type: "info",
        text: "Creating Pocket...",
    });
    this.dwCreatePocket(pocketName);
  }

  validateAddress = (address) => {
    this.dwValidateAddress(address);
  }

  sendCoins = (address, amount, pocket, fee) => {
    this.dwSend(address, amount, pocket, fee);
  }

  backupIdentity = () => {
    this.dwSeed();
  }

  /* **************** */
  /* Message Handlers */
  /* **************** */

  handleDaemonMessage = (message) => {
    if(message.error != null) {
      console.log(message.error);

      if(message.error == "wrong_password"){
        this.emit("daemonMessageDelete", "loggingIn");
        this.emit("daemonMessage", {
          name: "wrongPassword",
          type: "error",
          text: "Wrong password!",
        });
      }
      if(message.error == "invalid_brainwallet"){
        this.emit("daemonMessageDelete", "restoringIdentity");
        this.emit("daemonMessage", {
          name: "invalidBrainwallet",
          type: "error",
          text: "Invalid Brainwallet!",
        });
      }
      if(message.error =="passwords do not match"){
        this.emit("daemonMessageDelete", "creatingIdentity");
        this.emit("daemonMessage", {
          name: "passwordMismatch",
          type: "error",
          text: "Passwords do not match!",
        });
      }
      return;
    }

    if(typeof this.pendingRequests[message.id] == "undefined" || this.pendingRequests[message.id].command == "undefined") {
      console.log("Error handling message " + message.id);
      console.log(this.pendingRequests);
    }

    switch(this.pendingRequests[message.id].command) {
      case "dw_list_accounts" : this.handleListAccounts(message);
        break;
      case "dw_create_account" : this.handleCreateAccount(message);
        break;
      case "dw_restore_account" : this.handleRestoreAccount(message);
        break;
      case "dw_set_account" : this.handleSetAccount(message);
        break;
      case "dw_delete_account" : this.handleDeleteAccount(message);
        break;
      case "dw_list_pockets" : this.handleListPockets(message);
        break;
      case "dw_balance" : this.handleBalance(message);
        break;
      case "dw_create_pocket" : this.handleCreatePocket(message);
        break;
      case "dw_receive" : this.handleReceive(message);
        break;
      case "dw_validate_address" : this.handleValidate(message);
        break;
      case "dw_stealth" : this.handleStealth(message);
        break;
      case "dw_history" : this.handleHistory(message);
        break;
      case "dw_send" : this.handleSendCoins(message);
        break;
      case "dw_seed" : this.handleBackup(message);
        break;
      default: console.log("Warning: DaemonInterface: Unknown command");
        break;
    }
  };

  handleListAccounts = (message) => {
    //Take list of accounts and turn them into a list of identities
    //identities include a name and a balance
    var accounts = message.result;
    this.identities.identitiesList = accounts[1].map((accountName, index) => {
      //TODO: We want to see if we already know about this account to carry over the balance.
      return {
        name: accountName,
        balance: -1,
      }
    })
    this.identities.currentIdentity = accounts[0];
    if (this.identities.currentIdentity != null) {
      this.dwGetPockets();
    }
    this.emit("identitiesListReady", this.identities);
  };

  handleCreateAccount = (message) => {
    this.emit("daemonMessageDelete", "creatingIdentity");

    this.identities.identitiesList.push({
      name: this.pendingRequests[message.id].params[0],
      balance: 0,
      pockets: [],
    });

    this.emit("identitiesListReady", this.identities);
  };

  handleRestoreAccount = (message) => {
    this.emit("daemonMessageDelete", "restoringIdentity");

    this.identities.identitiesList.push({
      name: this.pendingRequests[message.id].params[0],
      balance: 0,
      pockets: [],
    });

    this.emit("identitiesListReady", this.identities);
  };

  handleSetAccount = (message) => {
    this.emit("daemonMessageDelete", "loggingIn");
    this.pockets = [];
    this.identities.currentIdentity = this.pendingRequests[message.id].params[0];
    this.dwGetPockets();
    this.emit("currentAccountReady", this.identities.currentIdentity);
  };

  handleDeleteAccount = (message) => {
    let identitiesList = this.identities.identitiesList;

    for(let i in identitiesList) {
      console.log(identitiesList[i]);
      if(identitiesList[i].name == this.pendingRequests[message.id].params[0]) {
        delete identitiesList[i];
      }
    }
    this.emit("identitiesListReady", this.identities);
    console.log(this.identities);
  };

  handleListPockets = (message) => {
    var pocketList = message.result[0]

    if(pocketList.length <= 0) {
      console.log("Empty Pocket List from Daemon");
      return;
    }

    for(let i = 0; i < pocketList.length; i++) {
      this.dwGetPocketBalance(pocketList[i]);
      this.dwGetPocketAddresses(pocketList[i]);
      this.dwGetPocketHistory(pocketList[i]);
      this.dwGetPocketStealthAddress(pocketList[i])
      this.pockets[i] = {
        name: pocketList[i],
        balance: -1,
        addresses: [],
      }
    }
    this.emit("pocketsListReady", this.pockets)
  };

  handleBalance = (message) => {
    let pocketName = this.pendingRequests[message.id].params[0]
    for(let i = 0; i < this.pockets.length; i++) {
      if(this.pockets[i].name == pocketName) {
        this.pockets[i] = {
          name: pocketName,
          balance: message.result[0],
        };
      }
    }

    this.shouldEmitPocketsReady(message.id);
  };

  handleCreatePocket = (message) => {
    this.emit("daemonMessageDelete", "creatingPocket");

/*    this.pockets.push({
      name: this.pendingRequests[message.id].params[0],
      balance: 0,
      addresses: [],
      history: [],
    }); */

    this.dwGetPockets();
  };

  handleReceive = (message) => {
    let addresses = message.result[0];
    let currentPocketName = this.pendingRequests[message.id].params[0];
    for(let id in this.pockets) {
      let pocket = this.pockets[id];
      if(pocket.name == currentPocketName) {
        pocket.addresses = addresses;
      }
    }
    this.shouldEmitPocketsReady(message.id);
  }

  handleValidate = (message) => {
    if(message.result[0] != "invalid") {
      this.emit("validAddress", message.result[0]);
      return;
    }
    this.emit("invalidAddress");
  }

  handleStealth = (message) => {
    let stealthAddress = message.result[0];
    let currentPocketName = this.pendingRequests[message.id].params[0];
    for(let id in this.pockets) {
      let pocket = this.pockets[id];
      if(pocket.name == currentPocketName) {
        pocket.stealthAddress = stealthAddress;
      }
    }
    this.shouldEmitPocketsReady(message.id);
  }

  handleHistory = (message) => {
    let history = message.result;
    let currentPocketName = this.pendingRequests[message.id].params[0];
    for(let id in this.pockets) {
      let pocket = this.pockets[id];
      if(pocket.name == currentPocketName) {
        pocket.history = history;
        if(typeof pocket.history == 'undefined') {
          pocket.history = [];
        }
      }
    }

    this.shouldEmitPocketsReady(message.id);
  }

  handleSendCoins = (message) => {
    // what do we do to handle this?
  }

  handleBackup = (message) => {
    // best function in here
    alert("Backup: \n\n" + message.result.join(" "));
  }

  /*************/
  /*  DW calls */
  /*  Accounts */
  /*************/
  dwCreateAccount(accountName, accountPassword, useTestNet){
    this.sendMessage({
      "command":"dw_create_account",
      "id": this.generateTransactionId(),
      "params": [accountName, accountPassword, useTestNet]});
  }

  /* Restore wallet from Seed */
  dwRestoreAccount(accountName, brainwallet, accountPassword, useTestNet) {
    this.sendMessage({
      "command":"dw_restore_account",
      "id": this.generateTransactionId(),
      "params": [accountName, brainwallet, accountPassword, useTestNet],
    });
  }

  dwSetAccount(accountName, accountPassword){
    this.sendMessage({
      "command": "dw_set_account",
      "id": this.generateTransactionId(),
      "params" : [accountName, accountPassword]
    });
  }

  dwGetAccounts(){
    this.sendMessage({
      "command":"dw_list_accounts",
      "id": this.generateTransactionId(),
      "params": []
    });
  }

  dwDeleteAccount(accountName){
    this.sendMessage({
      "command": "dw_delete_account",
      "id": this.generateTransactionId(),
      "params": [accountName],
    });
  }

  /* Pockets */
  dwCreatePocket(pocket){
    this.sendMessage({
      "command": "dw_create_pocket",
      "id": this.generateTransactionId(),
      "params": [pocket],
    });
  }

  dwGetPockets(){
    this.sendMessage({
      "command": "dw_list_pockets",
      "id": this.generateTransactionId(),
      "params": []
    });
  }

  dwGetPocketBalance(pocket) {
    this.sendMessage({
      "command": "dw_balance",
      "id": this.generateTransactionId(),
      "params": [pocket]
    });
  }

  dwGetPocketAddresses(pocket){
    this.sendMessage({
      "command": "dw_receive",
      "id": this.generateTransactionId(),
      "params": [pocket],
    });
  }

  dwValidateAddress(address){
    this.sendMessage({
      "command": "dw_validate_address",
      "id": this.generateTransactionId(),
      "params": [address],
    });
  }

  dwGetPocketStealthAddress(pocket) {
    this.sendMessage({
      "command": "dw_stealth",
      "id": this.generateTransactionId(),
      "params": [pocket],
    });
  }

  dwGetPocketHistory(pocket) {
    this.sendMessage({
      "command": "dw_history",
      "id": this.generateTransactionId(),
      "params": [pocket],
    })
  }
  dwDeletePocket(pocket){}

  /* Send Bitcoin */
  dwSend(address, amount, pocket, fee){
    this.sendMessage({
      "command": "dw_send",
      "id": this.generateTransactionId(),
      "params": [[[address , parseInt(amount)]], pocket, parseInt(fee)],
    });
  }

  /* Get Backup Seed */
  dwSeed(){
    this.sendMessage({
      "command": "dw_seed",
      "id": this.generateTransactionId(),
      "params": [],
    });
  }
}
<|endoftext|>


<commit_before>var intro = new Audio('assets/sounds/music/4/intro.ogg');
var loop = new Audio('assets/sounds/music/4/loop.ogg');
intro.play();
intro.addEventListener("ended", function () {
    intro.pause();
    intro.currentTime = 0;
    loop.play();
});
loop.addEventListener("ended", function () {
    loop.currentTime = 0;
    loop.play();
});
<commit_msg>4 -> 9<commit_after>var intro = new Audio('assets/sounds/music/9/intro.ogg');
var loop = new Audio('assets/sounds/music/9/loop.ogg');
intro.play();
intro.addEventListener("ended", function () {
    intro.pause();
    intro.currentTime = 0;
    loop.play();
});
loop.addEventListener("ended", function () {
    loop.currentTime = 0;
    loop.play();
});
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var DEAD = 0;
var LIVE = 1;

var sampleInput = "4 8\n........\n....*...\n...**...\n........\n";

var Game = function(r,c) {
  var game = {
      rows: r,
      cols: c,
      neighbours: function(c,r) {
        var n = 0;
        for (var i=-1;i<=1;++i) {
          for (var j=-1;j<=1;++j) {
            if (i === 0 && j === 0) {
              continue;
            }

            if (this[c+j] && this[c+j][r+i] === LIVE) {
              ++n;
            }
          }
        }
        return n;
      },
      to_string: function() {
        var s = this.rows + ' ' + this.cols + '\n';
        for (var i=0;i<this.rows;++i) {
          for (var j=0;j<this.cols;++j) {
            s+= (this[j][i] === LIVE ? '*' : '.');
          }
          s+='\n';
        }
        return s;
      }
  };
  return game;
};

var createGrid = function(s) {
  var lines = s.split('\n');
  var rc = lines[0].split(' ');
  var rows = rc[0] | 0; // 4
  var cols = rc[1] | 0; // 8

  var game = new Game(rows,cols);

  for (var i=0;i<rows;++i) {
    for (var j=0;j<cols;++j) {
      var v = lines[1+i][j];
      if (game[j] === undefined) { game[j] = []; }
      game[j][i] = v === '*' ? LIVE : DEAD;
    }
  }

  return game;
};

var cellState = function(state,neighbours) {
  if (neighbours < 2 && state === LIVE) {
    return DEAD;
  }
  else if (neighbours > 3 && state === LIVE) {
    return DEAD;
  }
  else if ((neighbours === 2 || neighbours === 3) && state === LIVE) {
    return LIVE;
  }
  else if (neighbours === 3 && state === DEAD) {
    return LIVE;
  }
  else {
    return DEAD;
  }
};

describe('game of life', function() {
  describe('cell', function() {
    it('dies with underpopulation', function() {
      assert.equal(DEAD, cellState(LIVE,1));
    });

    it('dies with overcrowding', function() {
      assert.equal(DEAD, cellState(LIVE,4));
    });

    it('maintains live if 2 or three neighbours', function() {
      assert.equal(LIVE, cellState(LIVE,2));
      assert.equal(LIVE, cellState(LIVE,3));
    });

    it('becomes alive', function() {
      assert.equal(LIVE, cellState(DEAD,3));
    });

    it('is fully defined', function() {
      for (var i=0;i<=8;++i) {
        assert(undefined !== cellState(DEAD,i));
        assert(undefined !== cellState(LIVE,i));
      }
    });
  });

  describe('grid', function() {
    it('should read input', function() {
      var grid = createGrid(sampleInput);

      assert.equal(4, grid.rows);

      assert.equal(DEAD, grid[0][0]);
      assert.equal(LIVE, grid[4][1]);
      assert.equal(LIVE, grid[3][2]);
      assert.equal(LIVE, grid[4][2]);
    });

    it('should be able to get the number of live neighbours', function() {
      var grid = createGrid(sampleInput);

      assert.equal(0, grid.neighbours(0,0));
      assert.equal(2, grid.neighbours(3,2));

      grid = createGrid('2 2\n..\n..');
      assert.equal(0, grid.neighbours(0,0));
      assert.equal(0, grid.neighbours(1,0));
      assert.equal(0, grid.neighbours(0,1));
      assert.equal(0, grid.neighbours(1,1));

      grid = createGrid('2 2\n**\n**');
      assert.equal(3, grid.neighbours(0,0));
      assert.equal(3, grid.neighbours(1,0));
      assert.equal(3, grid.neighbours(0,1));
      assert.equal(3, grid.neighbours(1,1));
    });

    it('should have a sensible printed representation', function() {
      var grid = createGrid('1 1\n.');
      assert.equal('1 1\n.\n', grid.to_string());

      grid = createGrid(sampleInput);
      assert.equal(sampleInput, grid.to_string());
    });

    it('can iterate', function() {
      var grid = createGrid('2 2\n..\n.*\n');

      assert.equals('2 2\n..\n..\n', grid.iterate().to_string());
    });
  });
});

<commit_msg>create ieration method<commit_after>"use strict";

var assert = require('assert');

var DEAD = 0;
var LIVE = 1;

var sampleInput = "4 8\n........\n....*...\n...**...\n........\n";

var Game = function(r,c) {
  var game = {
      rows: r,
      cols: c,
      neighbours: function(c,r) {
        var n = 0;
        for (var i=-1;i<=1;++i) {
          for (var j=-1;j<=1;++j) {
            if (i === 0 && j === 0) {
              continue;
            }

            if (this[c+j] && this[c+j][r+i] === LIVE) {
              ++n;
            }
          }
        }
        return n;
      },
      to_string: function() {
        var s = this.rows + ' ' + this.cols + '\n';
        for (var i=0;i<this.rows;++i) {
          for (var j=0;j<this.cols;++j) {
            s+= (this[j][i] === LIVE ? '*' : '.');
          }
          s+='\n';
        }
        return s;
      },
      iterate: function() {
        var newGame = new Game(this.rows, this.cols);

        return newGame;
      }
  };
  return game;
};

var createGrid = function(s) {
  var lines = s.split('\n');
  var rc = lines[0].split(' ');
  var rows = rc[0] | 0; // 4
  var cols = rc[1] | 0; // 8

  var game = new Game(rows,cols);

  for (var i=0;i<rows;++i) {
    for (var j=0;j<cols;++j) {
      var v = lines[1+i][j];
      if (game[j] === undefined) { game[j] = []; }
      game[j][i] = v === '*' ? LIVE : DEAD;
    }
  }

  return game;
};

var cellState = function(state,neighbours) {
  if (neighbours < 2 && state === LIVE) {
    return DEAD;
  }
  else if (neighbours > 3 && state === LIVE) {
    return DEAD;
  }
  else if ((neighbours === 2 || neighbours === 3) && state === LIVE) {
    return LIVE;
  }
  else if (neighbours === 3 && state === DEAD) {
    return LIVE;
  }
  else {
    return DEAD;
  }
};

describe('game of life', function() {
  describe('cell', function() {
    it('dies with underpopulation', function() {
      assert.equal(DEAD, cellState(LIVE,1));
    });

    it('dies with overcrowding', function() {
      assert.equal(DEAD, cellState(LIVE,4));
    });

    it('maintains live if 2 or three neighbours', function() {
      assert.equal(LIVE, cellState(LIVE,2));
      assert.equal(LIVE, cellState(LIVE,3));
    });

    it('becomes alive', function() {
      assert.equal(LIVE, cellState(DEAD,3));
    });

    it('is fully defined', function() {
      for (var i=0;i<=8;++i) {
        assert(undefined !== cellState(DEAD,i));
        assert(undefined !== cellState(LIVE,i));
      }
    });
  });

  describe('grid', function() {
    it('should read input', function() {
      var grid = createGrid(sampleInput);

      assert.equal(4, grid.rows);

      assert.equal(DEAD, grid[0][0]);
      assert.equal(LIVE, grid[4][1]);
      assert.equal(LIVE, grid[3][2]);
      assert.equal(LIVE, grid[4][2]);
    });

    it('should be able to get the number of live neighbours', function() {
      var grid = createGrid(sampleInput);

      assert.equal(0, grid.neighbours(0,0));
      assert.equal(2, grid.neighbours(3,2));

      grid = createGrid('2 2\n..\n..');
      assert.equal(0, grid.neighbours(0,0));
      assert.equal(0, grid.neighbours(1,0));
      assert.equal(0, grid.neighbours(0,1));
      assert.equal(0, grid.neighbours(1,1));

      grid = createGrid('2 2\n**\n**');
      assert.equal(3, grid.neighbours(0,0));
      assert.equal(3, grid.neighbours(1,0));
      assert.equal(3, grid.neighbours(0,1));
      assert.equal(3, grid.neighbours(1,1));
    });

    it('should have a sensible printed representation', function() {
      var grid = createGrid('1 1\n.');
      assert.equal('1 1\n.\n', grid.to_string());

      grid = createGrid(sampleInput);
      assert.equal(sampleInput, grid.to_string());
    });

    it('can iterate', function() {
      var grid = createGrid('2 2\n..\n.*\n');

      assert.equals('2 2\n..\n..\n', grid.iterate().to_string());
    });
  });
});

<|endoftext|>


<commit_before>"use strict";
var assert = require('assert');

var LIVE = 1;
var DEAD  = 0;

var cellState = function(currentCellState, numberOfAliveNeighbours) {
  var twoOrThreeNeighbours = numberOfAliveNeighbours === 2 ||
                             numberOfAliveNeighbours === 3;

  if (numberOfAliveNeighbours < 2 || numberOfAliveNeighbours > 3) {
    return DEAD;
  }
  else if (currentCellState === LIVE && twoOrThreeNeighbours) {
    return LIVE;
  }
  else if (currentCellState === DEAD && numberOfAliveNeighbours === 3) {
    return LIVE;
  }
  else {
    return DEAD;
  }
};

var Grid = function(width, height) {
  return {
    width: width,
    height: height,
    at: function(x,y) {
      return DEAD;
    },
    set: function(x,y,v) {
    }
  };
};

describe('Game of life', function() {

  describe('grid', function() {
    it('should have a width and a height', function() {
      var grid = new Grid(10,20);
      assert.equal(10, grid.width);
      assert.equal(20, grid.height);
    });

    it('should be possible to read and write cells', function() {
      var grid = new Grid(10,20);

      assert.equal(DEAD, grid.at(0,0));

      grid.set(0,0, LIVE);
      assert.equal(LIVE, grid.at(0,0));
    });
  });

  describe('cell', function() {
    it('fewer than two neighbours dies', function() {
      assert.equal(DEAD, cellState(LIVE,1));
    });

    it('more than 3 alive cells dies', function() {
      assert.equal(DEAD, cellState(LIVE,4));
    });

    it('live cells with 2 or 3 neighbours live on', function() {
      assert.equal(LIVE, cellState(LIVE,2));
      assert.equal(LIVE, cellState(LIVE,3));
    });

    it('dead cells with exactly 3 neighbours live', function() {
      assert.equal(LIVE, cellState(DEAD,3));
    });

    it('should be defined for all input types', function() {
      for (var i=0;i<=8;++i) {
        assert(undefined !== cellState(DEAD,i), 'dead with ' + i + 'neighbours');
        assert(undefined !== cellState(LIVE,i), 'live with ' + i + 'neighbours');
      }
    });
  });
});
<commit_msg>can now set cells<commit_after>"use strict";
var assert = require('assert');

var LIVE = 1;
var DEAD  = 0;

var cellState = function(currentCellState, numberOfAliveNeighbours) {
  var twoOrThreeNeighbours = numberOfAliveNeighbours === 2 ||
                             numberOfAliveNeighbours === 3;

  if (numberOfAliveNeighbours < 2 || numberOfAliveNeighbours > 3) {
    return DEAD;
  }
  else if (currentCellState === LIVE && twoOrThreeNeighbours) {
    return LIVE;
  }
  else if (currentCellState === DEAD && numberOfAliveNeighbours === 3) {
    return LIVE;
  }
  else {
    return DEAD;
  }
};

var Grid = function(width, height) {

  var grid = [];
  for (var i=0;i<height;++i) {
    var row = [];
    for (var j=0;j<width;++j) {
      row.push(DEAD);
    }
    grid.push(row);
  }

  return {
    width: width,
    height: height,
    at: function(x,y) {
      return grid[y][x];
    },
    set: function(x,y,v) {
      grid[y][x] = v;
    }
  };
};

describe('Game of life', function() {

  describe('grid', function() {
    it('should have a width and a height', function() {
      var grid = new Grid(10,20);
      assert.equal(10, grid.width);
      assert.equal(20, grid.height);
    });

    it('should be possible to read and write cells', function() {
      var grid = new Grid(10,20);

      assert.equal(DEAD, grid.at(0,0));

      grid.set(0,0, LIVE);
      assert.equal(LIVE, grid.at(0,0));
    });
  });

  describe('cell', function() {
    it('fewer than two neighbours dies', function() {
      assert.equal(DEAD, cellState(LIVE,1));
    });

    it('more than 3 alive cells dies', function() {
      assert.equal(DEAD, cellState(LIVE,4));
    });

    it('live cells with 2 or 3 neighbours live on', function() {
      assert.equal(LIVE, cellState(LIVE,2));
      assert.equal(LIVE, cellState(LIVE,3));
    });

    it('dead cells with exactly 3 neighbours live', function() {
      assert.equal(LIVE, cellState(DEAD,3));
    });

    it('should be defined for all input types', function() {
      for (var i=0;i<=8;++i) {
        assert(undefined !== cellState(DEAD,i), 'dead with ' + i + 'neighbours');
        assert(undefined !== cellState(LIVE,i), 'live with ' + i + 'neighbours');
      }
    });
  });
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** The Prototype for all Generated Prototypes. **/
// TODO: Rename FOAMObject or FObject
var AbstractPrototype = {
  __proto__: PropertyChangeSupport,

  TYPE: 'AbstractPrototype',

  create: function(args) {
/*
console.log("args: ", args);
    if (arguments.length > 1) {
      args = {};
      for (var i = 0 ; i < arguments.length; i++) {
        arguments[i].forEach(function (k,v) {
console.log(i, k, v);
          args[k] = v;
        });
      }
    }
*/

    if ( this.__objProto__ != this ) debugger;

    var obj = {
      __proto__: this.__objProto__ || this,
      instance_: {}
    };

    if ( typeof args === 'object' ) obj.copyFrom(args);
    obj.init(args);

    return obj;
  },

  init: function(_) {
    if ( ! this.model_ ) return;

    for ( var i = 0 ; i < this.model_.properties.length ; i++ ) {
      var prop = this.model_.properties[i];

      // I'm not sure why I added this next line, but it isn't used
      // so I've disabled it
      //     if ( prop.init ) prop.init.call(this);

      // If a value was explicitly provided in the create args
      // then don't call the valueFactory if it exists.
      if ( prop.valueFactory && ! this.instance_[prop.name] )
        this[prop.name] = prop.valueFactory.call(this);
    }

    // Add shortcut create() method to Models which allows them to be
    // used as constructors.  Don't do this for the Model though
    // because we need the regular behavior there.
    if ( this.model_ == Model && this.name != 'Model' )
      this.create = ModelProto.create;
  },

  defineFOAMGetter: function(name, getter) {
    this.__defineGetter__(name, function() {
      var value = getter.call(this);
      Events.onGet(this, name, value);
      return value;
    });
  },

  defineFOAMSetter: function(name, setter) {
    this.__defineSetter__(name, function(newValue) {
      if ( ! Events.onSet(this, name, newValue) ) return;
      setter.call(this, newValue);
    });
  },

  toString: function() {
// console.log(this.model_.name + "Prototype");
    // return this.model_.name + "Prototype";
    return this.toJSON();
  },

  hasOwnProperty: function(name) {
    return this.instance_.hasOwnProperty(name);
  },

  writeActions: function(other, out) {
      for (var i = 0, property; property = this.model_.properties[i]; i++) {
          if (property.actionFactory) {
              var actions = property.actionFactory(this, property.f(this), property.f(other));
              for (var j = 0; j < actions.length; j++)
                  out(actions[j]);
          }
      }
  },

  clearProperty: function(name) {
    delete this.instance_[name];
  },

  // todo:
  become: function(other) {

  },

  // todo:
  becomeClone: function(other) {

  },

  defineProperty: function(prop) {
    // this method might be a good candidate for a decision table

    var name = prop.name;

    if ( prop.getter ) {
      this.__defineGetter__(name, prop.getter);
    } else {
      this.defineFOAMGetter(name, prop.defaultValueFn ?
        function() {
          return this.hasOwnProperty(name) ? this.instance_[name] : prop.defaultValueFn.call(this);
        } :
        function() {
          return this.hasOwnProperty(name) ? this.instance_[name] : prop.defaultValue;
        });
    }

    if ( prop.setter ) {
      this.defineFOAMSetter(name, prop.setter);
    } else if ( prop.preSet || prop.postSet ) {
      this.defineFOAMSetter(name, function(newValue) {
        var oldValue = this[name];

        if ( prop.preSet )
          newValue = prop.preSet.call(this, newValue, oldValue, prop);

        // todo: fix
        if ( prop.type == 'int' || prop.type == 'float' )
          newValue = Number(newValue);

        this.instance_[name] = newValue;

        if ( prop.postSet )
          prop.postSet.call(this, newValue, oldValue);

        this.propertyChange(name, oldValue, newValue);
      });
    } else {
      this.defineFOAMSetter(name, function(newValue) {
        var oldValue = this[name];

        // todo: fix
        if ( prop.type == 'int' || prop.type == 'float' )
          newValue = Number(newValue);

        this.instance_[name] = newValue;

        // TODO: remove
        try {
          this.propertyChange(name, oldValue, newValue);
        } catch (x) {
        }
      });
    }
  },

  getProperty: function(name) {
    // TODO: cache in map
    for ( var i = 0 ; i < this.properties.length ; i++ ) {
      var prop = this.properties[i];

      if ( prop.name == name ) return prop;
    }

    return undefined;
  },

  hashCode: function() {
    var hash = 17;

    for ( var i = 0; i < this.model_.properties.length ; i++ ) {
      var prop = this[this.model_.properties[i].name];
      var code = ! prop ? 0 :
        prop.hashCode   ? prop.hashCode()
                        : prop.toString().hashCode();

      hash = ((hash << 5) - hash) + code;
      hash &= hash;
    }

    return hash;
  },

  // TODO: this should be monkey-patched from a 'ProtoBuf' library
  toProtobuf: function() {
    var out = ProtoWriter.create();
    this.outProtobuf(out);
    return out.value;
  },

  // TODO: this should be monkey-patched from a 'ProtoBuf' library
  outProtobuf: function(out) {
    for ( var i = 0; i < this.model_.properties.length; i++ ) {
      var prop = this.model_.properties[i];
      if ( Number.isFinite(prop.prototag) )
        prop.outProtobuf(this, out);
    }
  },

  /** Create a shallow copy of this object. **/
  clone: function() {
    return ( this.model_ && this.model_.create ) ? this.model_.create(this) : this;
  },

  /** Create a deep copy of this object. **/
  deepClone: function() {
    var cln = this.clone();

    // now clone inner collections
    for ( var key in cln.instance_ ) {
      var val = cln.instance_[key];

      if ( val instanceof Array ) {
        val = val.slice(0);
        cln.instance_[key] = val;

        for ( var i = 0 ; i < val.length ; i++ ) {
          var obj = val[i];

          if ( obj.deepClone )
            val[i] = obj.deepClone();
        }
      }
    }

    return cln;
  },

  /** @return this **/
  copyFrom: function(src) {
    // Faster and doesn't copy default values from modelled objects.
    // Doesn't work when src is modelled and has default values
    // if ( src && src.instance_ ) src = src.instance_;

    // TODO: remove the 'this.model_' check when all classes modelled
    if ( src && this.model_ ) {
      for ( var i = 0 ; i < this.model_.properties.length ; i++ ) {
        var prop = this.model_.properties[i];

        // If the src is modelled, and it has an instance_
        //   BUT the instance doesn't have a value for the property,
        //   then don't copy this value over since it's a default value.
        if ( src.model_ && src.instance_ &&
            !src.instance_.hasOwnProperty(prop.name) ) continue;

        if ( prop.name in src ) this[prop.name] = src[prop.name];
//         if ( src.instance_ && src.instance_.hasOwnProperty(name) ) this[prop.name] = src[prop.name];
      }
    }

    return this;
  },

  output: function(out) {
    return JSONUtil.output(out, this);
  },

  toJSON: function() {
    return JSONUtil.stringify(this);
  },

  toXML: function() {
    return XMLUtil.stringify(this);
  },

  write: function(document) {
    var view = ActionBorder.create(
      this.model_,
      DetailView.create({model: this.model_}));

    document.writeln(view.toHTML());
    view.value.set(this);
    view.initHTML();
  }
};

/*
AbstractPrototype.__defineGetter__('__super__', function() {
  return this.__proto__.__proto__;
});
*/
<commit_msg>Missed one file from previous CL.<commit_after>/**
 * @license
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** The Prototype for all Generated Prototypes. **/
// TODO: Rename FOAMObject or FObject
var AbstractPrototype = {
  __proto__: PropertyChangeSupport,

  TYPE: 'AbstractPrototype',

  create: function(args) {
/*
console.log("args: ", args);
    if (arguments.length > 1) {
      args = {};
      for (var i = 0 ; i < arguments.length; i++) {
        arguments[i].forEach(function (k,v) {
console.log(i, k, v);
          args[k] = v;
        });
      }
    }
*/

    var obj = {
      __proto__: this,
      instance_: {}
    };

    if ( typeof args === 'object' ) obj.copyFrom(args);
    obj.init(args);

    return obj;
  },

  init: function(_) {
    if ( ! this.model_ ) return;

    for ( var i = 0 ; i < this.model_.properties.length ; i++ ) {
      var prop = this.model_.properties[i];

      // I'm not sure why I added this next line, but it isn't used
      // so I've disabled it
      //     if ( prop.init ) prop.init.call(this);

      // If a value was explicitly provided in the create args
      // then don't call the valueFactory if it exists.
      if ( prop.valueFactory && ! this.instance_[prop.name] )
        this[prop.name] = prop.valueFactory.call(this);
    }

    // Add shortcut create() method to Models which allows them to be
    // used as constructors.  Don't do this for the Model though
    // because we need the regular behavior there.
    if ( this.model_ == Model && this.name != 'Model' )
      this.create = ModelProto.create;
  },

  defineFOAMGetter: function(name, getter) {
    this.__defineGetter__(name, function() {
      var value = getter.call(this);
      Events.onGet(this, name, value);
      return value;
    });
  },

  defineFOAMSetter: function(name, setter) {
    this.__defineSetter__(name, function(newValue) {
      if ( ! Events.onSet(this, name, newValue) ) return;
      setter.call(this, newValue);
    });
  },

  toString: function() {
// console.log(this.model_.name + "Prototype");
    // return this.model_.name + "Prototype";
    return this.toJSON();
  },

  hasOwnProperty: function(name) {
    return this.instance_.hasOwnProperty(name);
  },

  writeActions: function(other, out) {
      for (var i = 0, property; property = this.model_.properties[i]; i++) {
          if (property.actionFactory) {
              var actions = property.actionFactory(this, property.f(this), property.f(other));
              for (var j = 0; j < actions.length; j++)
                  out(actions[j]);
          }
      }
  },

  clearProperty: function(name) {
    delete this.instance_[name];
  },

  // todo:
  become: function(other) {

  },

  // todo:
  becomeClone: function(other) {

  },

  defineProperty: function(prop) {
    // this method might be a good candidate for a decision table

    var name = prop.name;

    if ( prop.getter ) {
      this.__defineGetter__(name, prop.getter);
    } else {
      this.defineFOAMGetter(name, prop.defaultValueFn ?
        function() {
          return this.hasOwnProperty(name) ? this.instance_[name] : prop.defaultValueFn.call(this);
        } :
        function() {
          return this.hasOwnProperty(name) ? this.instance_[name] : prop.defaultValue;
        });
    }

    if ( prop.setter ) {
      this.defineFOAMSetter(name, prop.setter);
    } else if ( prop.preSet || prop.postSet ) {
      this.defineFOAMSetter(name, function(newValue) {
        var oldValue = this[name];

        if ( prop.preSet )
          newValue = prop.preSet.call(this, newValue, oldValue, prop);

        // todo: fix
        if ( prop.type == 'int' || prop.type == 'float' )
          newValue = Number(newValue);

        this.instance_[name] = newValue;

        if ( prop.postSet )
          prop.postSet.call(this, newValue, oldValue);

        this.propertyChange(name, oldValue, newValue);
      });
    } else {
      this.defineFOAMSetter(name, function(newValue) {
        var oldValue = this[name];

        // todo: fix
        if ( prop.type == 'int' || prop.type == 'float' )
          newValue = Number(newValue);

        this.instance_[name] = newValue;

        // TODO: remove
        try {
          this.propertyChange(name, oldValue, newValue);
        } catch (x) {
        }
      });
    }
  },

  getProperty: function(name) {
    // TODO: cache in map
    for ( var i = 0 ; i < this.properties.length ; i++ ) {
      var prop = this.properties[i];

      if ( prop.name == name ) return prop;
    }

    return undefined;
  },

  hashCode: function() {
    var hash = 17;

    for ( var i = 0; i < this.model_.properties.length ; i++ ) {
      var prop = this[this.model_.properties[i].name];
      var code = ! prop ? 0 :
        prop.hashCode   ? prop.hashCode()
                        : prop.toString().hashCode();

      hash = ((hash << 5) - hash) + code;
      hash &= hash;
    }

    return hash;
  },

  // TODO: this should be monkey-patched from a 'ProtoBuf' library
  toProtobuf: function() {
    var out = ProtoWriter.create();
    this.outProtobuf(out);
    return out.value;
  },

  // TODO: this should be monkey-patched from a 'ProtoBuf' library
  outProtobuf: function(out) {
    for ( var i = 0; i < this.model_.properties.length; i++ ) {
      var prop = this.model_.properties[i];
      if ( Number.isFinite(prop.prototag) )
        prop.outProtobuf(this, out);
    }
  },

  /** Create a shallow copy of this object. **/
  clone: function() {
    return ( this.model_ && this.model_.create ) ? this.model_.create(this) : this;
  },

  /** Create a deep copy of this object. **/
  deepClone: function() {
    var cln = this.clone();

    // now clone inner collections
    for ( var key in cln.instance_ ) {
      var val = cln.instance_[key];

      if ( val instanceof Array ) {
        val = val.slice(0);
        cln.instance_[key] = val;

        for ( var i = 0 ; i < val.length ; i++ ) {
          var obj = val[i];

          if ( obj.deepClone )
            val[i] = obj.deepClone();
        }
      }
    }

    return cln;
  },

  /** @return this **/
  copyFrom: function(src) {
    // Faster and doesn't copy default values from modelled objects.
    // Doesn't work when src is modelled and has default values
    // if ( src && src.instance_ ) src = src.instance_;

    // TODO: remove the 'this.model_' check when all classes modelled
    if ( src && this.model_ ) {
      for ( var i = 0 ; i < this.model_.properties.length ; i++ ) {
        var prop = this.model_.properties[i];

        // If the src is modelled, and it has an instance_
        //   BUT the instance doesn't have a value for the property,
        //   then don't copy this value over since it's a default value.
        if ( src.model_ && src.instance_ &&
            !src.instance_.hasOwnProperty(prop.name) ) continue;

        if ( prop.name in src ) this[prop.name] = src[prop.name];
//         if ( src.instance_ && src.instance_.hasOwnProperty(name) ) this[prop.name] = src[prop.name];
      }
    }

    return this;
  },

  output: function(out) {
    return JSONUtil.output(out, this);
  },

  toJSON: function() {
    return JSONUtil.stringify(this);
  },

  toXML: function() {
    return XMLUtil.stringify(this);
  },

  write: function(document) {
    var view = ActionBorder.create(
      this.model_,
      DetailView.create({model: this.model_}));

    document.writeln(view.toHTML());
    view.value.set(this);
    view.initHTML();
  }
};

/*
AbstractPrototype.__defineGetter__('__super__', function() {
  return this.__proto__.__proto__;
});
*/
<|endoftext|>


<commit_before>/*
 * This file is part of the Spludo Framework.
 * Copyright (c) 2009-2010 DracoBlue, http://dracoblue.net/
 *
 * Licensed under the terms of MIT License. For the full copyright and license
 * information, please see the LICENSE file in the root folder.
 */

/**
 * @class The application running and listening on a specific port.
 *
 * @extends BaseApplication
 *
 * @param {Object} options Options to specify the behaviour
 * @param {Number} options.port The port, which should be used when launching the application server.
 *
 * @since 0.1
 * @author DracoBlue
 */
ServerApplication = function(options) {
    this.setOptions(options);

    this.options.session_key = this.options.session_key || "s";

    /**
     * The Http-Server listening for new connections.
     *
     * @private
     */
    this.server = null;
};

process.mixin(true, ServerApplication.prototype, BaseApplication.prototype);

var http = require("http");
var sys = require("sys");

/**
 * Runs the application.
 */
ServerApplication.prototype.run = function() {

    var session_key = this.options.session_key;

    var finishRequest = function(req, res, body) {
        var context = {
            status: 200,
            headers: {
                'Content-Type': 'text/plain',
                'Server': 'Spludo 0.1'
            }
        };

        context.params = {};

        if (body !== null) {
            /*
             * Ok, we need to parse that!
             */
             var body_entries = body.split("&");
             var body_entries_length = body_entries.length;
             var i = 0;

             for (i=0; i<body_entries_length; i++) {
                var row = body_entries[i].split("=");
                var key = decodeURIComponent(row[0]);
                var value = decodeURIComponent(row[1] || "");
                context.params[key] = value;
             }
        }

        ContextToolkit.applyRequestHeaders(context, req.headers);

        var session_id = (context.cookies && context.cookies[session_key]) || null;

        if (session_id) {
            try {
                context.session = session_manager.getSession(session_id);
            } catch (e) {
                /*
                 * Seems like that cookie is invalid by now. Let's remove the cookie.
                 */
                ContextToolkit.removeCookie(context, session_key);
                session_id = null;
            }
        }

        context.session_id = session_id;

        var response = null;

        try {
            response = BaseApplication.executePath(req.url.substr(1), context);
        } catch (e) {
            context.status = 404;
            response = "Page not found!" + sys.inspect(e);
        }

        if (session_id !== context.session_id) {
            session_id = context.session_id;

            if (session_id === null) {
                ContextToolkit.removeCookie(context, session_key);
            } else {
                ContextToolkit.setCookie(context, session_key, session_id);
            }
        }

        ContextToolkit.applyCookiesToHeaders(context);

        res.sendHeader(context.status, context.headers);
        res.sendBody(response, "utf8");

        res.finish();
    };

    this.server = http.createServer(function(req, res) {
        if (static_files_manager.canHandleRequest(req)) {
            static_files_manager.handleRequest(req, res);
            return ;
        }

        if (req.method === "GET") {
            finishRequest(req, res, null);
            return ;
        }

        var body = [];

        req.addListener('body', function(content) {
            if (content === null) {
                return ;
            }
            body.push(content);
        });

        req.addListener('complete', function(content) {
            finishRequest(req, res, body.join(""));
        });

    });

    this.server.listen(this.options["port"]);
};
<commit_msg>Added fileupload possibility by using multipart library, if body is multipart. Added encoding option to context, which defaults to uf8.<commit_after>/*
 * This file is part of the Spludo Framework.
 * Copyright (c) 2009-2010 DracoBlue, http://dracoblue.net/
 *
 * Licensed under the terms of MIT License. For the full copyright and license
 * information, please see the LICENSE file in the root folder.
 */

/**
 * @class The application running and listening on a specific port.
 *
 * @extends BaseApplication
 *
 * @param {Object} options Options to specify the behaviour
 * @param {Number} options.port The port, which should be used when launching the application server.
 *
 * @since 0.1
 * @author DracoBlue
 */
ServerApplication = function(options) {
    this.setOptions(options);

    this.options.session_key = this.options.session_key || "s";

    /**
     * The Http-Server listening for new connections.
     *
     * @private
     */
    this.server = null;
};

process.mixin(true, ServerApplication.prototype, BaseApplication.prototype);

var http = require("http");
var sys = require("sys");
var multipart = require("multipart");

/**
 * Runs the application.
 */
ServerApplication.prototype.run = function() {

    var session_key = this.options.session_key;

    var finishRequest = function(req, res, body, params) {
        var context = {
            status: 200,
            headers: {
                'Content-Type': 'text/plain',
                'Server': 'Spludo 0.1'
            }
        };

        context.params = params || {};

        if (body !== null) {
            /*
             * Ok, we need to parse that!
             */
             var body_entries = body.split("&");
             var body_entries_length = body_entries.length;
             var i = 0;

             for (i=0; i<body_entries_length; i++) {
                var row = body_entries[i].split("=");
                var key = decodeURIComponent(row[0]);
                var value = decodeURIComponent(row[1] || "");
                context.params[key] = value;
             }
        }

        ContextToolkit.applyRequestHeaders(context, req.headers);

        var session_id = (context.cookies && context.cookies[session_key]) || null;

        if (session_id) {
            try {
                context.session = session_manager.getSession(session_id);
            } catch (e) {
                /*
                 * Seems like that cookie is invalid by now. Let's remove the cookie.
                 */
                ContextToolkit.removeCookie(context, session_key);
                session_id = null;
            }
        }

        context.session_id = session_id;

        var response = null;

        try {
            response = BaseApplication.executePath(req.url.substr(1), context);
        } catch (e) {
            context.status = 404;
            response = "Page not found!\n\n" + (e.stack || e.message) + "\n\n";
            response = response + "Arguments: " + sys.inspect(e.arguments);
        }

        if (session_id !== context.session_id) {
            session_id = context.session_id;

            if (session_id === null) {
                ContextToolkit.removeCookie(context, session_key);
            } else {
                ContextToolkit.setCookie(context, session_key, session_id);
            }
        }

        ContextToolkit.applyCookiesToHeaders(context);

        res.sendHeader(context.status, context.headers);
        res.sendBody(response, context.encoding || "utf8");

        res.finish();
    };

    this.server = http.createServer(function(req, res) {
        if (static_files_manager.canHandleRequest(req)) {
            static_files_manager.handleRequest(req, res);
            return ;
        }

        if (req.method === "GET") {
            finishRequest(req, res, null);
            return ;
        }

        req.setBodyEncoding("binary");

        var stream = multipart.parse(req);

        if (stream.isMultiPart) {

            var parts = {};
            var current_part_name = null;

            stream.addListener("partBegin", function (part) {
                current_part_name = part.name;
                parts[current_part_name] = {
                    "name": current_part_name,
                    "filename": part.filename,
                    "body": []
                };
            });

            stream.addListener("body", function(chunk) {
                parts[current_part_name].body.push(chunk);
            });

            stream.addListener("partEnd", function () {
                if (current_part_name !== null) {
                    parts[current_part_name].body = parts[current_part_name].body.join("");
                }
                current_part_name = null;
            });

            stream.addListener('complete', function(content) {
                finishRequest(req, res, null, parts);
            });
        } else {
            var body = [];

            stream.addListener("body", function(chunk) {
                if (chunk === null) {
                    return ;
                }
                body.push(chunk);
            });

            stream.addListener('complete', function(content) {
                finishRequest(req, res, body.join(""));
            });
        }

    });

    this.server.listen(this.options["port"]);
};
<|endoftext|>


<commit_before>$(document).ready(function() {

  // import view port library function
  jQuery.extend(verge);

  // smooth scrolling of viewport to target
  $('a[href^="#"]').click(function(event) {
    event.preventDefault();
    $('html,body').animate({
      scrollTop: $(this.hash).offset().top - 50
    }, 900);
  });

  $('#down').click(function() {
    $('html,body').animate({
      scrollTop: $('#about').offset().top - 50
    }, 900);
  });

  var currentTime = new Date();
  var year = currentTime.getFullYear();

  // data for the portfolio cards front and back
  var projectData = [{
      title: 'Paramour',
      text: '
A fantastic JavaScript interpreter! JavaScript/Python/Swift Syntax with ES7 recommendations and regular updates. This version simply makes the code more developer friendly (proper variable names, commentation, etc.)
 Code: Javascript
',

      image: ['http://ephellon.github.io/Designer/img/Paramour.png'],
      site: [
        ['CodePen', 'fa-codepen', 'https://codepen.io/Ephellon/full/XKPVgw'],
        ['Live Site', 'fa-link', 'https://ephellon.github.io/Paramour/']
      ]
    }, {
      title: 'Mi/o',
      text: '
An improved LZW compression algorithm that allows the use of Base64.
 Code: JavaScript
',

      image: ['https://ephellon.github.io/Designer/img/Mio.png'],
      site: [
        ['CodePen', 'fa-codepen', 'https://codepen.io/Ephellon/full/NvEXbV'],
        ['Live Site', 'fa-link', 'https://ephellon.github.io/Mio/']
      ]
    }, {
      title: 'Rihanna: ANTI',
      text: '
An edited version of Rihanna\'s ANTI album art, which I thought should be her deluxe version\'s cover art.
',

      image: ['https://ephellon.github.io/Designer/img/ANTI.png'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/ANTI.png']
      ]
    }, {
      title: 'Rihanna: ANTI (Alternate)',
      text: '
An edited version of Rihanna\'s ANTI album art, which I thought should be her deluxe version\'s cover art.
',

      image: ['https://ephellon.github.io/Designer/img/ANTI (Alternate).png'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/ANTI (Alternate).png']
      ]
    }, {
      title: 'J. Cole: Born Sinner',
      text: '
An edited version of J. Cole\'s Born Sinner (Deluxe) album art. I thought "Forbidden Fruit" should\'ve had a different cover (as a single).
',

      image: ['https://ephellon.github.io/Designer/img/Forbidden Fruit.jpg'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/Forbidden Fruit.jpg']
      ]
    }, {
      title: 'Michael Jackson: Dirty Diana',
      text: '
A single version of Michael Jackson\'s Dirty Diana. It feels more like the song than the original, and 2017 album arts.
',

      image: ['https://ephellon.github.io/Designer/img/Dirty Diana.png'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/Dirty Diana.png']
      ]
    }
    /*, {
      title: 'Title',
      text: '
Description.
',

      image: ['#link-to-preview-image'],
      site: [
        ['CodePen', 'fa-codepen', '#link-to-pen'],
        ['Live Site', 'fa-link', '#link-to-site']
      ]
    }
    */
    ];

  // add listener to all the cards for click flipping
  function addListener() {
    var cards = document.querySelectorAll(".card.effect_click");

    for (var i = 0; i < cards.length; i++) {
      clickListener(cards[i]);
    }

    function clickListener(card) {
      card.addEventListener("click", function() {
        this.classList.toggle("flipped");
      });
    }
  }

  // create, populate and show portfolio project cards
  function showProjectCards() {
    var html = '';

    projectData.forEach(function(project) {
      html += '
' +
              '

' +
              '
' +
              '
' +
              project.title +
              '

' +

              '

' +
              '
' + project.title + '
' +
              '
' +
              '
' + project.text + '
' +
              '
';

      if (typeof project.site[1] != 'undefined')
        html += '';

      html += '

' +
              '
' +
              '
';
    });

    $('#theProjects').append(html);
    addListener();
  }

  showProjectCards();
  $(".copyright").append("© " + year + " Ephellon Dantzler. All rights reserved");

  // turn on bootstrap tooltips
  $('[data-toggle="tooltip"]').tooltip();

});
<commit_msg>Update index.js<commit_after>$(document).ready(function() {

  // import view port library function
  jQuery.extend(verge);

  // smooth scrolling of viewport to target
  $('a[href^="#"]').click(function(event) {
    event.preventDefault();
    $('html,body').animate({
      scrollTop: $(this.hash).offset().top - 50
    }, 900);
  });

  $('#down').click(function() {
    $('html,body').animate({
      scrollTop: $('#about').offset().top - 50
    }, 900);
  });

  var currentTime = new Date();
  var year = currentTime.getFullYear();

  // data for the portfolio cards front and back
  var projectData = [{
      title: 'Paramour',
      text: '
A fantastic JavaScript interpreter! JavaScript/Python/Swift Syntax with ES7 recommendations and regular updates. This version simply makes the code more developer friendly (proper variable names, commentation, etc.)
 Code: Javascript
',

      image: ['http://ephellon.github.io/Designer/img/Paramour.png'],
      site: [
        ['CodePen', 'fa-codepen', 'https://codepen.io/Ephellon/full/XKPVgw'],
        ['Live Site', 'fa-link', 'https://ephellon.github.io/Paramour/']
      ]
    }, {
      title: 'Mi/o',
      text: '
An improved LZW compression algorithm that allows the use of Base64.
 Code: JavaScript
',

      image: ['https://ephellon.github.io/Designer/img/Mio.png'],
      site: [
        ['CodePen', 'fa-codepen', 'https://codepen.io/Ephellon/full/NvEXbV'],
        ['Live Site', 'fa-link', 'https://ephellon.github.io/Mio/']
      ]
    }, {
      title: 'Rihanna: ANTI',
      text: '
An edited version of Rihanna\'s ANTI album art, which I thought should be her deluxe version\'s cover art.
',

      image: ['https://ephellon.github.io/Designer/img/ANTI.png'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/ANTI.png']
      ]
    }, {
      title: 'Rihanna: ANTI (Alternate)',
      text: '
An edited version of Rihanna\'s ANTI album art, which I thought should be her deluxe version\'s cover art.
',

      image: ['https://ephellon.github.io/Designer/img/ANTI (Alternate).png'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/ANTI (Alternate).png']
      ]
    }, {
      title: 'J. Cole: Born Sinner',
      text: '
An edited version of J. Cole\'s Born Sinner (Deluxe) album art. I thought "Forbidden Fruit" should\'ve had a different cover (as a single).
',

      image: ['https://ephellon.github.io/Designer/img/Forbidden Fruit.jpg'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/Forbidden Fruit.jpg']
      ]
    }, {
      title: 'Michael Jackson: Dirty Diana',
      text: '
A single version of Michael Jackson\'s Dirty Diana. It feels more like the song than the original, and 2017 album arts.
',

      image: ['https://ephellon.github.io/Designer/img/Dirty Diana.png'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/Dirty Diana.png']
      ]
    }, {
      title: 'Cardi B: Bodak Yellow',
      text: '
Preffered album art for Cardi B\'s Bodak Yellow (iTunes).
',

      image: ['https://ephellon.github.io/Designer/img/Bodak Yellow.png'],
      site: [
        ['Link to Image', 'fa-link', 'https://ephellon.github.io/Designer/img/Bodak Yellow.png']
      ]
    }
    /*, {
      title: 'Title',
      text: '
Description.
',

      image: ['#link-to-preview-image'],
      site: [
        ['CodePen', 'fa-codepen', '#link-to-pen'],
        ['Live Site', 'fa-link', '#link-to-site']
      ]
    }
    */
    ];

  // add listener to all the cards for click flipping
  function addListener() {
    var cards = document.querySelectorAll(".card.effect_click");

    for (var i = 0; i < cards.length; i++) {
      clickListener(cards[i]);
    }

    function clickListener(card) {
      card.addEventListener("click", function() {
        this.classList.toggle("flipped");
      });
    }
  }

  // create, populate and show portfolio project cards
  function showProjectCards() {
    var html = '';

    projectData.forEach(function(project) {
      html += '
' +
              '

' +
              '
' +
              '
' +
              project.title +
              '

' +

              '

' +
              '
' + project.title + '
' +
              '
' +
              '
' + project.text + '
' +
              '
';

      if (typeof project.site[1] != 'undefined')
        html += '';

      html += '

' +
              '
' +
              '
';
    });

    $('#theProjects').append(html);
    addListener();
  }

  showProjectCards();
  $(".copyright").append("© " + year + " Ephellon Dantzler. All rights reserved");

  // turn on bootstrap tooltips
  $('[data-toggle="tooltip"]').tooltip();

});
<|endoftext|>