<commit_before>//
// zombiePositions.js
// A library with functions that access the JSON containing zombie
// positions
//
// Author: Elisa Lupin-Jimenez
// Copyright High Fidelity 2018
//
// Licensed under the Apache 2.0 License
// See accompanying license file or http://apache.org/
//
// All assets are under CC Attribution Non-Commerical
// http://creativecommons.org/licenses/
//
/* globals module */

module.exports = {
    positions: {
        Red: {
            1: {
                x: -9.685,
                y: -8.8159,
                z: 16.6786
            },
            2: {
                x: -53.6797,
                y: -0.1246,
                z: -70.1916
            },
            3: {
                x: -23.3401,
                y: -9.2971,
                z: 7.9735
            },
            4: {
                x: -13.1930,
                y: -8.9837,
                z: -19.09211
            },
            5: {
                x: 23.7724,
                y: -8.3833,
                z: -13.1789
            },
            readable: {
                1: "Starting Bus",
                2: "Trees in the forest",
                3: "Second Bus",
                4: "Flipped over car",
                5: "Behind A&J"
            }
        },
        Purple: {
            1: {
                x: -31.4595,
                y: 3.3229,
                z: -63.5472
            },
            2: {
                x: -24.1829,
                y: -9.444,
                z: 5.0390
            },
            3: {
                x: -12.9658,
                y: -2.9995,
                z: -45.7409
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "Forest",
                2: "Second Bus",
                3: "Inside Regalia",
                4: "Boardwalk"
            }

        },
        Pink: {
            1: {
                x:-22.87,
                y:-3.972,
                z:-31.82
            },
            2: {
                x:-18.601,
                y:-9.198,
                z:25.885
            },
            3: {
                x:-34.911,
                y:-2.9444,
                z:-33.705
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "Dumpster",
                2: "Boardwalk",
                3: "Near Regalia",
                4: "Boardwalk"
            }
        },
        Teal : {
            1: {
                x: 3.2379,
                y: -5.2083,
                z: -32.8581
            },
            2: {
                x: -25.1212,
                y: -9.2486,
                z: 2.6429
            },
            3: {
                x: -31.6578,
                y: 3.3258,
                z: -68.6602
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "A&J Cubby",
                2: "Near Gas Main",
                3: "Forest",
                4: "Boardwalk"
            }
        },
        Brick: {
            1: {
                x:8.9289,
                y:-8.42,
                z:-15.043
            },
            2: {
                x:-27.6005,
                y:-9.1983,
                z:5.1727
            },
            3: {
                x:-47.769,
                y:-0.025,
                z:-61.34
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable : {
                1: "Back Alley",
                2: "Across from Gas Main",
                3: "Forest",
                4: "Boardwalk"
            }
        },
        Maroon: {
            1: {
                x:-21.4689,
                y:-9.1611,
                z:4.42181
            },
            2: {
                x:-19.5104,
                y:-9.16155,
                z:-8.32982
            },
            3: {
                x:34.951,
                y:-2.9243,
                z:-45.204
            },
            readable : {
                1: "Bus",
                2: "Back Alley",
                3: "Plateau"
            }
        },
        Boardwalk: {
            1: {
                x:-36.7870,
                y:-9.01325,
                z:18.25436
            },
            2: {
                x:-28.024,
                y:-9.3441,
                z:28.9311
            },
            3: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "Blocking cars",
                2: "Boardwalk path",
                3: "Final boardwalk"
            }
        },
        Generator: {
            1: {
                x:3.25877,
                y:-7.6755,
                z:-22.40
            },
            2: {
                x:2.4047,
                y:-6.2222,
                z:-27.292
            },
            3: {
                x:3.25877,
                y:-7.6755,
                z:-22.40
            },
            4: {
                x:1.0234,
                y:-9.2155,
                z:21.691
            },
            readable: {
                1: "Hill by A&J",
                2: "Near statue at A&J",
                3: "Hill by A&J",
                4: "Boardwalk"
            }
        },
        Plateau: {
            1: {
                x:26.7789,
                y:-3.0295,
                z:-23.85
            },
            2: {
                x:35.30,
                y:-2.96,
                z:-45.07
            },
            readable : {
                1: "Plateau Entry",
                2: "Top of Hill"
            }
        },
        CityWalk: {
            1: {
                x:-23.48978,
                y:-3.431381,
                z:-41.3309
            },
            2: {
                x:-10.348,
                y:-4.2053,
                z:-33.520
            },
            3: {
                x:1.0234,
                y:-9.2155,
                z:21.691
            },
            readable: {
                1: "Before Regalia",
                2: "Near Regalia Entrance",
                3: "Boardwalk"
            }
        }
    },

    getPosition: function(color, number, library) {
        if (color in library) {
            var colorJSON = library[color];
            if (number in colorJSON) {
                return colorJSON[number];
            }
            print("number not in specified color");
            return null;
        } else {
            print("Unable to locate position");
            return null;
        }
    }
};<commit_msg>Update zombiePositions.js<commit_after>//
// zombiePositions.js
// A library with functions that access the JSON containing zombie
// positions
//
// Author: Elisa Lupin-Jimenez
// Copyright High Fidelity 2018
//
// Licensed under the Apache 2.0 License
// See accompanying license file or http://apache.org/
//
// All assets are under CC Attribution Non-Commerical
// http://creativecommons.org/licenses/
//
/* globals module */

module.exports = {
    positions: {
        Red: {
            1: {
                x: -9.685,
                y: -8.8159,
                z: 16.6786
            },
            2: {
                x: -53.6797,
                y: -0.1246,
                z: -70.1916
            },
            3: {
                x: -23.3401,
                y: -9.2971,
                z: 7.9735
            },
            4: {
                x: -13.1930,
                y: -8.9837,
                z: -19.09211
            },
            5: {
                x: 23.7724,
                y: -8.3833,
                z: -13.1789
            },
            readable: {
                1: "Starting Bus",
                2: "Trees in the forest",
                3: "Second Bus",
                4: "Flipped over car",
                5: "Behind A&J"
            }
        },
        Purple: {
            1: {
                x: -31.4595,
                y: 3.3229,
                z: -63.5472
            },
            2: {
                x: -24.1829,
                y: -9.444,
                z: 5.0390
            },
            3: {
                x: -12.9658,
                y: -2.9995,
                z: -45.7409
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "Forest",
                2: "Second Bus",
                3: "Inside Regalia",
                4: "Boardwalk"
            }

        },
        Pink: {
            1: {
                x:-22.87,
                y:-3.972,
                z:-31.82
            },
            2: {
                x:-18.601,
                y:-9.198,
                z:25.885
            },
            3: {
                x:-34.911,
                y:-2.9444,
                z:-33.705
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "Dumpster",
                2: "Boardwalk",
                3: "Near Regalia",
                4: "Boardwalk"
            }
        },
        Teal : {
            1: {
                x: 3.2379,
                y: -5.2083,
                z: -32.8581
            },
            2: {
                x: -25.1212,
                y: -9.2486,
                z: 2.6429
            },
            3: {
                x: -31.6578,
                y: 3.3258,
                z: -68.6602
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "A&J Cubby",
                2: "Near Gas Main",
                3: "Forest",
                4: "Boardwalk"
            }
        },
        Brick: {
            1: {
                x:8.9289,
                y:-8.42,
                z:-15.043
            },
            2: {
                x:-27.6005,
                y:-9.1983,
                z:5.1727
            },
            3: {
                x:-47.769,
                y:-0.025,
                z:-61.34
            },
            4: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable : {
                1: "Back Alley",
                2: "Across from Gas Main",
                3: "Forest",
                4: "Boardwalk"
            }
        },
        Maroon: {
            1: {
                x:-21.4689,
                y:-9.1611,
                z:4.42181
            },
            2: {
                x:-19.5104,
                y:-9.16155,
                z:-8.32982
            },
            3: {
                x:34.951,
                y:-2.9243,
                z:-45.204
            },
            readable : {
                1: "Bus",
                2: "Back Alley",
                3: "Plateau"
            }
        },
        Boardwalk: {
            1: {
                x:-36.7870,
                y:-9.01325,
                z:18.25436
            },
            2: {
                x:-28.024,
                y:-9.3441,
                z:28.9311
            },
            3: {
                x: -1.9797,
                y: -10.2699,
                z: 22.4347
            },
            readable: {
                1: "Blocking cars",
                2: "Boardwalk path",
                3: "Final boardwalk"
            }
        },
        Generator: {
            1: {
                x:3.25877,
                y:-7.6755,
                z:-22.40
            },
            2: {
                x:2.4047,
                y:-6.2222,
                z:-27.292
            },
            3: {
                x:3.25877,
                y:-7.6755,
                z:-22.40
            },
            4: {
                x:1.0234,
                y:-9.2155,
                z:21.691
            },
            readable: {
                1: "Hill by A&J",
                2: "Near statue at A&J",
                3: "Hill by A&J",
                4: "Boardwalk"
            }
        },
        Plateau: {
            1: {
                x:26.7789,
                y:-3.0295,
                z:-23.85
            },
            2: {
                x:35.30,
                y:-2.96,
                z:-45.07
            },
            readable : {
                1: "Plateau Entry",
                2: "Top of Hill"
            }
        },
        CityWalk: {
            1: {
                x:-23.48978,
                y:-3.431381,
                z:-41.3309
            },
            2: {
                x:-10.348,
                y:-4.2053,
                z:-33.520
            },
            3: {
                x:1.0234,
                y:-9.2155,
                z:21.691
            },
            readable: {
                1: "Before Regalia",
                2: "Near Regalia Entrance",
                3: "Boardwalk"
            }
        }
    },

    getPosition: function(color, number, library) {
        if (color in library) {
            var colorJSON = library[color];
            if (number in colorJSON) {
                return colorJSON[number];
            }
            print("number not in specified color");
            return null;
        } else {
            print("Unable to locate position");
            return null;
        }
    }
};
<|endoftext|>


<commit_before>var w = 960,
    h = 700,
    r = Math.min(w, h) / 2;

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h)
  .append("svg:g")
    .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

function draw( org, question, colors ) {
  var optionToColor = {};
  for (var k = 0; k < question.options.length; k++) {
    optionToColor[question.options[k].id] = colors[k];
  }
  function voteColor(member) {
    var option = member.getEffectiveVote(question);
    if (option === null) {
      return '#999999';
    } else {
      if (optionToColor[option.id]) {
        return optionToColor[option.id];
      } else {
        return '#333333';
      }
    }
  }

  var partition = d3.layout.partition()
      .sort(null)
      .size([2 * Math.PI, r * r])
      .value(function(d) { return 1; })
      .children(function(member) {
         return org.getProxyChildren(member);
      });

  var arc = d3.svg.arc()
      .startAngle(function(d) { return d.x; })
      .endAngle(function(d) { return d.x + d.dx; })
      .innerRadius(function(d) { return Math.sqrt(d.y); })
      .outerRadius(function(d) { return Math.sqrt(d.y + d.dy); });

//var json = { name: 'flare', children: [ { name: 'alpha' }, { name: 'beta' }, { name: 'gamma' } ] };
// var json = { name: 'flare' };
//, children: [ { name: 'alpha' }, { name: 'beta' }, { name: 'gamma' } ] };
  var json = org.getRoot();
//debugger;
    var path = vis.data([json]).selectAll("path")
      .data(partition.nodes)
    .enter().append("svg:path")
      .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
      .attr("d", arc)
      .attr("fill-rule", "evenodd")
      .style("stroke", "#fff")
      .style("fill", voteColor )
      .each(stash);

}

// Stash the old values for transition.
function stash(d) {
  d.x0 = d.x;
  d.dx0 = d.dx;
}

// Interpolate the arcs in data space.
function arcTween(a) {
  var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
  return function(t) {
    var b = i(t);
    a.x0 = b.x;
    a.dx0 = b.dx;
    return arc(b);
  };
}

var population = 100;
// this is from flare.js
var org = generateRandomOrg(window.names, population);
var question = new Question( 'Lunch', [ 'pizza', 'chinese', 'falafel' ] );
org.addQuestion(question);

var proxies = [];
for ( var i = 1; i < population; i++ ) {
  if ( Math.random() * 2 > 1 ) {
    var target = Math.round( Math.sqrt( Math.random() * population ) );
    if ( i !== target && i !== 0 && target !== 0 ) {
      proxies.push( [ i.toString(), target.toString() ] );
    }
  }
}
// console.log( proxies );

function doProxies() {
  console.log( 'doProxies' );
  if ( proxies.length ) {
    _.each( proxies, function( proxy ) {
      console.log( "doing " + proxy[0] + " -> " + proxy[1] );
      org.setProxy( org.roster[proxy[0]], org.roster[proxy[1]] );
    } );
    //draw();
    // doProxies();
  }
}
doProxies();

var votes = [];
for ( var j = 1; j < population; j++ ) {
  if ( Math.random() * 2 > 1 ) {
    var optionIndex = Math.round( Math.random() * (question.options.length - 1) );
    var option = question.options[optionIndex];
    votes.push( [ j, question, option ] );
  }
}

function doVotes() {
  console.log( 'doVotes' );
  if ( votes.length ) {
    _.each( votes, function( vote ) {
      var member = org.roster[vote[0].toString()];
      var question = vote[1];
      var option = vote[2];
      console.log( "doing " + member.id + " voting " + question.description + " =  " + option.description );
      member.vote( question, option );
    } );
    //draw();
  }
}
doVotes();

var colors = [
    '#ff0000',
    '#ffa000',
    '#00ffff',
    '#00ff00',
    '#00ccff'
  ];

draw(org, question, colors);

/*
manipulate

  d3.select("#size").on("click", function() {
    path
        .data(partition.value(function(d) { return d.size; }))
      .transition()
        .duration(1500)
        .attrTween("d", arcTween);

    d3.select("#size").classed("active", true);
    d3.select("#count").classed("active", false);
  });

  d3.select("#count").on("click", function() {
    path
        .data(partition.value(function(d) { return 1; }))
      .transition()
        .duration(1500)
        .attrTween("d", arcTween);

    d3.select("#size").classed("active", false);
    d3.select("#count").classed("active", true);
  });
*/
<commit_msg>node sorting by effective vote (grouped together!)<commit_after>var w = 960,
    h = 700,
    r = Math.min(w, h) / 2;

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h)
  .append("svg:g")
    .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

function draw( org, question, colors ) {
  var optionToColor = {};
  for (var k = 0; k < question.options.length; k++) {
    optionToColor[question.options[k].id] = colors[k];
  }
  function voteColor(member) {
    var option = member.getEffectiveVote(question);
    if (option === null) {
      return '#999999';
    } else {
      if (optionToColor[option.id]) {
        return optionToColor[option.id];
      } else {
        return '#333333';
      }
    }
  }
  function byEffectiveVote(member1, member2) {
    function getVoteOrMax(member) {
      var vote = member.getEffectiveVote(question);
      return vote ? Number(vote.id) : -99999;
    }
    var val1 = getVoteOrMax(member1);
    var val2 = getVoteOrMax(member2);
    console.log( member1.name + "(" + val1 + ") " + member2.name + "(" + val2 + ")" );
    return val2 - val1;
  }

  var partition = d3.layout.partition()
      .sort(byEffectiveVote)
      .size([2 * Math.PI, r * r])
      .value(function(d) { return 1; })
      .children(function(member) {
         return org.getProxyChildren(member);
      });

  var arc = d3.svg.arc()
      .startAngle(function(d) { return d.x; })
      .endAngle(function(d) { return d.x + d.dx; })
      .innerRadius(function(d) { return Math.sqrt(d.y); })
      .outerRadius(function(d) { return Math.sqrt(d.y + d.dy); });

//var json = { name: 'flare', children: [ { name: 'alpha' }, { name: 'beta' }, { name: 'gamma' } ] };
// var json = { name: 'flare' };
//, children: [ { name: 'alpha' }, { name: 'beta' }, { name: 'gamma' } ] };
  var json = org.getRoot();
//debugger;
    var path = vis.data([json]).selectAll("path")
      .data(partition.nodes)
    .enter().append("svg:path")
      .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
      .attr("d", arc)
      .attr("fill-rule", "evenodd")
      .style("stroke", "#fff")
      .style("fill", voteColor )
      .each(stash);

}

// Stash the old values for transition.
function stash(d) {
  d.x0 = d.x;
  d.dx0 = d.dx;
}

// Interpolate the arcs in data space.
function arcTween(a) {
  var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
  return function(t) {
    var b = i(t);
    a.x0 = b.x;
    a.dx0 = b.dx;
    return arc(b);
  };
}

var population = 100;
// this is from flare.js
var org = generateRandomOrg(window.names, population);
var question = new Question( 'Lunch', [ 'pizza', 'chinese', 'falafel' ] );
org.addQuestion(question);

var proxies = [];
for ( var i = 1; i < population; i++ ) {
  if ( Math.random() * 2 > 1 ) {
    var target = Math.round( Math.sqrt( Math.random() * population ) );
    if ( i !== target && i !== 0 && target !== 0 ) {
      proxies.push( [ i.toString(), target.toString() ] );
    }
  }
}
// console.log( proxies );

function doProxies() {
  console.log( 'doProxies' );
  if ( proxies.length ) {
    _.each( proxies, function( proxy ) {
      console.log( "doing " + proxy[0] + " -> " + proxy[1] );
      org.setProxy( org.roster[proxy[0]], org.roster[proxy[1]] );
    } );
    //draw();
    // doProxies();
  }
}
doProxies();

var votes = [];
for ( var j = 1; j < population; j++ ) {
  if ( Math.random() * 2 > 1 ) {
    var optionIndex = Math.round( Math.random() * (question.options.length - 1) );
    var option = question.options[optionIndex];
    votes.push( [ j, question, option ] );
  }
}

function doVotes() {
  console.log( 'doVotes' );
  if ( votes.length ) {
    _.each( votes, function( vote ) {
      var member = org.roster[vote[0].toString()];
      var question = vote[1];
      var option = vote[2];
      console.log( "doing " + member.id + " voting " + question.description + " =  " + option.description );
      member.vote( question, option );
    } );
    //draw();
  }
}
doVotes();

var colors = [
    '#ff0000',
    '#ffa000',
    '#00ffff',
    '#00ff00',
    '#00ccff'
  ];

draw(org, question, colors);

/*
manipulate

  d3.select("#size").on("click", function() {
    path
        .data(partition.value(function(d) { return d.size; }))
      .transition()
        .duration(1500)
        .attrTween("d", arcTween);

    d3.select("#size").classed("active", true);
    d3.select("#count").classed("active", false);
  });

  d3.select("#count").on("click", function() {
    path
        .data(partition.value(function(d) { return 1; }))
      .transition()
        .duration(1500)
        .attrTween("d", arcTween);

    d3.select("#size").classed("active", false);
    d3.select("#count").classed("active", true);
  });
*/
<|endoftext|>


<commit_before>const domReady = function (callback) {
	const state = document.readyState;
	if (state === 'interactive' || state === 'complete') {
		callback();
	} else {
		document.addEventListener('DOMContentLoaded', callback);
	}
};

domReady(() => {
	const projectname = document.createElement('a');
	projectname.classList.add('project-name');
	projectname.text = 'combinatorics/permutation';
	projectname.href = './index.html';

	const header = document.querySelector('header');
	header.insertBefore(projectname, header.firstChild);

	const testlink = document.querySelector('header > a[data-ice="testLink"]');
	testlink.href =
		'https://coveralls.io/github/computational-combinatorics/permutation';
	testlink.target = '_BLANK';

	const searchBox = document.querySelector('.search-box');
	const input = document.querySelector('.search-input');

	// Active search box when focus on searchBox.
	input.addEventListener('focus', () => {
		searchBox.classList.add('active');
	});
});
<commit_msg>:robot: docs: Use codecov as test link.<commit_after>const domReady = function (callback) {
	const state = document.readyState;
	if (state === 'interactive' || state === 'complete') {
		callback();
	} else {
		document.addEventListener('DOMContentLoaded', callback);
	}
};

domReady(() => {
	const projectname = document.createElement('a');
	projectname.classList.add('project-name');
	projectname.text = 'combinatorics/permutation';
	projectname.href = './index.html';

	const header = document.querySelector('header');
	header.insertBefore(projectname, header.firstChild);

	const testlink = document.querySelector('header > a[data-ice="testLink"]');
	testlink.href =
		'https://app.codecov.io/gh/computational-combinatorics/permutation';
	testlink.target = '_BLANK';

	const searchBox = document.querySelector('.search-box');
	const input = document.querySelector('.search-input');

	// Active search box when focus on searchBox.
	input.addEventListener('focus', () => {
		searchBox.classList.add('active');
	});
});
<|endoftext|>


<commit_before><commit_msg>DevTools: Use in JavaScriptSourceFrame current target's debuggerModel instead of WebInspector.debuggerModel<commit_after><|endoftext|>


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

    var _context = null;
    var _fruitLayer = null;
    // var _fruitCollection = null;

    // Constructor
    function FruitDrawer(context, fruitLayer, fruitCollecion) {
        _context = context;
        _fruitLayer = fruitLayer.draw(); // draw and return an object
        //  _fruitCollection = fruitCollecion;
    }

    FruitDrawer.prototype.drawFruits = function (_fruitCollection, _collisionDispather, _mouseEventHandler) {
        //console.log(_fruitCollection)
        //for (var i = 0; i < _fruitCollection.length; i++) {
        //    console.log(_fruitCollection[i].coords)
        //    var imageObj = new Image();
        //    imageObj.onload = function () {
        //        var img = new Kinetic.Image({
        //            x: 50,
        //            y: 50,
        //            image: imageObj,
        //            width: 106,
        //            height: 118
        //        });
        //        _fruitLayer.add(img);
        //        console.log('----------------')
        //    }
        //    imageObj.src = 'images/' + _fruitCollection[i].defaultImageSrc;
        //}
        var canvas = document.getElementsByTagName('canvas')[0],
            ctx = canvas.getContext('2d'),
            center = {
                x: canvas.width / 2,
                y: canvas.height / 2 - 100
            },
            radius = 100,
            angle = 0,
            point = {
                radius: 30,
                x: 0,
                y: 0
            };

        //fruit
        function drawPoint(ctx, x, y, r, color) {
            ctx.beginPath();
            ctx.fillStyle = color;
            ctx.arc(x, y, r, 0, 2 * Math.PI);
            ctx.fill();
        }

        function drawFruit(ctx, x, y, imageObj) {
            /*ctx.beginPath();
            ctx.fillStyle = color;
            ctx.arc(x, y, r, 0, 2 * Math.PI);
            ctx.fill();*/

            ctx.drawImage(imageObj, x, y);
        }

        function movePoint(trajectory, isLeft) {
            var trajRadius = isLeft ? trajectory.radius : -trajectory.radius;

            return {
                x: trajectory.x + trajRadius * Math.cos(trajectory.angle / 180 * Math.PI) / 1.2,
                y: canvas.height - (trajectory.y + trajectory.radius * Math.sin(trajectory.angle / 180 * Math.PI) * trajectory.factorY)
            };
        }

        var shouldRun = true;

        function frame() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            angle += 1.5;

            if (angle >= 200) {
                _fruitCollection = [];
                angle = 0;
            }

            for (var i = 0; i < _fruitCollection.length; i++) {
                var movedPoints = movePoint({
                    x: _fruitCollection[i].x,
                    y: center.y - 150,
                    radius: radius,
                    angle: angle,
                    factorY: _fruitCollection[i].factorY
                }, _fruitCollection[i].direction);

                _collisionDispather.checkForCuttedOffFruits(_mouseEventHandler, _fruitCollection[i], movedPoints.x, movedPoints.y);

                var color = _fruitCollection[i].isCut ? '#ccc' : '#000';
                //drawPoint(ctx, movedPoints.x + i * 10, movedPoints.y, 50, color);

                drawFruit(ctx, movedPoints.x + i * 10, movedPoints.y, imageObj);

                if (movedPoints.y >= 500) {
                    _fruitCollection = null;
                }

                if (angle >= 180) {
                    _fruitCollection = [];
                    angle = 0;
                }
            }

            if (_fruitCollection.length > 0)
                window.requestAnimationFrame(frame);

        }
        var imageObj = new Image();
        imageObj.src = 'images/watermelon.png';
        imageObj.onload = function () {
            frame();
        };
    };

    return FruitDrawer;
});
<commit_msg>Example switching image when fruit is hit. The colision detection needs to be readjusted to the images<commit_after>define(function (require) {
    'use strict';

    var _context = null;
    var _fruitLayer = null;
    // var _fruitCollection = null;

    // Constructor
    function FruitDrawer(context, fruitLayer, fruitCollecion) {
        _context = context;
        _fruitLayer = fruitLayer.draw(); // draw and return an object
        //  _fruitCollection = fruitCollecion;
    }

    FruitDrawer.prototype.drawFruits = function (_fruitCollection, _collisionDispather, _mouseEventHandler) {
        //console.log(_fruitCollection)
        //for (var i = 0; i < _fruitCollection.length; i++) {
        //    console.log(_fruitCollection[i].coords)
        //    var imageObj = new Image();
        //    imageObj.onload = function () {
        //        var img = new Kinetic.Image({
        //            x: 50,
        //            y: 50,
        //            image: imageObj,
        //            width: 106,
        //            height: 118
        //        });
        //        _fruitLayer.add(img);
        //        console.log('----------------')
        //    }
        //    imageObj.src = 'images/' + _fruitCollection[i].defaultImageSrc;
        //}
        var canvas = document.getElementsByTagName('canvas')[0],
            ctx = canvas.getContext('2d'),
            center = {
                x: canvas.width / 2,
                y: canvas.height / 2 - 100
            },
            radius = 100,
            angle = 0,
            point = {
                radius: 30,
                x: 0,
                y: 0
            };

        //deprecated
        /*function drawPoint(ctx, x, y, r, color) {
            ctx.beginPath();
            ctx.fillStyle = color;
            ctx.arc(x, y, r, 0, 2 * Math.PI);
            ctx.fill();
        }*/

        function drawFruit(ctx, x, y, imageObj) {
            ctx.drawImage(imageObj, x, y);
        }

        function movePoint(trajectory, isLeft) {
            var trajRadius = isLeft ? trajectory.radius : -trajectory.radius;

            return {
                x: trajectory.x + trajRadius * Math.cos(trajectory.angle / 180 * Math.PI) / 1.2,
                y: canvas.height - (trajectory.y + trajectory.radius * Math.sin(trajectory.angle / 180 * Math.PI) * trajectory.factorY)
            };
        }

        var shouldRun = true;

        function frame() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            angle += 1.5;

            if (angle >= 200) {
                _fruitCollection = [];
                angle = 0;
            }

            for (var i = 0; i < _fruitCollection.length; i++) {
                var movedPoints = movePoint({
                    x: _fruitCollection[i].x,
                    y: center.y - 150,
                    radius: radius,
                    angle: angle,
                    factorY: _fruitCollection[i].factorY
                }, _fruitCollection[i].direction);

                _collisionDispather.checkForCuttedOffFruits(_mouseEventHandler, _fruitCollection[i], movedPoints.x, movedPoints.y);

                //deprecated
                //var color = _fruitCollection[i].isCut ? '#ccc' : '#000';
                //drawPoint(ctx, movedPoints.x + i * 10, movedPoints.y, 50, color);

                var image = _fruitCollection[i].isCut ? imageFruitHit : imageFruit;
                drawFruit(ctx, movedPoints.x + i * 10, movedPoints.y, image);

                if (movedPoints.y >= 500) {
                    _fruitCollection = null;
                }

                if (angle >= 180) {
                    _fruitCollection = [];
                    angle = 0;
                }
            }

            if (_fruitCollection.length > 0)
                window.requestAnimationFrame(frame);

        }

        var imageFruit = new Image(),
            imageFruitHit = new Image();
        imageFruit.src = 'images/watermelon.png';
        imageFruitHit.src = 'images/watermelon-hit.png';

        //onload for multiple images
        var imageCollector = function (expectedCount, completeFn) {
            var receivedCount;
            return function () {
                if (++receivedCount == expectedCount) {
                    completeFn();
                }
            };
        }();

        var ic = imageCollector(2, frame());
        imageFruit.onload = ic;
        imageFruitHit.onload = ic;

        /*imageFruit.onload = function () {
    frame();
};*/
    };

    return FruitDrawer;
});
<|endoftext|>


<commit_before>scripts
<commit_msg>deleted<commit_after><|endoftext|>


<commit_before><commit_msg>#1377 - Role attributes<commit_after><|endoftext|>


<commit_before>/**
 * JavaScript based speech recognizer.
 *
 * Copyright 2016, Dominic Winkelman
 * Free to use under the Apache 2.0 License
 *
 * https://github.com/dreamdom/JsSpeechRecognizer
 *
 * Requires the WebRTC adapter.js file.
 */

function JsSpeechRecognizer() {

    // Constants
    this.RecordingEnum = { "NOT_RECORDING": 0, "TRAINING": 1, "RECOGNITION": 2, "KEYWORD_SPOTTING": 3 };
    Object.freeze(this.RecordingEnum);
    this.RecognitionModel = { "TRAINED": 0, "AVERAGE": 1, "COMPOSITE": 2 };
    Object.freeze(this.RecognitionModel);

    // Variables for recording data
    this.recordingBufferArray = [];
    this.currentRecordingBuffer = [];
    this.wordBuffer = [];
    this.modelBuffer = [];
    this.groupedValues = [];

    // Keyword spotting variables for recording data
    this.keywordSpottingGroupBuffer = [];
    this.keywordSpottingRecordingBuffer = [];

    // The speech recognition model
    this.model = {};

    // The average model contains one average entry for each key
    this.averageModel = {};

    // State variable. Initialize to not recording
    this.recordingState = this.RecordingEnum.NOT_RECORDING;
    // Default to using the composite recognition model
    this.useRecognitionModel = this.RecognitionModel.COMPOSITE;

    // Get an audio context
    this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();

    // Create an analyser
    this.analyser = this.audioCtx.createAnalyser();
    this.analyser.minDecibels = -80;
    this.analyser.maxDecibels = -10;
    this.analyser.smoothingTimeConstant = 0;
    this.analyser.fftSize = 1024;

    // Parameters for the model calculation
    this.numGroups = 25;
    this.groupSize = 10;
    this.minPower = 0.01;

    // Keyword spotting parameters
    this.keywordSpottingMinConfidence = 0.55;
    this.keywordSpottingBufferCount = 80;
    this.keywordSpottedCallback = null;

    // Create the scriptNode
    this.scriptNode = this.audioCtx.createScriptProcessor(this.analyser.fftSize, 1, 1);

    // Function for script node to process
    var _this = this;
    this.scriptNode.onaudioprocess = function(audioProcessingEvent) {

        var i = 0;

        // If we aren't recording, don't do anything
        if (_this.recordingState === _this.RecordingEnum.NOT_RECORDING) {
            return;
        }

        // get the fft data
        var dataArray = new Uint8Array(_this.analyser.fftSize);
        _this.analyser.getByteFrequencyData(dataArray);

        // Find the max in the fft array
        var max = Math.max.apply(Math, dataArray);

        // If the max is zero ignore it.
        if (max === 0) {
            return;
        }

        // Get the audio data. For simplicity just take one channel
        var inputBuffer = audioProcessingEvent.inputBuffer;
        var leftChannel = inputBuffer.getChannelData(0);

        // Calculate the power
        var curFrame = new Float32Array(leftChannel);
        var power = 0;
        for (i = 0; i < curFrame.length; i++) {
            power += curFrame[i] * curFrame[i];
        }

        // Check for the proper power level
        if (power < _this.minPower) {
            return;
        }

        // Save the data for playback.
        Array.prototype.push.apply(_this.currentRecordingBuffer, curFrame);

        // Normalize and Group the frequencies
        var groups = [];

        for (i = 0; i < _this.numGroups; i++) {
            var peakGroupValue = 0;
            for (var j = 0; j < _this.groupSize; j++) {
                var curPos = (_this.groupSize * i) + j;

                // normalize the value
                var tempCalc = Math.floor((dataArray[curPos] / max) * 100);

                // Keep the peak normalized value for this group
                if (tempCalc > peakGroupValue) {
                    peakGroupValue = tempCalc;
                }

            }
            groups.push(peakGroupValue);
        }

        // Depending on the state, handle the data differently
        if (_this.recordingState === _this.RecordingEnum.KEYWORD_SPOTTING) {
            _this.keywordSpottingProcessFrame(groups, curFrame);
        } else {
            _this.groupedValues.push(groups);
        }

    };  // End of onaudioprocess

}

JsSpeechRecognizer.prototype.openMic = function() {
    // Request access to the microphone
    var constraints = {
        "audio": true
    };

    navigator.getUserMedia(constraints, successCallback, errorCallback);

    var _this = this;
    // Acess to the microphone was granted
    function successCallback(stream) {
        _this.stream = stream;
        _this.source = _this.audioCtx.createMediaStreamSource(stream);

        _this.source.connect(_this.analyser);
        _this.analyser.connect(_this.scriptNode);

        // This is needed for chrome
        _this.scriptNode.connect(_this.audioCtx.destination);
    }

    function errorCallback(error) {
        console.error('navigator.getUserMedia error: ', error);
    }
};

/**
 * Returns false if the recognizer is not recording. True otherwise.
 */
JsSpeechRecognizer.prototype.isRecording = function() {
    if (this.recordingState === this.RecordingEnum.NOT_RECORDING) {
        return false;
    }

    return true;
};

JsSpeechRecognizer.prototype.startTrainingRecording = function(curWord) {

    this.recordingState = this.RecordingEnum.TRAINING;

    // Create a new current recording buffer
    this.currentRecordingBuffer = [];

    // Create a new groupedValues buffer
    this.groupedValues = [];
    this.wordBuffer.push(curWord);
};

JsSpeechRecognizer.prototype.startRecognitionRecording = function() {

    this.recordingState = this.RecordingEnum.RECOGNITION;

    // Create a new current recording buffer
    this.currentRecordingBuffer = [];

    // Create a new groupedValues buffer
    this.groupedValues = [];
};

JsSpeechRecognizer.prototype.stopRecording = function() {

    this.groupedValues = [].concat.apply([], this.groupedValues);

    // If we are training we want to save to the recongition model
    if (this.recordingState === this.RecordingEnum.TRAINING) {
        this.recordingBufferArray.push(this.currentRecordingBuffer.slice(0));
        this.modelBuffer.push(this.groupedValues.slice(0));
    }

    this.recordingState = this.RecordingEnum.NOT_RECORDING;

    return this.recordingBufferArray.length;
};

/**
 * Function will play back the recorded audio for a specific index that is part of the training data.
 */
JsSpeechRecognizer.prototype.playTrainingBuffer = function(index) {
    this.playMonoAudio(this.recordingBufferArray[index]);
};

JsSpeechRecognizer.prototype.deleteTrainingBuffer = function(input) {
    this.modelBuffer[input] = null;
};

JsSpeechRecognizer.prototype.playMonoAudio = function(playBuffer) {

    // Mono
    var channels = 1;
    var frameCount = playBuffer.length;
    var myArrayBuffer = this.audioCtx.createBuffer(channels, frameCount, this.audioCtx.sampleRate);

    for (var channel = 0; channel < channels; channel++) {
        var nowBuffering = myArrayBuffer.getChannelData(channel);
        for (var i = 0; i < frameCount; i++) {
            nowBuffering[i] = playBuffer[i];
        }
    }

    var playSource = this.audioCtx.createBufferSource();
    playSource.buffer = myArrayBuffer;
    playSource.connect(this.audioCtx.destination);
    playSource.start();
};

/**
 * Method to generate the new speech recognition model from the training data.
 */
JsSpeechRecognizer.prototype.generateModel = function() {

    // Local vars
    var i = 0;
    var key = "";

    // Reset the model
    this.model = {};

    for (i = 0; i < this.wordBuffer.length; i++) {
        key = this.wordBuffer[i];
        this.model[key] = [];
    }

    for (i = 0; i < this.modelBuffer.length; i++) {
        if (this.modelBuffer[i] !== null) {
            key = this.wordBuffer[i];
            this.model[key].push(this.modelBuffer[i]);
        }
    }

    // Average Model
    // Holds one entry for each key. That entry is the average of all the entries in the model
    this.averageModel = {};
    for (key in this.model) {
        var average = [];
        for (i = 0; i < this.model[key].length; i++) {
            for (var j = 0; j < this.model[key][i].length; j++) {
                average[j] = (average[j] || 0) + (this.model[key][i][j] / this.model[key].length);
            }
        }

        this.averageModel[key] = [];
        this.averageModel[key].push(average);
    }

};

JsSpeechRecognizer.prototype.getTopRecognitionHypotheses = function(numResults) {

    if (this.useRecognitionModel === this.RecognitionModel.AVERAGE) {
        return this.findClosestMatch(this.groupedValues, numResults, this.averageModel);
    } else if (this.useRecognitionModel === this.RecognitionModel.TRAINED) {
        return this.findClosestMatch(this.groupedValues, numResults, this.model);
    } else {
        // For the composite model, combine the trained and average results and sort them
        var results = this.findClosestMatch(this.groupedValues, -1, this.model);
        var resultsAverage = this.findClosestMatch(this.groupedValues, -1, this.averageModel);

        var allResults = results.concat(resultsAverage);
        allResults.sort(function(a, b) { return b.confidence - a.confidence; });

        return allResults.slice(0, numResults);
    }
};

/**
 * Function called to process a new frame of data while in recording state KEYWORD_SPOTTING.
 *  groups - the group data for the frame
 *  curFrame - the raw audio data for the frame
 */
JsSpeechRecognizer.prototype.keywordSpottingProcessFrame = function(groups, curFrame) {

};

// Calculation functions

JsSpeechRecognizer.prototype.findClosestMatch = function(input, numResults, speechModel) {

    var i = 0;
    var key = "";
    var allResults = [];

    // Loop through all the keys in the model
    for (key in speechModel) {
        // Loop through all entries for that key
        for (i = 0; i < speechModel[key].length; i++) {

            var curDistance = this.findDistance(input, speechModel[key][i]);
            var curConfidence = this.calcConfidence(curDistance, speechModel[key][i]);

            var newResult = {};
            newResult.match = key;
            newResult.confidence = curConfidence;
            allResults.push(newResult);
        }

    }

    allResults.sort(function(a, b) { return b.confidence - a.confidence; });

    if (numResults === -1) {
        return allResults;
    }

    return allResults.slice(0, numResults);
};

JsSpeechRecognizer.prototype.findDistance = function(input, check) {
    var i = 0;
    var distance = 0;

    for (i = 0; i < Math.max(input.length, check.length); i++) {
        var checkVal = check[i] || 0;
        var inputVal = input[i] || 0;
        distance += Math.abs(checkVal - inputVal);
    }

    return distance;
};

JsSpeechRecognizer.prototype.calcConfidence = function(distance, matchArray) {
    var sum = 0;
    var i = 0;

    for (i = 0; i < matchArray.length; i++) {
        sum += matchArray[i];
    }

    return (1 - (distance / sum));
};

<commit_msg>More work on the keyword spotting functionality.<commit_after>/**
 * JavaScript based speech recognizer.
 *
 * Copyright 2016, Dominic Winkelman
 * Free to use under the Apache 2.0 License
 *
 * https://github.com/dreamdom/JsSpeechRecognizer
 *
 * Requires the WebRTC adapter.js file.
 */

function JsSpeechRecognizer() {

    // Constants
    this.RecordingEnum = { "NOT_RECORDING": 0, "TRAINING": 1, "RECOGNITION": 2, "KEYWORD_SPOTTING": 3 };
    Object.freeze(this.RecordingEnum);
    this.RecognitionModel = { "TRAINED": 0, "AVERAGE": 1, "COMPOSITE": 2 };
    Object.freeze(this.RecognitionModel);

    // Variables for recording data
    this.recordingBufferArray = [];
    this.currentRecordingBuffer = [];
    this.wordBuffer = [];
    this.modelBuffer = [];
    this.groupedValues = [];

    // Keyword spotting variables for recording data
    this.keywordSpottingGroupBuffer = [];
    this.keywordSpottingRecordingBuffer = [];

    // The speech recognition model
    this.model = {};

    // The average model contains one average entry for each key
    this.averageModel = {};

    // State variable. Initialize to not recording
    this.recordingState = this.RecordingEnum.NOT_RECORDING;
    // Default to using the composite recognition model
    this.useRecognitionModel = this.RecognitionModel.COMPOSITE;

    // Get an audio context
    this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();

    // Create an analyser
    this.analyser = this.audioCtx.createAnalyser();
    this.analyser.minDecibels = -80;
    this.analyser.maxDecibels = -10;
    this.analyser.smoothingTimeConstant = 0;
    this.analyser.fftSize = 1024;

    // Parameters for the model calculation
    this.numGroups = 25;
    this.groupSize = 10;
    this.minPower = 0.01;

    // Keyword spotting parameters
    this.keywordSpottingMinConfidence = 0.55;
    this.keywordSpottingBufferCount = 80;
    this.keywordSpottedCallback = null;

    // Create the scriptNode
    this.scriptNode = this.audioCtx.createScriptProcessor(this.analyser.fftSize, 1, 1);

    // Function for script node to process
    var _this = this;
    this.scriptNode.onaudioprocess = function(audioProcessingEvent) {

        var i = 0;

        // If we aren't recording, don't do anything
        if (_this.recordingState === _this.RecordingEnum.NOT_RECORDING) {
            return;
        }

        // get the fft data
        var dataArray = new Uint8Array(_this.analyser.fftSize);
        _this.analyser.getByteFrequencyData(dataArray);

        // Find the max in the fft array
        var max = Math.max.apply(Math, dataArray);

        // If the max is zero ignore it.
        if (max === 0) {
            return;
        }

        // Get the audio data. For simplicity just take one channel
        var inputBuffer = audioProcessingEvent.inputBuffer;
        var leftChannel = inputBuffer.getChannelData(0);

        // Calculate the power
        var curFrame = new Float32Array(leftChannel);
        var power = 0;
        for (i = 0; i < curFrame.length; i++) {
            power += curFrame[i] * curFrame[i];
        }

        // Check for the proper power level
        if (power < _this.minPower) {
            return;
        }

        // Save the data for playback.
        Array.prototype.push.apply(_this.currentRecordingBuffer, curFrame);

        // Normalize and Group the frequencies
        var groups = [];

        for (i = 0; i < _this.numGroups; i++) {
            var peakGroupValue = 0;
            for (var j = 0; j < _this.groupSize; j++) {
                var curPos = (_this.groupSize * i) + j;

                // normalize the value
                var tempCalc = Math.floor((dataArray[curPos] / max) * 100);

                // Keep the peak normalized value for this group
                if (tempCalc > peakGroupValue) {
                    peakGroupValue = tempCalc;
                }

            }
            groups.push(peakGroupValue);
        }

        // Depending on the state, handle the data differently
        if (_this.recordingState === _this.RecordingEnum.KEYWORD_SPOTTING) {
            _this.keywordSpottingProcessFrame(groups, curFrame);
        } else {
            _this.groupedValues.push(groups);
        }

    };  // End of onaudioprocess

}

JsSpeechRecognizer.prototype.openMic = function() {
    // Request access to the microphone
    var constraints = {
        "audio": true
    };

    navigator.getUserMedia(constraints, successCallback, errorCallback);

    var _this = this;
    // Acess to the microphone was granted
    function successCallback(stream) {
        _this.stream = stream;
        _this.source = _this.audioCtx.createMediaStreamSource(stream);

        _this.source.connect(_this.analyser);
        _this.analyser.connect(_this.scriptNode);

        // This is needed for chrome
        _this.scriptNode.connect(_this.audioCtx.destination);
    }

    function errorCallback(error) {
        console.error('navigator.getUserMedia error: ', error);
    }
};

/**
 * Returns false if the recognizer is not recording. True otherwise.
 */
JsSpeechRecognizer.prototype.isRecording = function() {
    if (this.recordingState === this.RecordingEnum.NOT_RECORDING) {
        return false;
    }

    return true;
};

JsSpeechRecognizer.prototype.startTrainingRecording = function(curWord) {

    this.recordingState = this.RecordingEnum.TRAINING;

    // Create a new current recording buffer
    this.currentRecordingBuffer = [];

    // Create a new groupedValues buffer
    this.groupedValues = [];
    this.wordBuffer.push(curWord);
};

JsSpeechRecognizer.prototype.startRecognitionRecording = function() {

    this.recordingState = this.RecordingEnum.RECOGNITION;

    // Create a new current recording buffer
    this.currentRecordingBuffer = [];

    // Create a new groupedValues buffer
    this.groupedValues = [];
};

JsSpeechRecognizer.prototype.startKeywordSpottingRecording = function() {
    this.recordingState = this.RecordingEnum.KEYWORD_SPOTTING;

    // Create a new current recording buffer
    this.currentRecordingBuffer = [];

    // Create a new groupedValues buffer
    this.groupedValues = [];
};

JsSpeechRecognizer.prototype.stopRecording = function() {

    this.groupedValues = [].concat.apply([], this.groupedValues);

    // If we are training we want to save to the recongition model
    if (this.recordingState === this.RecordingEnum.TRAINING) {
        this.recordingBufferArray.push(this.currentRecordingBuffer.slice(0));
        this.modelBuffer.push(this.groupedValues.slice(0));
    }

    this.recordingState = this.RecordingEnum.NOT_RECORDING;

    return this.recordingBufferArray.length;
};

/**
 * Function will play back the recorded audio for a specific index that is part of the training data.
 */
JsSpeechRecognizer.prototype.playTrainingBuffer = function(index) {
    this.playMonoAudio(this.recordingBufferArray[index]);
};

JsSpeechRecognizer.prototype.deleteTrainingBuffer = function(input) {
    this.modelBuffer[input] = null;
};

JsSpeechRecognizer.prototype.playMonoAudio = function(playBuffer) {

    // Mono
    var channels = 1;
    var frameCount = playBuffer.length;
    var myArrayBuffer = this.audioCtx.createBuffer(channels, frameCount, this.audioCtx.sampleRate);

    for (var channel = 0; channel < channels; channel++) {
        var nowBuffering = myArrayBuffer.getChannelData(channel);
        for (var i = 0; i < frameCount; i++) {
            nowBuffering[i] = playBuffer[i];
        }
    }

    var playSource = this.audioCtx.createBufferSource();
    playSource.buffer = myArrayBuffer;
    playSource.connect(this.audioCtx.destination);
    playSource.start();
};

/**
 * Method to generate the new speech recognition model from the training data.
 */
JsSpeechRecognizer.prototype.generateModel = function() {

    // Local vars
    var i = 0;
    var key = "";

    // Reset the model
    this.model = {};

    for (i = 0; i < this.wordBuffer.length; i++) {
        key = this.wordBuffer[i];
        this.model[key] = [];
    }

    for (i = 0; i < this.modelBuffer.length; i++) {
        if (this.modelBuffer[i] !== null) {
            key = this.wordBuffer[i];
            this.model[key].push(this.modelBuffer[i]);
        }
    }

    // Average Model
    // Holds one entry for each key. That entry is the average of all the entries in the model
    this.averageModel = {};
    for (key in this.model) {
        var average = [];
        for (i = 0; i < this.model[key].length; i++) {
            for (var j = 0; j < this.model[key][i].length; j++) {
                average[j] = (average[j] || 0) + (this.model[key][i][j] / this.model[key].length);
            }
        }

        this.averageModel[key] = [];
        this.averageModel[key].push(average);
    }

};

JsSpeechRecognizer.prototype.getTopRecognitionHypotheses = function(numResults) {

    if (this.useRecognitionModel === this.RecognitionModel.AVERAGE) {
        return this.findClosestMatch(this.groupedValues, numResults, this.averageModel);
    } else if (this.useRecognitionModel === this.RecognitionModel.TRAINED) {
        return this.findClosestMatch(this.groupedValues, numResults, this.model);
    } else {
        // For the composite model, combine the trained and average results and sort them
        var results = this.findClosestMatch(this.groupedValues, -1, this.model);
        var resultsAverage = this.findClosestMatch(this.groupedValues, -1, this.averageModel);

        var allResults = results.concat(resultsAverage);
        allResults.sort(function(a, b) { return b.confidence - a.confidence; });

        return allResults.slice(0, numResults);
    }
};

/**
 * Function called to process a new frame of data while in recording state KEYWORD_SPOTTING.
 *  groups - the group data for the frame
 *  curFrame - the raw audio data for the frame
 */
JsSpeechRecognizer.prototype.keywordSpottingProcessFrame = function(groups, curFrame) {

};

// Calculation functions

JsSpeechRecognizer.prototype.findClosestMatch = function(input, numResults, speechModel) {

    var i = 0;
    var key = "";
    var allResults = [];

    // Loop through all the keys in the model
    for (key in speechModel) {
        // Loop through all entries for that key
        for (i = 0; i < speechModel[key].length; i++) {

            var curDistance = this.findDistance(input, speechModel[key][i]);
            var curConfidence = this.calcConfidence(curDistance, speechModel[key][i]);

            var newResult = {};
            newResult.match = key;
            newResult.confidence = curConfidence;
            allResults.push(newResult);
        }

    }

    allResults.sort(function(a, b) { return b.confidence - a.confidence; });

    if (numResults === -1) {
        return allResults;
    }

    return allResults.slice(0, numResults);
};

JsSpeechRecognizer.prototype.findDistance = function(input, check) {
    var i = 0;
    var distance = 0;

    for (i = 0; i < Math.max(input.length, check.length); i++) {
        var checkVal = check[i] || 0;
        var inputVal = input[i] || 0;
        distance += Math.abs(checkVal - inputVal);
    }

    return distance;
};

JsSpeechRecognizer.prototype.calcConfidence = function(distance, matchArray) {
    var sum = 0;
    var i = 0;

    for (i = 0; i < matchArray.length; i++) {
        sum += matchArray[i];
    }

    return (1 - (distance / sum));
};

<|endoftext|>


<commit_before>// ==========================================================================
// Project:   The M-Project - Mobile HTML5 Application Framework
// Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
// Creator:   Sebastian
// Date:      11.11.2010
// License:   Dual licensed under the MIT or GPL Version 2 licenses.
//            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
//            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
// ==========================================================================

m_require('../foundation/object.js');

/* definition of some date specific constants */
M.MILLISECONDS = 'milliseconds';
M.SECONDS = 'seconds';
M.MINUTES = 'minutes';
M.HOURS = 'hours';
M.DAYS = 'days';

/**
 * @class
 *
 * Object for simpler handling of dates.
 */
M.Date = M.Object.extend({

    /**
     * Returns the current date, e.g.
     * Thu Nov 11 2010 14:20:55 GMT+0100 (CET)
     */
    now: function() {
        return new Date();
    },

    /**
     * This method returns the date, 24h in the future.
     */
    tomorrow: function() {
        return this.daysFromNow(1);
    },

    /**
     * This method returns the date, 24h in the past.
     */
    yesterday: function() {
        return this.daysFromNow(-1);
    },

    /**
     * This method returns a date in the future or past, based on 'days'. Basically it adds or
     * subtracts x times the milliseconds of a day, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} days The number of days to be added to or subtracted from the current date.
     */
    daysFromNow: function(days) {
        return this.millisecondsFromNow(days * 24 * 60 * 60 * 1000);
    },

    /**
     * This method returns a date in the future or past, based on 'hours'. Basically it adds or
     * subtracts x times the milliseconds of an hour, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} hours The number of hours to be added to or subtracted from the current date.
     */
    hoursFromNow: function(hours) {
        return this.millisecondsFromNow(hours * 60 * 60 * 1000);
    },

    /**
     * This method returns a date in the future or past, based on 'minutes'. Basically it adds or
     * subtracts x times the milliseconds of a minute, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} minutes The number of minutes to be added to or subtracted from the current date.
     */
    minutesFromNow: function(minutes) {
        return this.millisecondsFromNow(minutes * 60 * 1000);
    },

    /**
     * This method returns a date in the future or past, based on 'seconds'. Basically it adds or
     * subtracts x times the milliseconds of a second, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} seconds The number of seconds to be added to or subtracted from the current date.
     */
    secondsFromNow: function(seconds) {
        return this.millisecondsFromNow(seconds * 1000);
    },

    /**
     * This method returns a date in the future or past, based on 'milliseconds'. Basically it adds or
     * subtracts x milliseconds, but also checks for clock changes and automatically includes these
     * into the calculation of the future or past date.
     *
     * @param {Number} milliseconds The number of milliseconds to be added to or subtracted from the current date.
     */
    millisecondsFromNow: function(milliseconds) {
        var now = this.now();
        var future = new Date(Date.parse(now) + milliseconds);
        return new Date(Date.parse(future) + (future.getTimezoneOffset() - now.getTimezoneOffset()) * (60 * 1000));
    },

    /**
     * This method returns the time between two dates, based on the given returnType.
     *
     * Possible returnTypes are:
     * - M.MILLISECONDS: milliseconds
     * - M.SECONDS: seconds
     * - M.MINUTES: minutes
     * - M.HOURS: hours
     * - M.DAYS: days
     *
     * @param {Object} firstDate The first date.
     * @param {Object} secondDate The second date.
     * @param {String} returnType The return type for the call.
     */
    timeBetween: function(firstDate, secondDate, returnType) {
        var firstDateInMilliseconds = Date.parse(firstDate);
        var secondDateInMilliseconds = Date.parse(secondDate);

        switch (returnType) {
            case M.DAYS:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / (24 * 60 * 60 * 1000);
                break;
            case M.HOURS:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / (60 * 60 * 1000);
                break;
            case M.MINUTES:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / (60 * 1000);
                break;
            case M.SECONDS:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / 1000;
                break;
            case M.MILLISECONDS:
            default:
                return (secondDateInMilliseconds - firstDateInMilliseconds);
                break;
        }
    }

});<commit_msg>Added a create method for creating a new JS Date object from a given dateString<commit_after>// ==========================================================================
// Project:   The M-Project - Mobile HTML5 Application Framework
// Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
// Creator:   Sebastian
// Date:      11.11.2010
// License:   Dual licensed under the MIT or GPL Version 2 licenses.
//            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
//            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
// ==========================================================================

m_require('../foundation/object.js');

/* definition of some date specific constants */
M.MILLISECONDS = 'milliseconds';
M.SECONDS = 'seconds';
M.MINUTES = 'minutes';
M.HOURS = 'hours';
M.DAYS = 'days';

/**
 * @class
 *
 * Object for simpler handling of dates.
 */
M.Date = M.Object.extend({

    /**
     * Returns the current date, e.g.
     * Thu Nov 11 2010 14:20:55 GMT+0100 (CET)
     */
    now: function() {
        return new Date();
    },

    /**
     * This method returns the date, 24h in the future.
     */
    tomorrow: function() {
        return this.daysFromNow(1);
    },

    /**
     * This method returns a date for a given date string. It is based on JS Date's parse
     * method.
     *
     * The following formats are accepted (time and timezone are optional):
     * - 11/12/2010
     * - 11/12/2010 15:28:15
     * - 11/12/2010 13:28:15 GMT
     * - 11/12/2010 15:28:15 GMT+0200
     * - 12 November 2010
     * - 12 November 2010 15:28:15
     * - 12 November 2010 13:28:15 GMT
     * - 12 November 2010 15:28:15 GMT+0200
     * - 12 Nov 2010
     * - 12 Nov 2010 15:28:15
     * - 12 Nov 2010 13:28:15 GMT
     * - 12 Nov 2010 15:28:15 GMT+0200
     *
     * If a wrong formatted date string is given, the method will return null. Otherwise a
     * JS Date object will be returned.
     */
    create: function(dateString) {
        var milliseconds = Date.parse(dateString);
        if(!milliseconds) {
            M.Logger.log('Invalid dateString \'' + dateString + '\'.', M.WARN);
            return null;
        }
        return new Date(milliseconds);
    },

    /**
     * This method returns the date, 24h in the past.
     */
    yesterday: function() {
        return this.daysFromNow(-1);
    },

    /**
     * This method returns a date in the future or past, based on 'days'. Basically it adds or
     * subtracts x times the milliseconds of a day, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} days The number of days to be added to or subtracted from the current date.
     */
    daysFromNow: function(days) {
        return this.daysFromDate(days, this.now());
    },

    /**
     * This method returns a date in the future or past, based on 'days' and a given date. Basically
     * it adds or subtracts x days, but also checks for clock changes and automatically includes
     * these into the calculation of the future or past date.
     *
     * @param {Number} days The number of days to be added to or subtracted from the current date.
     * @param {Object} inputDate The input date as a date object.
     */
    daysFromDate: function(days, inputDate) {
        return this.millisecondsFromDate(days * 24 * 60 * 60 * 1000, inputDate);
    },

    /**
     * This method returns a date in the future or past, based on 'hours'. Basically it adds or
     * subtracts x times the milliseconds of an hour, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} hours The number of hours to be added to or subtracted from the current date.
     */
    hoursFromNow: function(hours) {
        return this.hoursFromDate(hours, this.now());
    },

    /**
     * This method returns a date in the future or past, based on 'hours' and a given date. Basically
     * it adds or subtracts x hours, but also checks for clock changes and automatically includes
     * these into the calculation of the future or past date.
     *
     * @param {Number} hours The number of hours to be added to or subtracted from the current date.
     * @param {Object} inputDate The input date as a date object.
     */
    hoursFromDate: function(hours, inputDate) {
        return this.millisecondsFromDate(hours * 60 * 60 * 1000, inputDate);
    },

    /**
     * This method returns a date in the future or past, based on 'minutes'. Basically it adds or
     * subtracts x times the milliseconds of a minute, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} minutes The number of minutes to be added to or subtracted from the current date.
     */
    minutesFromNow: function(minutes) {
        return this.minutesFromDate(minutes, this.now());
    },

    /**
     * This method returns a date in the future or past, based on 'minutes' and a given date. Basically
     * it adds or subtracts x minutes, but also checks for clock changes and automatically includes
     * these into the calculation of the future or past date.
     *
     * @param {Number} minutes The number of minutes to be added to or subtracted from the current date.
     * @param {Object} inputDate The input date as a date object.
     */
    minutesFromDate: function(minutes, inputDate) {
        return this.millisecondsFromDate(minutes * 60 * 1000, inputDate);
    },

    /**
     * This method returns a date in the future or past, based on 'seconds'. Basically it adds or
     * subtracts x times the milliseconds of a second, but also checks for clock changes and
     * automatically includes these into the calculation of the future or past date.
     *
     * @param {Number} seconds The number of seconds to be added to or subtracted from the current date.
     */
    secondsFromNow: function(seconds) {
        return this.secondsFromDate(seconds, this.now());
    },

    /**
     * This method returns a date in the future or past, based on 'seconds' and a given date. Basically
     * it adds or subtracts x seconds, but also checks for clock changes and automatically includes
     * these into the calculation of the future or past date.
     *
     * @param {Number} seconds The number of seconds to be added to or subtracted from the current date.
     * @param {Object} inputDate The input date as a date object.
     */
    secondsFromDate: function(seconds, inputDate) {
        return this.millisecondsFromDate(seconds * 1000, inputDate);
    },

    /**
     * This method returns a date in the future or past, based on 'milliseconds'. Basically it adds or
     * subtracts x milliseconds, but also checks for clock changes and automatically includes these
     * into the calculation of the future or past date.
     *
     * @param {Number} milliseconds The number of milliseconds to be added to or subtracted from the current date.
     */
    millisecondsFromNow: function(milliseconds) {
        return this.millisecondsFromDate(milliseconds, this.now());
    },

    /**
     * This method returns a date in the future or past, based on 'milliseconds' and a given date. Basically
     * it adds or subtracts x milliseconds, but also checks for clock changes and automatically includes
     * these into the calculation of the future or past date.
     *
     * @param {Number} milliseconds The number of milliseconds to be added to or subtracted from the current date.
     * @param {Object} inputDate The input date as a date object.
     */
    millisecondsFromDate: function(milliseconds, inputDate) {
        var outputDate = new Date(Date.parse(inputDate) + milliseconds);
        return new Date(Date.parse(outputDate) + (outputDate.getTimezoneOffset() - inputDate.getTimezoneOffset()) * (60 * 1000));
    },

    /**
     * This method returns the time between two dates, based on the given returnType.
     *
     * Possible returnTypes are:
     * - M.MILLISECONDS: milliseconds
     * - M.SECONDS: seconds
     * - M.MINUTES: minutes
     * - M.HOURS: hours
     * - M.DAYS: days
     *
     * @param {Object} firstDate The first date.
     * @param {Object} secondDate The second date.
     * @param {String} returnType The return type for the call.
     */
    timeBetween: function(firstDate, secondDate, returnType) {
        var firstDateInMilliseconds = Date.parse(firstDate);
        var secondDateInMilliseconds = Date.parse(secondDate);

        switch (returnType) {
            case M.DAYS:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / (24 * 60 * 60 * 1000);
                break;
            case M.HOURS:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / (60 * 60 * 1000);
                break;
            case M.MINUTES:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / (60 * 1000);
                break;
            case M.SECONDS:
                return (secondDateInMilliseconds - firstDateInMilliseconds) / 1000;
                break;
            case M.MILLISECONDS:
            default:
                return (secondDateInMilliseconds - firstDateInMilliseconds);
                break;
        }
    }

});<|endoftext|>


<commit_before>Kwf.onContentReady(function(el, param) {
    if (!param.newRender) return false;
    Ext.select('.kwcForm > form', true, el).each(function(form) {
        form = form.parent('.kwcForm', false);
        if (!form.kwcForm) {
            form.kwcForm = new Kwc.Form.Component(form);
        }
    });
});
Ext.ns('Kwc.Form');
Kwc.Form.findForm = function(el) {
    var formEl = el.child('.kwcForm > form');
    if (formEl) {
        formEl = formEl.parent('.kwcForm');
        return formEl.kwcForm;
    }
    return null;
};
Kwc.Form.formsByComponentId = {};

Kwc.Form.Component = function(form)
{
    this.addEvents('submitSuccess', 'fieldChange');
    this.el = form;
    var config = form.parent().down('.config', true);
    if (!config) return;
    config = Ext.decode(config.value);
    if (!config) return;
    this.config = config;

    Kwc.Form.formsByComponentId[this.config.componentId] = this;

    this.fields = [];
    form.select('.kwfField', true).each(function(fieldEl) {
        var classes = fieldEl.dom.className.split(' ');
        var fieldConstructor = false;
        classes.each(function (c) {
            if (Kwf.FrontendForm.fields[c]) {
                fieldConstructor = Kwf.FrontendForm.fields[c];
            }
        }, this);
        if (fieldConstructor) {
            var field = new fieldConstructor(fieldEl, this);
            this.fields.push(field);
        }
    }, this);

    if (this.config.hideForValue) {
        this.config.hideForValue.each(function(hideForValue) {
            var field = this.findField(hideForValue.field);
            field.on('change', function(v, f) {
                if (v == hideForValue.value) {
                    this.findField(hideForValue.hide).hide();
                } else {
                    this.findField(hideForValue.hide).show();
                }
            }, this);

            //initialize on startup
            if (field.getValue() == hideForValue.value) {
                this.findField(hideForValue.hide).hide();
            }
        }, this);
    }

    if (this.config.useAjaxRequest) {
        var button = form.child('form button.submit');
        if (button) {
            button.on('click', this.onSubmit, this);
        }
    }

    this.fields.forEach(function(f) {
        f.on('change', function() {
            this.fireEvent('fieldChange', f);
        }, this);
    }, this);

    this.errorStyle = new Kwf.FrontendForm.errorStyles[this.config.errorStyle](this);
};
Ext.extend(Kwc.Form.Component, Ext.util.Observable, {
    getFieldConfig: function(fieldName)
    {
        if (this.config.fieldConfig[fieldName]) {
            return this.config.fieldConfig[fieldName];
        }
        return {};
    },
    findField: function(fieldName) {
        var ret = null;
        this.fields.each(function(f) {
            if (f.getFieldName() == fieldName) {
                ret = f;
                return true;
            }
        }, this);
        return ret;
    },
    getValues: function() {
        var ret = {};
        this.fields.each(function(f) {
            ret[f.getFieldName()] = f.getValue();
        }, this);
        return ret;
    },
    clearValues: function() {
        this.fields.each(function(f) {
            f.clearValue();
        }, this);
    },
    hideSubmit: function() {
        this.el.child('.submitWrapper').enableDisplayMode();
        this.el.child('.submitWrapper').hide();
    },
    onSubmit: function(e) {
        if (this.dontUseAjaxRequest) return;

        var button = this.el.child('.submitWrapper .button');
        button.down('.saving').show();
        button.down('.submit').hide();

        this.errorStyle.hideErrors();

        Ext.Ajax.request({
            url: this.config.controllerUrl + '/json-save',
            ignoreErrors: true,
            params: {
                componentId: this.config.componentId
            },
            form: this.el.down('form'),
            failure: function() {
                //on failure try a plain old post of the form
                this.dontUseAjaxRequest = true; //avoid endless recursion
                button.down('.submit').dom.click();
            },
            success: function(response, options, r) {

                this.errorStyle.showErrors({
                    errorFields: r.errorFields,
                    errorMessages: r.errorMessages,
                    errorPlaceholder: r.errorPlaceholder
                });

                var hasErrors = false;
                if (r.errorMessages && r.errorMessages.length) {
                    hasErrors = true;
                }
                for(var fieldName in r.errorFields) {
                    hasErrors = true;
                }

                if (!r.successUrl) {
                    button.down('.saving').hide();
                    button.down('.submit').show();
                }

                // show success content
                if (r.successContent) {
                    var el = this.el.parent().createChild(r.successContent);
                    if (this.config.hideFormOnSuccess) {
                        this.el.remove();
                    } else {
                        (function(el) {
                            el.remove();
                            Kwf.callOnContentReady(this.el.dom);
                        }).defer(5000, this, [el]);
                    }
                    if(el) Kwf.callOnContentReady(el.dom, {newRender: true});
                } else if (r.successUrl) {
                    document.location.href = r.successUrl;
                }

                if (!hasErrors) {
                    this.fireEvent('submitSuccess', this, r);
                }
            },
            scope: this
        });

        e.stopEvent();
    }
});
<commit_msg>remove unused method<commit_after>Kwf.onContentReady(function(el, param) {
    if (!param.newRender) return false;
    Ext.select('.kwcForm > form', true, el).each(function(form) {
        form = form.parent('.kwcForm', false);
        if (!form.kwcForm) {
            form.kwcForm = new Kwc.Form.Component(form);
        }
    });
});
Ext.ns('Kwc.Form');
Kwc.Form.findForm = function(el) {
    var formEl = el.child('.kwcForm > form');
    if (formEl) {
        formEl = formEl.parent('.kwcForm');
        return formEl.kwcForm;
    }
    return null;
};
Kwc.Form.formsByComponentId = {};

Kwc.Form.Component = function(form)
{
    this.addEvents('submitSuccess', 'fieldChange');
    this.el = form;
    var config = form.parent().down('.config', true);
    if (!config) return;
    config = Ext.decode(config.value);
    if (!config) return;
    this.config = config;

    Kwc.Form.formsByComponentId[this.config.componentId] = this;

    this.fields = [];
    form.select('.kwfField', true).each(function(fieldEl) {
        var classes = fieldEl.dom.className.split(' ');
        var fieldConstructor = false;
        classes.each(function (c) {
            if (Kwf.FrontendForm.fields[c]) {
                fieldConstructor = Kwf.FrontendForm.fields[c];
            }
        }, this);
        if (fieldConstructor) {
            var field = new fieldConstructor(fieldEl, this);
            this.fields.push(field);
        }
    }, this);

    if (this.config.hideForValue) {
        this.config.hideForValue.each(function(hideForValue) {
            var field = this.findField(hideForValue.field);
            field.on('change', function(v, f) {
                if (v == hideForValue.value) {
                    this.findField(hideForValue.hide).hide();
                } else {
                    this.findField(hideForValue.hide).show();
                }
            }, this);

            //initialize on startup
            if (field.getValue() == hideForValue.value) {
                this.findField(hideForValue.hide).hide();
            }
        }, this);
    }

    if (this.config.useAjaxRequest) {
        var button = form.child('form button.submit');
        if (button) {
            button.on('click', this.onSubmit, this);
        }
    }

    this.fields.forEach(function(f) {
        f.on('change', function() {
            this.fireEvent('fieldChange', f);
        }, this);
    }, this);

    this.errorStyle = new Kwf.FrontendForm.errorStyles[this.config.errorStyle](this);
};
Ext.extend(Kwc.Form.Component, Ext.util.Observable, {
    getFieldConfig: function(fieldName)
    {
        if (this.config.fieldConfig[fieldName]) {
            return this.config.fieldConfig[fieldName];
        }
        return {};
    },
    findField: function(fieldName) {
        var ret = null;
        this.fields.each(function(f) {
            if (f.getFieldName() == fieldName) {
                ret = f;
                return true;
            }
        }, this);
        return ret;
    },
    getValues: function() {
        var ret = {};
        this.fields.each(function(f) {
            ret[f.getFieldName()] = f.getValue();
        }, this);
        return ret;
    },
    clearValues: function() {
        this.fields.each(function(f) {
            f.clearValue();
        }, this);
    },
    onSubmit: function(e) {
        if (this.dontUseAjaxRequest) return;

        var button = this.el.child('.submitWrapper .button');
        button.down('.saving').show();
        button.down('.submit').hide();

        this.errorStyle.hideErrors();

        Ext.Ajax.request({
            url: this.config.controllerUrl + '/json-save',
            ignoreErrors: true,
            params: {
                componentId: this.config.componentId
            },
            form: this.el.down('form'),
            failure: function() {
                //on failure try a plain old post of the form
                this.dontUseAjaxRequest = true; //avoid endless recursion
                button.down('.submit').dom.click();
            },
            success: function(response, options, r) {

                this.errorStyle.showErrors({
                    errorFields: r.errorFields,
                    errorMessages: r.errorMessages,
                    errorPlaceholder: r.errorPlaceholder
                });

                var hasErrors = false;
                if (r.errorMessages && r.errorMessages.length) {
                    hasErrors = true;
                }
                for(var fieldName in r.errorFields) {
                    hasErrors = true;
                }

                if (!r.successUrl) {
                    button.down('.saving').hide();
                    button.down('.submit').show();
                }

                // show success content
                if (r.successContent) {
                    var el = this.el.parent().createChild(r.successContent);
                    if (this.config.hideFormOnSuccess) {
                        this.el.remove();
                    } else {
                        (function(el) {
                            el.remove();
                            Kwf.callOnContentReady(this.el.dom);
                        }).defer(5000, this, [el]);
                    }
                    if(el) Kwf.callOnContentReady(el.dom, {newRender: true});
                } else if (r.successUrl) {
                    document.location.href = r.successUrl;
                }

                if (!hasErrors) {
                    this.fireEvent('submitSuccess', this, r);
                }
            },
            scope: this
        });

        e.stopEvent();
    }
});
<|endoftext|>


<commit_before>const util = require('util');

const TreeFamily = require('../models/TreeFamily').Model;
const Tree = require('../models/Tree').Model;

function findAnswerConsequencesPieces(node, treeFamilyPieces) {
  if ('answerConsequences' in node && node.answerConsequences.length !== 0) {
    node.answerConsequences.forEach((answerConsequence) => {
      treeFamilyPieces.push(answerConsequence);
    });
  }
}

function findWholeNodesPieces(node, treeFamilyPieces, crossReferences) {
  if (crossReferences.indexOf(String(node._id)) !== -1) {
    return;
  }
  console.log(String(node._id), 'passed');
  treeFamilyPieces.push(node);
  findAnswerConsequencesPieces(node, treeFamilyPieces);
  if ('branches' in node) {
    node.branches.forEach((branchNode) => {
      findWholeNodesPieces(branchNode, treeFamilyPieces, crossReferences);
    });
  }
}

function findWholeTreePieces(tree, treeFamilyPieces, crossReferences) {
  treeFamilyPieces.push(tree);
  tree.root.forEach((rootNode) => {
    findWholeNodesPieces(rootNode, treeFamilyPieces, crossReferences);
  });
}

function removeAllTreePieces(treePieces) {
  return new Promise((fulfill, reject) => {
    for (const index in treePieces) {
      const piece = treePieces[index];

      piece.remove().then(() => {
        if (Number(index) === treePieces.length - 1) {
          fulfill();
        }
      }).catch((error) => {
        reject(error);
      });
    }
  });
}

function retrieveWholeFamily(id) {
  return new Promise((fulfill, reject) => {
    TreeFamily.findById(id).then((treeFamily) => {
      if (!treeFamily) {
        reject(`Tree family id ${id} not found`);
      }
      fulfill(treeFamily);
    }).catch((error) => {
      reject(error);
    });
  });
}

function removeTree(id) {
  return new Promise((fulfill, reject) => {
    Tree.findById(id).then((tree) => {
      if (!tree) {
        reject(`Tree id ${id} not found`);
      }
      console.log(util.format('%s', util.inspect(tree, { depth: Infinity })));
      console.log();
      retrieveWholeFamily(tree.familyId).then((family) => {
        const allReferences = [];
        const treePiecesToDelete = [];
        let treeIndex = 0;
        for (; treeIndex !== family.trees.length; treeIndex += 1) {
          if (String(family.trees[treeIndex]._id) === id) {
            break;
          }
        }
        if (treeIndex >= family.trees.length || String(family.trees[treeIndex]._id) !== id) {
          reject(`Tree id ${id} not found inside family id ${family._id}`);
        }
        family.references.forEach((treeReferences) => {
          allReferences.push(...treeReferences);
        });
        for (let i = 0; i !== allReferences.length; i += 1) {
          allReferences[i] = String(allReferences[i]);
        }
        findWholeTreePieces(tree, treePiecesToDelete, allReferences);
        console.log(allReferences);
        console.log();
        console.log(treePiecesToDelete);
        console.log();
        removeAllTreePieces(treePiecesToDelete).then(() => {
          family.trees.splice(treeIndex, 1);
          family.references.splice(treeIndex, 1);
          family.save().then(() => {
            fulfill();
          }).catch((error) => {
            console.log(error);
            reject(error);
          });
        }).catch((error) => {
          console.log(error);
          reject(error);
        });
      }).catch((error) => {
        console.log(error);
        reject(error);
      });
      fulfill();
    }).catch((error) => {
      console.log(error);
      reject(error);
    });
  });
}

module.exports.removeFromId = removeTree;
<commit_msg>htest-server : Remove debug prints from treeRemover<commit_after>const TreeFamily = require('../models/TreeFamily').Model;
const Tree = require('../models/Tree').Model;

function findAnswerConsequencesPieces(node, treeFamilyPieces) {
  if ('answerConsequences' in node && node.answerConsequences.length !== 0) {
    node.answerConsequences.forEach((answerConsequence) => {
      treeFamilyPieces.push(answerConsequence);
    });
  }
}

function findWholeNodesPieces(node, treeFamilyPieces, crossReferences) {
  if (crossReferences.indexOf(String(node._id)) !== -1) {
    return;
  }
  treeFamilyPieces.push(node);
  findAnswerConsequencesPieces(node, treeFamilyPieces);
  if ('branches' in node) {
    node.branches.forEach((branchNode) => {
      findWholeNodesPieces(branchNode, treeFamilyPieces, crossReferences);
    });
  }
}

function findWholeTreePieces(tree, treeFamilyPieces, crossReferences) {
  treeFamilyPieces.push(tree);
  tree.root.forEach((rootNode) => {
    findWholeNodesPieces(rootNode, treeFamilyPieces, crossReferences);
  });
}

function removeAllTreePieces(treePieces) {
  return new Promise((fulfill, reject) => {
    for (const index in treePieces) {
      const piece = treePieces[index];

      piece.remove().then(() => {
        if (Number(index) === treePieces.length - 1) {
          fulfill();
        }
      }).catch((error) => {
        reject(error);
      });
    }
  });
}

function retrieveWholeFamily(id) {
  return new Promise((fulfill, reject) => {
    TreeFamily.findById(id).then((treeFamily) => {
      if (!treeFamily) {
        reject(`Tree family id ${id} not found`);
      }
      fulfill(treeFamily);
    }).catch((error) => {
      reject(error);
    });
  });
}

function removeTree(id) {
  return new Promise((fulfill, reject) => {
    Tree.findById(id).then((tree) => {
      if (!tree) {
        reject(`Tree id ${id} not found`);
      }
      retrieveWholeFamily(tree.familyId).then((family) => {
        const allReferences = [];
        const treePiecesToDelete = [];
        let treeIndex = 0;
        for (; treeIndex !== family.trees.length; treeIndex += 1) {
          if (String(family.trees[treeIndex]._id) === id) {
            break;
          }
        }
        if (treeIndex >= family.trees.length || String(family.trees[treeIndex]._id) !== id) {
          reject(`Tree id ${id} not found inside family id ${family._id}`);
        }
        family.references.forEach((treeReferences) => {
          allReferences.push(...treeReferences);
        });
        for (let i = 0; i !== allReferences.length; i += 1) {
          allReferences[i] = String(allReferences[i]);
        }
        findWholeTreePieces(tree, treePiecesToDelete, allReferences);
        removeAllTreePieces(treePiecesToDelete).then(() => {
          family.trees.splice(treeIndex, 1);
          family.references.splice(treeIndex, 1);
          family.save().then(() => {
            fulfill();
          }).catch((error) => {
            reject(error);
          });
        }).catch((error) => {
          reject(error);
        });
      }).catch((error) => {
        reject(error);
      });
      fulfill();
    }).catch((error) => {
      reject(error);
    });
  });
}

module.exports.removeFromId = removeTree;
<|endoftext|>


<commit_before>/* global describe it expect */
'use strict'

describe('PlantumlPreviewView', function () {
  return it('has one valid test', function () {
    return expect('life').toBe('easy')
  })
})
<commit_msg>Fix failing test<commit_after>/* global describe it expect */
'use strict'

describe('PlantumlPreviewView', function () {
  return it('has one valid test', function () {
    return expect('life').toBe('life')
  })
})
<|endoftext|>


<commit_before><commit_msg>GParamSpec: fix typo<commit_after><|endoftext|>