<commit_before>import _ from "underscore";
import Immutable from "immutable";
import Minify from "../minify";

/**
 * Obtains a property from a minified topic tree node
 */
const getMinifiedPropFromNode = (topicTreeNode, prop) =>
    topicTreeNode.get(Minify.getShortName(prop));

/**
 * Do something to {forEach: fn} child element
 * @param fn A string function like "map", "forEach", etc.
 * @param kinds An array of kinds to be filtered on
 * @param topicTreeNode The topic to filter on
 * @param callback The function that should be called for {forEach: fn} filtered child
 */
const fnChildrenByKind = (fn) => (kinds) => {
    return (topicTreeNode, callback) => {
        return getMinifiedPropFromNode(topicTreeNode, "children").filter((child) =>
            _.includes(kinds, getMinifiedPropFromNode(child, "kind"))
        )[fn](callback);
    };
};

export const mapChildrenByKind = fnChildrenByKind("map");
export const eachChildrenByKind = fnChildrenByKind("forEach");

export const topicKind = [Minify.getShortValue("kind", "Topic")];
export const contentKinds = [Minify.getShortValue("kind", "Video"),
    Minify.getShortValue("kind", "Article"),
    Minify.getShortValue("kind", "Exercise")];

export const eachChildTopicNode = eachChildrenByKind(topicKind);
export const mapChildTopicNodes = mapChildrenByKind(topicKind);
export const eachChildContentNode = eachChildrenByKind(contentKinds);
export const mapChildContentNodes = mapChildrenByKind(contentKinds);

export const getTitle = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "translated_title") ||
    getMinifiedPropFromNode(topicTreeNode, "translated_display_name");

export const getProgressKey = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "progress_key");

export const getKind = (topicTreeNode) =>
    Minify.getLongValue("kind", getMinifiedPropFromNode(topicTreeNode, "kind"));

const genIsKindFn = (kind) =>
    (topicTreeNode) =>
        getKind(topicTreeNode) === kind;

export const isTopic = genIsKindFn("Topic");
export const isVideo = genIsKindFn("Video");
export const isArticle = genIsKindFn("Article");
export const isExercise = genIsKindFn("Exercise");

const genCheckAnyFn = (...validators) =>
    (topicTreeNode) =>
        _.any(validators, (validator) => validator(topicTreeNode));

export const isContent = genCheckAnyFn(isVideo, isArticle, isExercise);
export const isContentList = () => false;

export const getId = (topicTreeNode) => {
    if (isExercise(topicTreeNode)) {
        return getProgressKey(topicTreeNode).substring(1);
    }
    return getMinifiedPropFromNode(topicTreeNode, "id");
};

// todo: It's probably better to store this out of the topic tree
export const getDownloadCount = (topicTreeNode) =>
    topicTreeNode.get("downloadCount") === 0;

export const getSlug = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "slug");

export const getKey = (topicTreeNode) => {
    return getId(topicTreeNode) || getSlug(topicTreeNode) || getTitle(topicTreeNode);
};

export const getKAUrl = (topicTreeNode) => {
    var value = getMinifiedPropFromNode(topicTreeNode, "ka_url");
    if (!value) {
        return null;
    }
    if (value.substring(0, 4) !== "http") {
        value = "http://www.khanacademy.org/video/" + value;
    }
    return value;
};

export const isDownloaded = (topicTreeNode) =>
    !!topicTreeNode.get("downloaded");

export const isStarted = (topicTreeNode) =>
    topicTreeNode.get("started");

export const isCompleted = (topicTreeNode) =>
    topicTreeNode.get("completed");

export const getYoutubeId = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "youtube_id");

export const getDuration = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "duration");

export const getPoints = (topicTreeNode) =>
    topicTreeNode.get("points") || 0;

export const getContentMimeType = (topicTreeNode) =>
    isVideo(topicTreeNode) ? "video/mp4" : "text/html";

export const getDownloadUrl = (topicTreeNode) => {
    var value = getMinifiedPropFromNode(topicTreeNode, "download_urls");
    if (!value) {
        return null;
    }
    if (value.substring(0, 4) !== "http") {
        value = "http://fastly.kastatic.org/KA-youtube-converted/" + value + ".mp4";
    }
    return value;
};

export const getName = (topicTreeNode)  =>
    getMinifiedPropFromNode(topicTreeNode, "name");

export const isPerseusExercise = (topicTreeNode) =>
    !getMinifiedPropFromNode(topicTreeNode, "file_name");

export const isKhanExercisesExercise = (topicTreeNode) =>
    !!getMinifiedPropFromNode(topicTreeNode, "file_name");

export const getFilename = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "file_name");

// TODO: remove all dependencies on this and remove this
export const getParentDomain = (topicTreeNode) => {
    return null;
};

/**
 * Initiates a recursive search for the term `search`
 */
export const findContentItems = (topicTreeNode, search, maxResults) => {
    if (_.isUndefined(maxResults)) {
        maxResults = 40;
    }

    var results = [];
    _findContentItems(topicTreeNode, search.toLowerCase(), results, maxResults);
    return Immutable.fromJS(results.slice(0, maxResults));
};

/**
 * Recursively calls _findContentItems on all children and adds videos and articles with
 * a matching title to the results array.
 */
const _findContentItems = (topicTreeNode, search, results, maxResults) => {
    if (results.length > maxResults) {
        return;
    }

    eachChildContentNode(topicTreeNode, (childNode) => {
        // TODO: Possibly search descriptions too?
        // TODO: We could potentially index the transcripts for a really good search
        // TODO: Tokenize the `search` string and do an indexOf for each token
        // TODO: Allow for OR/AND search term strings
        if (getTitle(childNode) &&
                getTitle(childNode).toLowerCase().indexOf(search) !== -1) {
            results.push(childNode);
        }
    });

    eachChildTopicNode(topicTreeNode, (childNode) => {
        _findContentItems(childNode, search, results, maxResults);
    });
};
<commit_msg>Make searching by ID easier mostly for debugging<commit_after>import _ from "underscore";
import Immutable from "immutable";
import Minify from "../minify";

/**
 * Obtains a property from a minified topic tree node
 */
const getMinifiedPropFromNode = (topicTreeNode, prop) =>
    topicTreeNode.get(Minify.getShortName(prop));

/**
 * Do something to {forEach: fn} child element
 * @param fn A string function like "map", "forEach", etc.
 * @param kinds An array of kinds to be filtered on
 * @param topicTreeNode The topic to filter on
 * @param callback The function that should be called for {forEach: fn} filtered child
 */
const fnChildrenByKind = (fn) => (kinds) => {
    return (topicTreeNode, callback) => {
        return getMinifiedPropFromNode(topicTreeNode, "children").filter((child) =>
            _.includes(kinds, getMinifiedPropFromNode(child, "kind"))
        )[fn](callback);
    };
};

export const mapChildrenByKind = fnChildrenByKind("map");
export const eachChildrenByKind = fnChildrenByKind("forEach");

export const topicKind = [Minify.getShortValue("kind", "Topic")];
export const contentKinds = [Minify.getShortValue("kind", "Video"),
    Minify.getShortValue("kind", "Article"),
    Minify.getShortValue("kind", "Exercise")];

export const eachChildTopicNode = eachChildrenByKind(topicKind);
export const mapChildTopicNodes = mapChildrenByKind(topicKind);
export const eachChildContentNode = eachChildrenByKind(contentKinds);
export const mapChildContentNodes = mapChildrenByKind(contentKinds);

export const getTitle = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "translated_title") ||
    getMinifiedPropFromNode(topicTreeNode, "translated_display_name");

export const getProgressKey = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "progress_key");

export const getKind = (topicTreeNode) =>
    Minify.getLongValue("kind", getMinifiedPropFromNode(topicTreeNode, "kind"));

const genIsKindFn = (kind) =>
    (topicTreeNode) =>
        getKind(topicTreeNode) === kind;

export const isTopic = genIsKindFn("Topic");
export const isVideo = genIsKindFn("Video");
export const isArticle = genIsKindFn("Article");
export const isExercise = genIsKindFn("Exercise");

const genCheckAnyFn = (...validators) =>
    (topicTreeNode) =>
        _.any(validators, (validator) => validator(topicTreeNode));

export const isContent = genCheckAnyFn(isVideo, isArticle, isExercise);
export const isContentList = () => false;

export const getId = (topicTreeNode) => {
    if (isExercise(topicTreeNode)) {
        return getProgressKey(topicTreeNode).substring(1);
    }
    return getMinifiedPropFromNode(topicTreeNode, "id");
};

// todo: It's probably better to store this out of the topic tree
export const getDownloadCount = (topicTreeNode) =>
    topicTreeNode.get("downloadCount") === 0;

export const getSlug = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "slug");

export const getKey = (topicTreeNode) => {
    return getId(topicTreeNode) || getSlug(topicTreeNode) || getTitle(topicTreeNode);
};

export const getKAUrl = (topicTreeNode) => {
    var value = getMinifiedPropFromNode(topicTreeNode, "ka_url");
    if (!value) {
        return null;
    }
    if (value.substring(0, 4) !== "http") {
        value = "http://www.khanacademy.org/video/" + value;
    }
    return value;
};

export const isDownloaded = (topicTreeNode) =>
    !!topicTreeNode.get("downloaded");

export const isStarted = (topicTreeNode) =>
    topicTreeNode.get("started");

export const isCompleted = (topicTreeNode) =>
    topicTreeNode.get("completed");

export const getYoutubeId = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "youtube_id");

export const getDuration = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "duration");

export const getPoints = (topicTreeNode) =>
    topicTreeNode.get("points") || 0;

export const getContentMimeType = (topicTreeNode) =>
    isVideo(topicTreeNode) ? "video/mp4" : "text/html";

export const getDownloadUrl = (topicTreeNode) => {
    var value = getMinifiedPropFromNode(topicTreeNode, "download_urls");
    if (!value) {
        return null;
    }
    if (value.substring(0, 4) !== "http") {
        value = "http://fastly.kastatic.org/KA-youtube-converted/" + value + ".mp4";
    }
    return value;
};

export const getName = (topicTreeNode)  =>
    getMinifiedPropFromNode(topicTreeNode, "name");

export const isPerseusExercise = (topicTreeNode) =>
    !getMinifiedPropFromNode(topicTreeNode, "file_name");

export const isKhanExercisesExercise = (topicTreeNode) =>
    !!getMinifiedPropFromNode(topicTreeNode, "file_name");

export const getFilename = (topicTreeNode) =>
    getMinifiedPropFromNode(topicTreeNode, "file_name");

// TODO: remove all dependencies on this and remove this
export const getParentDomain = (topicTreeNode) => {
    return null;
};

/**
 * Initiates a recursive search for the term `search`
 */
export const findContentItems = (topicTreeNode, search, maxResults) => {
    if (_.isUndefined(maxResults)) {
        maxResults = 40;
    }

    var results = [];
    _findContentItems(topicTreeNode, search.toLowerCase(), results, maxResults);
    return Immutable.fromJS(results.slice(0, maxResults));
};

/**
 * Recursively calls _findContentItems on all children and adds videos and articles with
 * a matching title to the results array.
 */
const _findContentItems = (topicTreeNode, search, results, maxResults) => {
    if (results.length > maxResults) {
        return;
    }

    eachChildContentNode(topicTreeNode, (childNode) => {
        // TODO: Possibly search descriptions too?
        // TODO: We could potentially index the transcripts for a really good search
        // TODO: Tokenize the `search` string and do an indexOf for each token
        // TODO: Allow for OR/AND search term strings
        if (getTitle(childNode) &&
                getTitle(childNode).toLowerCase().indexOf(search) !== -1 ||
                getId(childNode).indexOf(search) !== -1) {
            results.push(childNode);
        }
    });

    eachChildTopicNode(topicTreeNode, (childNode) => {
        _findContentItems(childNode, search, results, maxResults);
    });
};
<|endoftext|>


<commit_before>var obj_canvas,
obj_c,
cp_canvas = null;

var canvas
var video_canvas,
vid_c;

var brown_const=0;

var vid_width = 640;
var vid_height = 480;
var n_object = 20;
var m_object = 5;

var canvas;
var context;

function setupD3(){
	var w = 640,
    	h = 480,
    	n = 20,
    	m = 12,
    	l = 80,
    	degrees = 180 / Math.PI;

	var objects = d3.range(n).map(function() {
  		var x = Math.random() * w, y = Math.random() * h;
  		var active = true;
  		var radius = 50;
  		return {
    		vx: Math.random() * 2 - 1,
    		vy: Math.random() * 2 - 1,
    		path: d3.range(m).map(function() { return [x, y]; }),
    		count: 0
  		};
	});

	var svg = d3.select("#canvasArea").append("svg:svg")
    	.attr("width", vid_width)
    	.attr("height", vid_height);

	var image = svg.append("image")
    	.attr("xlink:href", "http://171.65.102.132:8080/?action=snapshot?t=" + new Date().getTime())
    	.attr("width", vid_width)
    	.attr("height", vid_height);

	var g = svg.selectAll("g")
    	.data(objects)
		.enter().append("svg:g");

	var box = g.append("svg:rect")
    	.attr("width", l)
    	.attr("height", l);

	function getVideo(){
		var frameURL = "http://171.65.102.132:8080/?action=snapshot?t=" + new Date().getTime();
		//var svg = d3.select('svg');
		image.attr('onload', function() {
         		compareFrame(image);
    		})
    		.attr("xlink:href", frameURL)
    		.attr("width", vid_width)
    		.attr("height", vid_height);
	}

	function drawObjects(){
		for (var i = -1; ++i < n;) {
    		var object = objects[i],
        		path = object.path,
        		dx = object.vx,
        		dy = object.vy,
        		x = path[0][0] += dx,
        		y = path[0][1] += dy,
        		speed = Math.sqrt(dx * dx + dy * dy),
        		count = speed * 10,
        		k1 = -5 - speed / 3;

    		// Bounce off the walls.
    		if (x < 0 || x > w) object.vx *= -1;
    		if (y < 0 || y > h) object.vy *= -1;

    		// Swim!
    		for (var j = 0; ++j < m;) {
      			var vx = x - path[j][0],
          			vy = y - path[j][1],
          			k2 = Math.sin(((object.count += count) + j * 3) / 300) / speed;
      			path[j][0] = (x += dx / speed * k1) - dy * k2;
      			path[j][1] = (y += dy / speed * k1) + dx * k2;
      			speed = Math.sqrt((dx = vx) * dx + (dy = vy) * dy);
    		}
  		}

  		box.attr("transform", function(d) {
    		return "translate(" + d.path[0] + ")rotate(" + Math.atan2(d.vy, d.vx) * degrees + ")";
  		});
  	}

d3.timer(function() {
	getVideo();
	//console.log(hit);
  	drawObjects();
});

}

function game(){
	switch(gamephase)
	{
		case 'pre-game':
			// draw intro
		break;
		case 'game-rest':
    		vid_c.fillStyle = "#fff";
    		vid_c.font="14px sans-serif";
    		vid_c.fillText('New target ...',200,20);
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
		break;
		case 'game-action':
    		vid_c.fillStyle = "#fff";
    		vid_c.font="14px sans-serif";
    		vid_c.fillText('Run! Run! Run!',200,20);
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
		break;
		case 'gameover':
    		vid_c.fillStyle = "#fff";
    		vid_c.font="14px sans-serif";
    		vid_c.textAlign="start";
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
    		vid_c.fillStyle = "rgba(253,172,13,1)";
    		vid_c.font="40pt sans-serif";
    		vid_c.textAlign="center";
    		vid_c.fillText('GAME OVER',vid_width/2,vid_height/2-100);
    		vid_c.fillStyle = "#fff";
    		vid_c.font="20pt sans-serif";
    		vid_c.fillText(username+' scored '+score_val,vid_width/2,vid_height/2);
		break;
		default:
			vid_c.fillStyle = "#fff";
			vid_c.font="14px sans-serif";
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
	}
}

var shipX=vid_width/2,
	shipY=vid_height/2,
	shipRad,
	shipL=20,
	starX=40,
	starY=20;
var gamelevel;
var int_star=-1;
var int_engine=-1;
var engine = false;
var rest = false;
var starTimer;
var enginerTimer;
var gamephase;
var score_val = 0;
var actionTimer;
var hit = new Array();
var unit=30;

function setGameAction(){
	actionTimer = window.requestAnimationFrame(actionLoop);
}

function setbackPreGame(){
    score_val = 0;
    hit = new Array();
    gamelevel=1;

	shipX = vid_width/2;
    shipY = vid_height/2;

    gamephase='pre-game';
}

function setGameOver(){
  	window.cancelAnimationFrame(actionTimer);
    actionTimer = undefined;
}

function actionLoop(){
	switch(gamephase)
	{
		case 'rest':
  			if(rest==false)
			{
				rest=true;
				int_star=gamelevel+6;
				getStarLocation(); // get new starX, starY, shipRad
				starTimer=window.setInterval(showStar,500);
			}
			drawStar(shipX,shipY,starX,starY,gamelevel-(int_star-6));
			drawShip(shipX,shipY,shipRad);
			actionTimer = window.requestAnimationFrame(gameLoop);
  		break;
		case 'engine':
			console.log(hit);
  			if(hit>0)
			{
				window.clearInterval(engineTimer);
				engine=false;
				rest=false;
				int_star=-1;
				int_engine=-1;
				gamephase='gameover';
				gamelevel=-1;
			}
			else
			{
				score_val=score_val+10;
				if(engine==false)
				{
					engine=true;
					int_engine=gamelevel+4;
					engineTimer=window.setInterval(runEngine,500);
				}
			}
			drawStar(shipX,shipY,starX,starY,gamelevel-(int_star-6));
			drawShip(shipX,shipY,shipRad);

  		break;
	}
}

function getStarLocation(){
	shipRad=Math.random()*Math.PI*2;
	starX=shipX+unit*(Math.cos(shipRad))*gamelevel;
	starY=shipY+unit*(Math.sin(shipRad))*gamelevel;
}

function getShipLocation(){
	var step = gamelevel-(int_engine-4);
	var u = (step > gamelevel - 1) ? 0 : 1;
	shipX=shipX+unit*(Math.cos(shipRad))*u;
	shipY=shipY+unit*(Math.sin(shipRad))*u;
}

function showStar(){
	if(int_star>0)
	{
		int_star=int_star-1;
	}
	else
	{
		window.clearInterval(starTimer);
		rest=false;
		gamephase='engine';
	}
}

function runEngine(){
	if(int_engine>0)
	{
		getShipLocation();
		int_engine=int_engine-1;
	}
	else
	{
		window.clearInterval(engineTimer);
		engine=false;
		gamephase='rest';
		if(gamelevel<10)
		{
			gamelevel=gamelevel+1;
		}
	}
}

function gameOver(){
    var msg = {type:'sendscore', user:username, score:score_val};
    socket.json.send(msg);
}

/*******************************************************************************
  Copyright (C) 2009 Tom Stoeveken
  This program is free software;
  you can redistribute it and/or modify it under the terms of the
  GNU General Public License, version 2.
  See the file COPYING for details.
*******************************************************************************/

var img1 = null;
var img2 = null;
var md_canvas = null;

function setupMotionDetection() {
  md_canvas = document.getElementById('mdCanvas');
  test_canvas = document.getElementById('testCanvas');
  md_canvas.width = vid_width;
  md_canvas.height = vid_height;
}

/*
  compare two images and count the differences

  input.: image1 and image2 are Image() objects
  input.: threshold specifies by how much the color value of a pixel
          must differ before they are regarded to be different

  return: number of different pixels
*/

function compare(image1, image2, ptX, ptY, threshold, ObjR) {
  var movement = new Array(0,0,0,0);
  var md_ctx = md_canvas.getContext("2d");
  var width = md_canvas.width/2, height = md_canvas.height/2;

  // copy images into canvas element
  // these steps scale the images and decodes the image data
  md_ctx.drawImage(image1, 0, 0, width, height);
  md_ctx.drawImage(image2, width, 0, width, height);

  // this makes r,g,b,alpha data of images available
  var pixels1 = md_ctx.getImageData(0, 0, width, height);
  var pixels2 = md_ctx.getImageData(width, 0, width, height);

  // substract picture1 from picture2
  // if they differ set color value to max,
  // if the difference is below threshold set difference to 0.
  for (var x = Math.round((ptX-ObjR)/2); x < Math.round((ptX+ObjR)/2); x++) {
    for (var y = Math.round((ptY-ObjR)/2); y < Math.round((ptY+ObjR)/2); y++) {

      // each pixel has a red, green, blue and alpha value
      // all values are stored in a linear array
      var i = x*4 + y*4*pixels1.width;

      var ch0 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch1 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch2 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;

      // count differing pixels
      var n = (x<Math.round(ptX/2))?0:1;
      var m = (y<Math.round(ptY/2))?0:2;
      movement[n+m] += Math.min(1, ch0 + ch1 + ch2);
    }
  }
  return movement;
}

function compareFrame(img1,arrObject) {
  // just compare if there are two pictures
  if ( img2 != null ) {
    var res=[0,0,0,0];
    var ObjR=10;

    try {
    		for (var n=0; n<arrMotion.length; n++){
    			// arrObject [active, position_x, position_y, detection_radius]
    			res = compare(img1, img2, arrObject[n][1], arrObject[n][2], 10, arrObject[n][3]);
    			    if ((res[0]>400)||(res[1]>400)||(res[2]>400)||(res[3]>400)){
            			res[0]=0;res[1]=0;res[2]=0;res[3]=0;
    				}
				hit[n]=res[0]+res[1]+res[2]+res[3];
    		}
    	}
    catch(e) {
    		// errors
    	}
	}
	img2 = img1;
}
<commit_msg>d3 debug<commit_after>var obj_canvas,
obj_c,
cp_canvas = null;

var canvas
var video_canvas,
vid_c;

var brown_const=0;

var vid_width = 640;
var vid_height = 480;
var n_object = 20;
var m_object = 5;

var canvas;
var context;

function setupD3(){
	var w = 640,
    	h = 480,
    	n = 20,
    	m = 12,
    	l = 80,
    	degrees = 180 / Math.PI;

	var objects = d3.range(n).map(function() {
  		var x = Math.random() * w, y = Math.random() * h;
  		var active = true;
  		var radius = 50;
  		return {
    		vx: Math.random() * 2 - 1,
    		vy: Math.random() * 2 - 1,
    		path: d3.range(m).map(function() { return [x, y]; }),
    		count: 0
  		};
	});

	var svg = d3.select("#canvasArea").append("svg:svg")
    	.attr("width", vid_width)
    	.attr("height", vid_height);

	var image = svg.append("image")
    	.attr("xlink:href", "http://171.65.102.132:8080/?action=snapshot?t=" + new Date().getTime())
    	.attr("width", vid_width)
    	.attr("height", vid_height);

	var g = svg.selectAll("g")
    	.data(objects)
		.enter().append("svg:g");

	var box = g.append("svg:rect")
    	.attr("width", l)
    	.attr("height", l);

	function getVideo(){
		var frameURL = "http://171.65.102.132:8080/?action=snapshot?t=" + new Date().getTime();
		image.attr('onload', function() {
         		compareFrame(image);
    		})
    		.attr("xlink:href", frameURL)
    		.attr("width", vid_width)
    		.attr("height", vid_height);
	}

	function drawObjects(){
		for (var i = -1; ++i < n;) {
    		var object = objects[i],
        		path = object.path,
        		dx = object.vx,
        		dy = object.vy,
        		x = path[0][0] += dx,
        		y = path[0][1] += dy,
        		speed = Math.sqrt(dx * dx + dy * dy),
        		count = speed * 10,
        		k1 = -5 - speed / 3;

    		// Bounce off the walls.
    		if (x < 0 || x > w) object.vx *= -1;
    		if (y < 0 || y > h) object.vy *= -1;

    		// Swim!
    		for (var j = 0; ++j < m;) {
      			var vx = x - path[j][0],
          			vy = y - path[j][1],
          			k2 = Math.sin(((object.count += count) + j * 3) / 300) / speed;
      			path[j][0] = (x += dx / speed * k1) - dy * k2;
      			path[j][1] = (y += dy / speed * k1) + dx * k2;
      			speed = Math.sqrt((dx = vx) * dx + (dy = vy) * dy);
    		}
  		}

  		box.attr("transform", function(d) {
    		return "translate(" + d.path[0] + ")";
    		//return "translate(" + d.path[0] + ")rotate(" + Math.atan2(d.vy, d.vx) * degrees + ")";
  		});
  	}

d3.timer(function() {
	getVideo();
	//console.log(hit);
  	drawObjects();
});

}

function game(){
	switch(gamephase)
	{
		case 'pre-game':
			// draw intro
		break;
		case 'game-rest':
    		vid_c.fillStyle = "#fff";
    		vid_c.font="14px sans-serif";
    		vid_c.fillText('New target ...',200,20);
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
		break;
		case 'game-action':
    		vid_c.fillStyle = "#fff";
    		vid_c.font="14px sans-serif";
    		vid_c.fillText('Run! Run! Run!',200,20);
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
		break;
		case 'gameover':
    		vid_c.fillStyle = "#fff";
    		vid_c.font="14px sans-serif";
    		vid_c.textAlign="start";
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
    		vid_c.fillStyle = "rgba(253,172,13,1)";
    		vid_c.font="40pt sans-serif";
    		vid_c.textAlign="center";
    		vid_c.fillText('GAME OVER',vid_width/2,vid_height/2-100);
    		vid_c.fillStyle = "#fff";
    		vid_c.font="20pt sans-serif";
    		vid_c.fillText(username+' scored '+score_val,vid_width/2,vid_height/2);
		break;
		default:
			vid_c.fillStyle = "#fff";
			vid_c.font="14px sans-serif";
    		vid_c.fillText('player : ' + username + '  score : ' +score_val ,20,20);
	}
}

var shipX=vid_width/2,
	shipY=vid_height/2,
	shipRad,
	shipL=20,
	starX=40,
	starY=20;
var gamelevel;
var int_star=-1;
var int_engine=-1;
var engine = false;
var rest = false;
var starTimer;
var enginerTimer;
var gamephase;
var score_val = 0;
var actionTimer;
var hit = new Array();
var unit=30;

function setGameAction(){
	actionTimer = window.requestAnimationFrame(actionLoop);
}

function setbackPreGame(){
    score_val = 0;
    hit = new Array();
    gamelevel=1;

	shipX = vid_width/2;
    shipY = vid_height/2;

    gamephase='pre-game';
}

function setGameOver(){
  	window.cancelAnimationFrame(actionTimer);
    actionTimer = undefined;
}

function actionLoop(){
	switch(gamephase)
	{
		case 'rest':
  			if(rest==false)
			{
				rest=true;
				int_star=gamelevel+6;
				getStarLocation(); // get new starX, starY, shipRad
				starTimer=window.setInterval(showStar,500);
			}
			drawStar(shipX,shipY,starX,starY,gamelevel-(int_star-6));
			drawShip(shipX,shipY,shipRad);
			actionTimer = window.requestAnimationFrame(gameLoop);
  		break;
		case 'engine':
			console.log(hit);
  			if(hit>0)
			{
				window.clearInterval(engineTimer);
				engine=false;
				rest=false;
				int_star=-1;
				int_engine=-1;
				gamephase='gameover';
				gamelevel=-1;
			}
			else
			{
				score_val=score_val+10;
				if(engine==false)
				{
					engine=true;
					int_engine=gamelevel+4;
					engineTimer=window.setInterval(runEngine,500);
				}
			}
			drawStar(shipX,shipY,starX,starY,gamelevel-(int_star-6));
			drawShip(shipX,shipY,shipRad);

  		break;
	}
}

function getStarLocation(){
	shipRad=Math.random()*Math.PI*2;
	starX=shipX+unit*(Math.cos(shipRad))*gamelevel;
	starY=shipY+unit*(Math.sin(shipRad))*gamelevel;
}

function getShipLocation(){
	var step = gamelevel-(int_engine-4);
	var u = (step > gamelevel - 1) ? 0 : 1;
	shipX=shipX+unit*(Math.cos(shipRad))*u;
	shipY=shipY+unit*(Math.sin(shipRad))*u;
}

function showStar(){
	if(int_star>0)
	{
		int_star=int_star-1;
	}
	else
	{
		window.clearInterval(starTimer);
		rest=false;
		gamephase='engine';
	}
}

function runEngine(){
	if(int_engine>0)
	{
		getShipLocation();
		int_engine=int_engine-1;
	}
	else
	{
		window.clearInterval(engineTimer);
		engine=false;
		gamephase='rest';
		if(gamelevel<10)
		{
			gamelevel=gamelevel+1;
		}
	}
}

function gameOver(){
    var msg = {type:'sendscore', user:username, score:score_val};
    socket.json.send(msg);
}

/*******************************************************************************
  Copyright (C) 2009 Tom Stoeveken
  This program is free software;
  you can redistribute it and/or modify it under the terms of the
  GNU General Public License, version 2.
  See the file COPYING for details.
*******************************************************************************/

var img1 = null;
var img2 = null;
var md_canvas = null;

function setupMotionDetection() {
  md_canvas = document.getElementById('mdCanvas');
  test_canvas = document.getElementById('testCanvas');
  md_canvas.width = vid_width;
  md_canvas.height = vid_height;
}

/*
  compare two images and count the differences

  input.: image1 and image2 are Image() objects
  input.: threshold specifies by how much the color value of a pixel
          must differ before they are regarded to be different

  return: number of different pixels
*/

function compare(image1, image2, ptX, ptY, threshold, ObjR) {
  var movement = new Array(0,0,0,0);
  var md_ctx = md_canvas.getContext("2d");
  var width = md_canvas.width/2, height = md_canvas.height/2;

  // copy images into canvas element
  // these steps scale the images and decodes the image data
  md_ctx.drawImage(image1, 0, 0, width, height);
  md_ctx.drawImage(image2, width, 0, width, height);

  // this makes r,g,b,alpha data of images available
  var pixels1 = md_ctx.getImageData(0, 0, width, height);
  var pixels2 = md_ctx.getImageData(width, 0, width, height);

  // substract picture1 from picture2
  // if they differ set color value to max,
  // if the difference is below threshold set difference to 0.
  for (var x = Math.round((ptX-ObjR)/2); x < Math.round((ptX+ObjR)/2); x++) {
    for (var y = Math.round((ptY-ObjR)/2); y < Math.round((ptY+ObjR)/2); y++) {

      // each pixel has a red, green, blue and alpha value
      // all values are stored in a linear array
      var i = x*4 + y*4*pixels1.width;

      var ch0 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch1 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch2 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;

      // count differing pixels
      var n = (x<Math.round(ptX/2))?0:1;
      var m = (y<Math.round(ptY/2))?0:2;
      movement[n+m] += Math.min(1, ch0 + ch1 + ch2);
    }
  }
  return movement;
}

function compareFrame(img1,arrObject) {
  // just compare if there are two pictures
  if ( img2 != null ) {
    var res=[0,0,0,0];
    var ObjR=10;

    try {
    		for (var n=0; n<arrMotion.length; n++){
    			// arrObject [active, position_x, position_y, detection_radius]
    			res = compare(img1, img2, arrObject[n][1], arrObject[n][2], 10, arrObject[n][3]);
    			    if ((res[0]>400)||(res[1]>400)||(res[2]>400)||(res[3]>400)){
            			res[0]=0;res[1]=0;res[2]=0;res[3]=0;
    				}
				hit[n]=res[0]+res[1]+res[2]+res[3];
    		}
    	}
    catch(e) {
    		// errors
    	}
	}
	img2 = img1;
}
<|endoftext|>


<commit_before>import UsersCtrl from '../controllers/UserCtr';
import Auth from '../middleware/Auth';

const UserRoutes = (router) => {
  router.route('/user')
    .get(Auth.verifyToken, UsersCtrl.showUsers);

  router.route('/user/signup')
    .post(UsersCtrl.signUp);

  router.route('/user/signin')
    .post(UsersCtrl.signIn);
  router.route('/user/signOut')
    .post(UsersCtrl.signOut);
};

export default UserRoutes;
<commit_msg>[feature]: add validation middleware to routes<commit_after>import UsersCtrl from '../controllers/UserCtr';
import Auth from '../middleware/Auth';
import Validation from '../middleware/Validation';

const UserRoutes = (router) => {
  router.route('/user')
    .get(Auth.verifyToken, UsersCtrl.showUsers);

  router.route('/user/signup')
    .post(Validation.validateSignUpInput, UsersCtrl.signUp);

  router.route('/user/signin')
    .post(Validation.validateSignInInput, UsersCtrl.signIn);
  router.route('/user/signOut')
    .post(UsersCtrl.signOut);
};

export default UserRoutes;
<|endoftext|>


<commit_before>OV.ImporterThreeBase = class extends OV.ImporterBase
{
    constructor ()
    {
        super ();
    }

    GetExternalLibraries ()
    {
        return null;
    }

    CreateLoader (manager)
    {
        return null;
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }

    IsMeshVisible (mesh)
    {
        return true;
    }

    ClearContent ()
    {
        this.loader = null;
        this.materialIdToIndex = null;
        this.objectUrlToFileName = null;
    }

    ResetContent ()
    {
        this.loader = null;
        this.materialIdToIndex = new Map ();
        this.objectUrlToFileName = new Map ();
    }

    ImportContent (fileContent, onFinish)
    {
        async function LoadLibraries (libraries, onFinish, onError)
        {
            try {
                for (let i = 0; i < libraries.length; i++) {
                    await OV.LoadExternalLibrary (libraries[i]);
                }
            } catch (err) {
                onError ();
            }
            onFinish ();
        }

        const libraries = this.GetExternalLibraries ();
        if (libraries === null) {
            onFinish ();
            return;
        }

        LoadLibraries (libraries, () => {
            this.LoadModel (fileContent, onFinish);
        }, () => {
            onFinish ();
        });
    }

    LoadModel (fileContent, onFinish)
    {
        let loadedObject = null;
        let loadingManager = new THREE.LoadingManager (() => {
            if (loadedObject !== null) {
                this.OnThreeObjectsLoaded (loadedObject, onFinish);
            }
        });

        const mainFileUrl = OV.CreateObjectUrl (fileContent);
        loadingManager.setURLModifier ((url) => {
            if (url === mainFileUrl) {
                return url;
            }
            if (url.startsWith ('blob:')) {
                const name = OV.GetFileName (url);
                const extension = OV.GetFileExtension (url);
                if (extension.length > 0) {
                    const buffer = this.callbacks.getFileBuffer (url);
                    if (buffer !== null) {
                        let objectUrl = OV.CreateObjectUrl (buffer);
                        this.objectUrlToFileName.set (objectUrl, name);
                        return objectUrl;
                    }
                }
            }
            return url;
        });

        const threeLoader = this.CreateLoader (loadingManager);
        if (threeLoader === null) {
            onFinish ();
            return;
        }

        threeLoader.load (mainFileUrl,
            (object) => {
                loadedObject = object;
            },
            () => {
            },
            (err) => {
                this.SetError (err);
                onFinish ();
            }
        );
    }

    OnThreeObjectsLoaded (loadedObject, onFinish)
    {
        function GetObjectTransformation (threeObject)
        {
            let matrix = new OV.Matrix ().CreateIdentity ();
            threeObject.updateMatrix ();
            if (threeObject.matrix !== undefined && threeObject.matrix !== null) {
                matrix.Set (threeObject.matrix.elements);
            }
            return new OV.Transformation (matrix);
        }

        function AddObject (importer, model, threeObject, parentNode)
        {
            let node = new OV.Node ();
            if (threeObject.name !== undefined) {
                node.SetName (threeObject.name);
            }
            node.SetTransformation (GetObjectTransformation (threeObject));
            parentNode.AddChildNode (node);

            for (let childObject of threeObject.children) {
                AddObject (importer, model, childObject, node);
            }
            if (threeObject.isMesh && importer.IsMeshVisible (threeObject)) {
                node.SetType (OV.NodeType.MeshNode);
                let mesh = importer.ConvertThreeMesh (threeObject);
                let meshIndex = model.AddMesh (mesh);
                node.AddMeshIndex (meshIndex);
            }
        }

        let mainObject = this.GetMainObject (loadedObject);
        let rootNode = this.model.GetRootNode ();
        rootNode.SetTransformation (GetObjectTransformation (mainObject));
        for (let childObject of mainObject.children) {
            AddObject (this, this.model, childObject, rootNode);
        }

        onFinish ();
    }

    ConvertThreeMesh (threeMesh)
    {
        let mesh = null;
        if (Array.isArray (threeMesh.material)) {
            mesh = OV.ConvertThreeGeometryToMesh (threeMesh.geometry, null);
            if (threeMesh.geometry.attributes.color === undefined || threeMesh.geometry.attributes.color === null) {
                let materialIndices = [];
                for (let i = 0; i < threeMesh.material.length; i++) {
                    const material = threeMesh.material[i];
                    const materialIndex = this.FindOrCreateMaterial (material);
                    materialIndices.push (materialIndex);
                }
                for (let i = 0; i < threeMesh.geometry.groups.length; i++) {
                    let group = threeMesh.geometry.groups[i];
                    for (let j = group.start / 3; j < group.start / 3 + group.count / 3; j++) {
                        let triangle = mesh.GetTriangle (j);
                        triangle.SetMaterial (materialIndices[group.materialIndex]);
                    }
                }
            }
        } else {
            const materialIndex = this.FindOrCreateMaterial (threeMesh.material);
            mesh = OV.ConvertThreeGeometryToMesh (threeMesh.geometry, materialIndex);
        }
        if (threeMesh.name !== undefined && threeMesh.name !== null) {
            mesh.SetName (threeMesh.name);
        }
        return mesh;
    }

    FindOrCreateMaterial (threeMaterial)
    {
        if (this.materialIdToIndex.has (threeMaterial.id)) {
            return this.materialIdToIndex.get (threeMaterial.id);
        }
        let material = this.ConvertThreeMaterial (threeMaterial);
        let materialIndex = this.model.AddMaterial (material);
        this.materialIdToIndex.set (threeMaterial.id, materialIndex);
        return materialIndex;
    }

    ConvertThreeMaterial (threeMaterial)
    {
        function SetColor (color, threeColor)
        {
            color.Set (
                parseInt (threeColor.r * 255.0, 10),
                parseInt (threeColor.g * 255.0, 10),
                parseInt (threeColor.b * 255.0, 10)
            );
        }

        function CreateTexture (threeMap, objectUrlToFileName)
        {
            function GetDataUrl (img)
            {
                if (img.data !== undefined && img.data !== null) {
                    let imageData = new ImageData (img.width, img.height);
                    let imageSize = img.width * img.height * 4;
                    for (let i = 0; i < imageSize; i++) {
                        imageData.data[i] = img.data[i];
                    }
                    return THREE.ImageUtils.getDataURL (imageData);
                } else {
                    return THREE.ImageUtils.getDataURL (img);
                }
            }

            if (threeMap === undefined || threeMap === null) {
                return null;
            }

            if (threeMap.image === undefined || threeMap.image === null) {
                return null;
            }

            try {
                const dataUrl = GetDataUrl (threeMap.image);
                const base64Buffer = OV.Base64DataURIToArrayBuffer (dataUrl);
                let texture = new OV.TextureMap ();
                let textureName = null;
                if (objectUrlToFileName.has (threeMap.image.src)) {
                    textureName = objectUrlToFileName.get (threeMap.image.src);
                } else if (threeMap.name !== undefined && threeMap.name !== null) {
                    textureName = threeMap.name + '.' + OV.GetFileExtensionFromMimeType (base64Buffer.mimeType);
                } else {
                    textureName = 'Embedded_' + threeMap.id.toString () + '.' + OV.GetFileExtensionFromMimeType (base64Buffer.mimeType);
                }
                texture.name = textureName;
                texture.url = dataUrl;
                texture.buffer = base64Buffer.buffer;
                texture.rotation = threeMap.rotation;
                texture.offset.x = threeMap.offset.x;
                texture.offset.y = threeMap.offset.y;
                texture.scale.x = threeMap.repeat.x;
                texture.scale.y = threeMap.repeat.y;
                return texture;
            } catch (err) {
                return null;
            }
        }

        let material = new OV.Material (OV.MaterialType.Phong);
        material.name = threeMaterial.name;
        SetColor (material.color, threeMaterial.color);
        material.opacity = threeMaterial.opacity;
        material.transparent = threeMaterial.transparent;
        material.alphaTest = threeMaterial.alphaTest;
        if (threeMaterial.type === 'MeshPhongMaterial') {
            SetColor (material.specular, threeMaterial.specular);
            material.shininess = threeMaterial.shininess / 100.0;
        }
        material.diffuseMap = CreateTexture (threeMaterial.map, this.objectUrlToFileName);
        material.normalMap = CreateTexture (threeMaterial.normalMap, this.objectUrlToFileName);
        material.bumpMap = CreateTexture (threeMaterial.bumpMap, this.objectUrlToFileName);

        return material;
    }
};

OV.ImporterThreeFbx = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'fbx';
    }

    GetUpDirection ()
    {
        return OV.Direction.Y;
    }

    GetExternalLibraries ()
    {
        return [
            'loaders/fflate.min.js',
            'three_loaders/TGALoader.js',
            'three_loaders/FBXLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        manager.addHandler (/\.tga$/i, new THREE.TGALoader (manager));
        return new THREE.FBXLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }
};

OV.ImporterThreeDae = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'dae';
    }

    GetUpDirection ()
    {
        return OV.Direction.Y;
    }

    GetExternalLibraries ()
    {
        return [
            'three_loaders/TGALoader.js',
            'three_loaders/ColladaLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        manager.addHandler (/\.tga$/i, new THREE.TGALoader (manager));
        return new THREE.ColladaLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject.scene;
    }
};

OV.ImporterThreeWrl = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'wrl';
    }

    GetUpDirection ()
    {
        return OV.Direction.Y;
    }

    GetExternalLibraries ()
    {
        return [
            'three_loaders/chevrotain.min.js',
            'three_loaders/VRMLLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        return new THREE.VRMLLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }

    IsMeshVisible (mesh)
    {
        let isVisible = true;
        if (Array.isArray (mesh.material)) {
            for (let i = 0; i < mesh.material.length; i++) {
                if (mesh.material[i].side === THREE.BackSide) {
                    isVisible = false;
                    break;
                }
            }
        } else {
            isVisible = (mesh.material.side !== THREE.BackSide);
        }
        return isVisible;
    }
};

OV.ImporterThree3mf = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === '3mf';
    }

    GetUpDirection ()
    {
        return OV.Direction.Z;
    }

    GetExternalLibraries ()
    {
        return [
            'loaders/fflate.min.js',
            'three_loaders/3MFLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        return new THREE.ThreeMFLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }
};

OV.ImporterThreeSvg = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'svg';
    }

    GetUpDirection ()
    {
        return OV.Direction.Z;
    }

    GetExternalLibraries ()
    {
        return [
            'three_loaders/SVGLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        return new THREE.SVGLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        function ShowFill (path)
        {
            const style = path.userData.style;
            if (style.fill === undefined || style.fill === 'none') {
                return false;
            }
            return true;
        }

        function ShowStroke (path)
        {
            const style = path.userData.style;
            if (style.stroke === undefined || style.stroke === 'none') {
                return false;
            }
            return true;
        }

        let object = new THREE.Object3D ();

        const material = new THREE.MeshPhongMaterial ({
            color: 0xcc0000
        });
        for (let path of loadedObject.paths) {
            const shapes = THREE.SVGLoader.createShapes (path);
            if (ShowFill (path)) {
                for (const shape of shapes) {
                    const geometry = new THREE.ShapeGeometry (shape);
                    const mesh = new THREE.Mesh (geometry, material);
                    object.add (mesh);
                }
            }
            if (ShowStroke (path)) {
                for (const subPath of path.subPaths) {
                    const geometry = THREE.SVGLoader.pointsToStroke (subPath.getPoints (), path.userData.style);
                    if (geometry) {
                        const mesh = new THREE.Mesh (geometry, material);
                        object.add (mesh);
                    }
                }
            }
        }
        return object;
    }
};
<commit_msg>Fix three.js import when a mesh node has children.<commit_after>OV.ImporterThreeBase = class extends OV.ImporterBase
{
    constructor ()
    {
        super ();
    }

    GetExternalLibraries ()
    {
        return null;
    }

    CreateLoader (manager)
    {
        return null;
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }

    IsMeshVisible (mesh)
    {
        return true;
    }

    ClearContent ()
    {
        this.loader = null;
        this.materialIdToIndex = null;
        this.objectUrlToFileName = null;
    }

    ResetContent ()
    {
        this.loader = null;
        this.materialIdToIndex = new Map ();
        this.objectUrlToFileName = new Map ();
    }

    ImportContent (fileContent, onFinish)
    {
        async function LoadLibraries (libraries, onFinish, onError)
        {
            try {
                for (let i = 0; i < libraries.length; i++) {
                    await OV.LoadExternalLibrary (libraries[i]);
                }
            } catch (err) {
                onError ();
            }
            onFinish ();
        }

        const libraries = this.GetExternalLibraries ();
        if (libraries === null) {
            onFinish ();
            return;
        }

        LoadLibraries (libraries, () => {
            this.LoadModel (fileContent, onFinish);
        }, () => {
            onFinish ();
        });
    }

    LoadModel (fileContent, onFinish)
    {
        let loadedObject = null;
        let loadingManager = new THREE.LoadingManager (() => {
            if (loadedObject !== null) {
                this.OnThreeObjectsLoaded (loadedObject, onFinish);
            }
        });

        const mainFileUrl = OV.CreateObjectUrl (fileContent);
        loadingManager.setURLModifier ((url) => {
            if (url === mainFileUrl) {
                return url;
            }
            if (url.startsWith ('blob:')) {
                const name = OV.GetFileName (url);
                const extension = OV.GetFileExtension (url);
                if (extension.length > 0) {
                    const buffer = this.callbacks.getFileBuffer (url);
                    if (buffer !== null) {
                        let objectUrl = OV.CreateObjectUrl (buffer);
                        this.objectUrlToFileName.set (objectUrl, name);
                        return objectUrl;
                    }
                }
            }
            return url;
        });

        const threeLoader = this.CreateLoader (loadingManager);
        if (threeLoader === null) {
            onFinish ();
            return;
        }

        threeLoader.load (mainFileUrl,
            (object) => {
                loadedObject = object;
            },
            () => {
            },
            (err) => {
                this.SetError (err);
                onFinish ();
            }
        );
    }

    OnThreeObjectsLoaded (loadedObject, onFinish)
    {
        function GetObjectTransformation (threeObject)
        {
            let matrix = new OV.Matrix ().CreateIdentity ();
            threeObject.updateMatrix ();
            if (threeObject.matrix !== undefined && threeObject.matrix !== null) {
                matrix.Set (threeObject.matrix.elements);
            }
            return new OV.Transformation (matrix);
        }

        function AddObject (importer, model, threeObject, parentNode)
        {
            let node = new OV.Node ();
            if (threeObject.name !== undefined) {
                node.SetName (threeObject.name);
            }
            node.SetTransformation (GetObjectTransformation (threeObject));
            parentNode.AddChildNode (node);

            for (let childObject of threeObject.children) {
                AddObject (importer, model, childObject, node);
            }
            if (threeObject.isMesh && importer.IsMeshVisible (threeObject)) {
                if (threeObject.children.length === 0) {
                    node.SetType (OV.NodeType.MeshNode);
                }
                let mesh = importer.ConvertThreeMesh (threeObject);
                let meshIndex = model.AddMesh (mesh);
                node.AddMeshIndex (meshIndex);
            }
        }

        let mainObject = this.GetMainObject (loadedObject);
        let rootNode = this.model.GetRootNode ();
        rootNode.SetTransformation (GetObjectTransformation (mainObject));
        for (let childObject of mainObject.children) {
            AddObject (this, this.model, childObject, rootNode);
        }

        onFinish ();
    }

    ConvertThreeMesh (threeMesh)
    {
        let mesh = null;
        if (Array.isArray (threeMesh.material)) {
            mesh = OV.ConvertThreeGeometryToMesh (threeMesh.geometry, null);
            if (threeMesh.geometry.attributes.color === undefined || threeMesh.geometry.attributes.color === null) {
                let materialIndices = [];
                for (let i = 0; i < threeMesh.material.length; i++) {
                    const material = threeMesh.material[i];
                    const materialIndex = this.FindOrCreateMaterial (material);
                    materialIndices.push (materialIndex);
                }
                for (let i = 0; i < threeMesh.geometry.groups.length; i++) {
                    let group = threeMesh.geometry.groups[i];
                    for (let j = group.start / 3; j < group.start / 3 + group.count / 3; j++) {
                        let triangle = mesh.GetTriangle (j);
                        triangle.SetMaterial (materialIndices[group.materialIndex]);
                    }
                }
            }
        } else {
            const materialIndex = this.FindOrCreateMaterial (threeMesh.material);
            mesh = OV.ConvertThreeGeometryToMesh (threeMesh.geometry, materialIndex);
        }
        if (threeMesh.name !== undefined && threeMesh.name !== null) {
            mesh.SetName (threeMesh.name);
        }
        return mesh;
    }

    FindOrCreateMaterial (threeMaterial)
    {
        if (this.materialIdToIndex.has (threeMaterial.id)) {
            return this.materialIdToIndex.get (threeMaterial.id);
        }
        let material = this.ConvertThreeMaterial (threeMaterial);
        let materialIndex = this.model.AddMaterial (material);
        this.materialIdToIndex.set (threeMaterial.id, materialIndex);
        return materialIndex;
    }

    ConvertThreeMaterial (threeMaterial)
    {
        function SetColor (color, threeColor)
        {
            color.Set (
                parseInt (threeColor.r * 255.0, 10),
                parseInt (threeColor.g * 255.0, 10),
                parseInt (threeColor.b * 255.0, 10)
            );
        }

        function CreateTexture (threeMap, objectUrlToFileName)
        {
            function GetDataUrl (img)
            {
                if (img.data !== undefined && img.data !== null) {
                    let imageData = new ImageData (img.width, img.height);
                    let imageSize = img.width * img.height * 4;
                    for (let i = 0; i < imageSize; i++) {
                        imageData.data[i] = img.data[i];
                    }
                    return THREE.ImageUtils.getDataURL (imageData);
                } else {
                    return THREE.ImageUtils.getDataURL (img);
                }
            }

            if (threeMap === undefined || threeMap === null) {
                return null;
            }

            if (threeMap.image === undefined || threeMap.image === null) {
                return null;
            }

            try {
                const dataUrl = GetDataUrl (threeMap.image);
                const base64Buffer = OV.Base64DataURIToArrayBuffer (dataUrl);
                let texture = new OV.TextureMap ();
                let textureName = null;
                if (objectUrlToFileName.has (threeMap.image.src)) {
                    textureName = objectUrlToFileName.get (threeMap.image.src);
                } else if (threeMap.name !== undefined && threeMap.name !== null) {
                    textureName = threeMap.name + '.' + OV.GetFileExtensionFromMimeType (base64Buffer.mimeType);
                } else {
                    textureName = 'Embedded_' + threeMap.id.toString () + '.' + OV.GetFileExtensionFromMimeType (base64Buffer.mimeType);
                }
                texture.name = textureName;
                texture.url = dataUrl;
                texture.buffer = base64Buffer.buffer;
                texture.rotation = threeMap.rotation;
                texture.offset.x = threeMap.offset.x;
                texture.offset.y = threeMap.offset.y;
                texture.scale.x = threeMap.repeat.x;
                texture.scale.y = threeMap.repeat.y;
                return texture;
            } catch (err) {
                return null;
            }
        }

        let material = new OV.Material (OV.MaterialType.Phong);
        material.name = threeMaterial.name;
        SetColor (material.color, threeMaterial.color);
        material.opacity = threeMaterial.opacity;
        material.transparent = threeMaterial.transparent;
        material.alphaTest = threeMaterial.alphaTest;
        if (threeMaterial.type === 'MeshPhongMaterial') {
            SetColor (material.specular, threeMaterial.specular);
            material.shininess = threeMaterial.shininess / 100.0;
        }
        material.diffuseMap = CreateTexture (threeMaterial.map, this.objectUrlToFileName);
        material.normalMap = CreateTexture (threeMaterial.normalMap, this.objectUrlToFileName);
        material.bumpMap = CreateTexture (threeMaterial.bumpMap, this.objectUrlToFileName);

        return material;
    }
};

OV.ImporterThreeFbx = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'fbx';
    }

    GetUpDirection ()
    {
        return OV.Direction.Y;
    }

    GetExternalLibraries ()
    {
        return [
            'loaders/fflate.min.js',
            'three_loaders/TGALoader.js',
            'three_loaders/FBXLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        manager.addHandler (/\.tga$/i, new THREE.TGALoader (manager));
        return new THREE.FBXLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }
};

OV.ImporterThreeDae = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'dae';
    }

    GetUpDirection ()
    {
        return OV.Direction.Y;
    }

    GetExternalLibraries ()
    {
        return [
            'three_loaders/TGALoader.js',
            'three_loaders/ColladaLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        manager.addHandler (/\.tga$/i, new THREE.TGALoader (manager));
        return new THREE.ColladaLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject.scene;
    }
};

OV.ImporterThreeWrl = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'wrl';
    }

    GetUpDirection ()
    {
        return OV.Direction.Y;
    }

    GetExternalLibraries ()
    {
        return [
            'three_loaders/chevrotain.min.js',
            'three_loaders/VRMLLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        return new THREE.VRMLLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }

    IsMeshVisible (mesh)
    {
        let isVisible = true;
        if (Array.isArray (mesh.material)) {
            for (let i = 0; i < mesh.material.length; i++) {
                if (mesh.material[i].side === THREE.BackSide) {
                    isVisible = false;
                    break;
                }
            }
        } else {
            isVisible = (mesh.material.side !== THREE.BackSide);
        }
        return isVisible;
    }
};

OV.ImporterThree3mf = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === '3mf';
    }

    GetUpDirection ()
    {
        return OV.Direction.Z;
    }

    GetExternalLibraries ()
    {
        return [
            'loaders/fflate.min.js',
            'three_loaders/3MFLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        return new THREE.ThreeMFLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        return loadedObject;
    }
};

OV.ImporterThreeSvg = class extends OV.ImporterThreeBase
{
    constructor ()
    {
        super ();
    }

    CanImportExtension (extension)
    {
        return extension === 'svg';
    }

    GetUpDirection ()
    {
        return OV.Direction.Z;
    }

    GetExternalLibraries ()
    {
        return [
            'three_loaders/SVGLoader.js'
        ];
    }

    CreateLoader (manager)
    {
        return new THREE.SVGLoader (manager);
    }

    GetMainObject (loadedObject)
    {
        function ShowFill (path)
        {
            const style = path.userData.style;
            if (style.fill === undefined || style.fill === 'none') {
                return false;
            }
            return true;
        }

        function ShowStroke (path)
        {
            const style = path.userData.style;
            if (style.stroke === undefined || style.stroke === 'none') {
                return false;
            }
            return true;
        }

        let object = new THREE.Object3D ();

        const material = new THREE.MeshPhongMaterial ({
            color: 0xcc0000
        });
        for (let path of loadedObject.paths) {
            const shapes = THREE.SVGLoader.createShapes (path);
            if (ShowFill (path)) {
                for (const shape of shapes) {
                    const geometry = new THREE.ShapeGeometry (shape);
                    const mesh = new THREE.Mesh (geometry, material);
                    object.add (mesh);
                }
            }
            if (ShowStroke (path)) {
                for (const subPath of path.subPaths) {
                    const geometry = THREE.SVGLoader.pointsToStroke (subPath.getPoints (), path.userData.style);
                    if (geometry) {
                        const mesh = new THREE.Mesh (geometry, material);
                        object.add (mesh);
                    }
                }
            }
        }
        return object;
    }
};
<|endoftext|>


<commit_before>"use strict";

/**
 *   Copyright 2013 Vimeo
 *
 *   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.
 */

/**
 * For this example to run properly you must create an api app at developer.vimeo.com/apps/new and set your callback url to http://localhost:8080/oauth_callback
 *
 */
var vimeo_module = require('../index');
var Vimeo = vimeo_module.Vimeo;
var util_module = require('util');

try {
	var config = require('./config.json');
} catch (error) {
	console.error('ERROR: For this example to run properly you must create an api app at developer.vimeo.com/apps/new and set your callback url to http://localhost:8080/oauth_callback');
	console.error('ERROR: Once you have your app, make a copy of config.json.example named "config.json" and add your client id and client secret');
	return;
}

var http_module = require('http');
var url_module = require('url');

var state_data = {
	state : "unauthorized"
};

// Here we have to build the vimeo library using the client_id and client_secret
// We do not need an access token here because we will generate one
// If we already knew our access token, we can provide it as the third parameter
var lib = new Vimeo(config.client_id, config.client_secret);

// The authorization process requires the user to be redirected back to a webpage, so we can start up a simple http server here
var server = http_module.createServer(function (request, response) {
	var url = url_module.parse(request.url, true);

	// Once the user accepts your app, they will be redirected back to localhost:8080/oauth_callback.
	// If they are not redirected you should check your apps configuration on developer.vimeo.com/apps
	if (url.pathname === '/oauth_callback') {
		if (url.query.state !== 'abcdefg') {
			throw new Error('invalid state');
		}

		if (!url.query.error) {
			// At this state (a request to /oauth_callback without an error parameter)
			// the user has been redirected back to the app and you can exchange the "code" parameter for an access token
			console.info('successful oauth callback request');
			lib.accessToken(url.query.code, 'http://localhost:8080/oauth_callback', function (err, token) {
				if (err) {
					return response.end("error\n" + err);
				}

				if (token.access_token) {
					// At this state the code has been successfully exchanged for an access token
					lib.access_token = token.access_token;
					state_data.user = token.user;
					state_data.state = "authorized";
					response.statusCode = 302;
					response.setHeader('Location', '/');
					response.end();
				} else {
					throw new Error('no access token provided');
				}
			});
		} else {
			// At this state (a request to /oauth_callback with an error parameter)
			// something went wrong when you sent your user to Vimeo.com. The error parameter should tell you more
			console.error('failed oauth callback request');
			console.error(url.query.error);

			response.setHeader('Content-Type', 'text/html');
			response.write('Your command line is currently unauthenticated. Please ');
			response.end('Link with Vimeo
' + JSON.stringify(url.query));
		}

	} else {
		if (state_data.state !== "authorized") {
			// At this state (any request where state_data.state has not been set to "authorized")
			// we do not have an authentication token, so we need to send the user to Vimeo.
			console.info('http request without access token');
			response.setHeader('Content-Type', 'text/html');
			response.write('Your command line is currently unauthenticated. Please ');
			response.end('Link with Vimeo');
		} else {
			// At this state (state_data.state has been set to "authorized" when we retrieved the access token)
			// we can make authenticated api requests
			console.info('http request with access token');
			response.setHeader('Content-Type', 'text/html');
			response.end('Your command line is currently authorized with the user : ' + state_data.user.name + '. You can make api requests via the command line using the "request" function, or upload files using the "upload" function.
 Try "request(\'/me\');"');
		}
	}
});

server.listen(8080, function () {
	console.log('Server started on 8080');
});

var context = require('repl').start({}).context;

/**
 * This will upload the video to the authenticated account.
 *
 * @param  {string} path The path to the video file
 */
context.upload = function (path) {
	lib.streamingUpload(path, function (err, data, status, headers) {
		if (err) {
			console.log('---upload error---');
			console.log('error');
			console.log(err);
			console.log('response body');
			console.log(data);
			console.log('response status');
			console.log(status);
			console.log('response headers');
			console.log(headers);
		} else {
			console.log('---upload success---');
			console.log('response body');
			console.log(data);
			console.log('response status');
			console.log(status);
			console.log('response headers');
			console.log(headers);
		}
	});
};

/**
 * This method lets you make api requests.
 *
 * options.method is a string of the HTTP method for the request (GET, POST, PUT, PATCH, DELETE)
 * options.path is a string of the path portion of a url (eg. /users/dashron)
 * options.query is an object containing all of your request parameters. If GET they will be appended to the url, if POST it will be part of your request body
 * options.headers is an object containing key value pairings of all of the HTTP request headers
 *
 * @param  {Object|String} options If string, it will make a GET request to that url. If an object, you can provide many parameters. See the function description for more.
 */
context.request = function (options) {
	if (typeof options === "string") {
		options = {path : options};
	}

	lib.request(options, function (err, data, status, headers) {
		if (err) {
			console.log('---request error---');
			console.log('status');
			console.log(status);
			console.log('headers');
			console.log(headers);

			console.log('error');
			console.log(util_module.inspect(err));
		} else {
			console.log('---request success---');
			console.log('status');
			console.log(status);
			console.log('headers');
			console.log(headers);

			console.log('response');
			console.log(data);
		}
	});
};
<commit_msg>remove upload scope for an easier first time auth example<commit_after>"use strict";

/**
 *   Copyright 2013 Vimeo
 *
 *   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.
 */

/**
 * For this example to run properly you must create an api app at developer.vimeo.com/apps/new and set your callback url to http://localhost:8080/oauth_callback
 *
 */
var vimeo_module = require('../index');
var Vimeo = vimeo_module.Vimeo;
var util_module = require('util');

try {
	var config = require('./config.json');
} catch (error) {
	console.error('ERROR: For this example to run properly you must create an api app at developer.vimeo.com/apps/new and set your callback url to http://localhost:8080/oauth_callback');
	console.error('ERROR: Once you have your app, make a copy of config.json.example named "config.json" and add your client id and client secret');
	return;
}

var http_module = require('http');
var url_module = require('url');

var state_data = {
	state : "unauthorized"
};

// Here we have to build the vimeo library using the client_id and client_secret
// We do not need an access token here because we will generate one
// If we already knew our access token, we can provide it as the third parameter
var lib = new Vimeo(config.client_id, config.client_secret);

// The authorization process requires the user to be redirected back to a webpage, so we can start up a simple http server here
var server = http_module.createServer(function (request, response) {
	var url = url_module.parse(request.url, true);

	// Once the user accepts your app, they will be redirected back to localhost:8080/oauth_callback.
	// If they are not redirected you should check your apps configuration on developer.vimeo.com/apps
	if (url.pathname === '/oauth_callback') {
		if (url.query.state !== 'abcdefg') {
			throw new Error('invalid state');
		}

		if (!url.query.error) {
			// At this state (a request to /oauth_callback without an error parameter)
			// the user has been redirected back to the app and you can exchange the "code" parameter for an access token
			console.info('successful oauth callback request');
			lib.accessToken(url.query.code, 'http://localhost:8080/oauth_callback', function (err, token) {
				if (err) {
					return response.end("error\n" + err);
				}

				if (token.access_token) {
					// At this state the code has been successfully exchanged for an access token
					lib.access_token = token.access_token;
					state_data.user = token.user;
					state_data.state = "authorized";
					response.statusCode = 302;
					response.setHeader('Location', '/');
					response.end();
				} else {
					throw new Error('no access token provided');
				}
			});
		} else {
			// At this state (a request to /oauth_callback with an error parameter)
			// something went wrong when you sent your user to Vimeo.com. The error parameter should tell you more
			console.error('failed oauth callback request');
			console.error(url.query.error);

			response.setHeader('Content-Type', 'text/html');
			response.write('Your command line is currently unauthenticated. Please ');
			response.end('Link with Vimeo
' + JSON.stringify(url.query));
		}

	} else {
		if (state_data.state !== "authorized") {
			// At this state (any request where state_data.state has not been set to "authorized")
			// we do not have an authentication token, so we need to send the user to Vimeo.
			console.info('http request without access token');
			response.setHeader('Content-Type', 'text/html');
			response.write('Your command line is currently unauthenticated. Please ');
			response.end('Link with Vimeo');
		} else {
			// At this state (state_data.state has been set to "authorized" when we retrieved the access token)
			// we can make authenticated api requests
			console.info('http request with access token');
			response.setHeader('Content-Type', 'text/html');
			response.end('Your command line is currently authorized with the user : ' + state_data.user.name + '. You can make api requests via the command line using the "request" function, or upload files using the "upload" function.
 Try "request(\'/me\');"');
		}
	}
});

server.listen(8080, function () {
	console.log('Server started on 8080');
});

var context = require('repl').start({}).context;

/**
 * This will upload the video to the authenticated account.
 *
 * @param  {string} path The path to the video file
 */
context.upload = function (path) {
	lib.streamingUpload(path, function (err, data, status, headers) {
		if (err) {
			console.log('---upload error---');
			console.log('error');
			console.log(err);
			console.log('response body');
			console.log(data);
			console.log('response status');
			console.log(status);
			console.log('response headers');
			console.log(headers);
		} else {
			console.log('---upload success---');
			console.log('response body');
			console.log(data);
			console.log('response status');
			console.log(status);
			console.log('response headers');
			console.log(headers);
		}
	});
};

/**
 * This method lets you make api requests.
 *
 * options.method is a string of the HTTP method for the request (GET, POST, PUT, PATCH, DELETE)
 * options.path is a string of the path portion of a url (eg. /users/dashron)
 * options.query is an object containing all of your request parameters. If GET they will be appended to the url, if POST it will be part of your request body
 * options.headers is an object containing key value pairings of all of the HTTP request headers
 *
 * @param  {Object|String} options If string, it will make a GET request to that url. If an object, you can provide many parameters. See the function description for more.
 */
context.request = function (options) {
	if (typeof options === "string") {
		options = {path : options};
	}

	lib.request(options, function (err, data, status, headers) {
		if (err) {
			console.log('---request error---');
			console.log('status');
			console.log(status);
			console.log('headers');
			console.log(headers);

			console.log('error');
			console.log(util_module.inspect(err));
		} else {
			console.log('---request success---');
			console.log('status');
			console.log(status);
			console.log('headers');
			console.log(headers);

			console.log('response');
			console.log(data);
		}
	});
};
<|endoftext|>


<commit_before>"use strict";

if(module != null) var misc = require('./misc.js');

var app = (function(){
    var me = {};

    //make row
    var r = function(a, am, c, cm, g, gm, t, tm){
	return {'A': {cmd: me.cmd[a], turn: am, name: a},
		'C': {cmd: me.cmd[c], turn: cm, name: c},
		'G': {cmd: me.cmd[g], turn: gm, name: g},
		'T': {cmd: me.cmd[t], turn: tm, name: t}};
    };

    var turnMap = {
	's': 0, //straight
	'r': -1,//right
	'l': 1  //left
    };

    var noop = function(state){ return state; };

    me.getPairs = function(code){
	var pairs = [];
	for(var i = 0, j = 1;;){
	    if(j < code.length){
		pairs.push({ first: code[i], last: code[j] });
	    }else{
		break;
	    }
	    i = j + 1;
	    j = i + 1;
	}
	return pairs;
    };

    me.getCommands = function(pairs){
	var cmds = [];
	misc.arrayEach(pairs, function(p){
	    cmds.push(me.codeMap[p.first][p.last]);
	});
	return cmds;
    };

    me.getBindingPreference = function(commands){
	var dir = 0;
	misc.arrayEach(commands, function(c){
	    dir += turnMap[c.turn];
	});
	return (['A', 'C', 'T', 'G'])[(4 + (dir % 4)) % 4];
    };

    me.doCommand = function(state){
	return me.cmd[state.command](state);
    };

    me.cmd = {
	'cut': noop,
	'del': noop,
	'swi': noop,
	'mvr': noop,
	'mvl': noop,
	'cop': noop,
	'off': noop,
	'ina': noop,
	'inc': noop,
	'ing': noop,
	'int': noop,
	'rpy': noop,
	'rpu': noop,
	'lpy': noop,
	'lpu': noop,
	'   ': noop
    };

    me.codeMap = {
	//       A           C           G           T
	'A': r('   ', ' ', 'cut', 's', 'del', 's', 'swi', 'r'),
	'C': r('mvr', 's', 'mvl', 's', 'cop', 'r', 'off', 'l'),
	'G': r('ina', 's', 'inc', 'r', 'ing', 'r', 'int', 'l'),
	'T': r('rpy', 'r', 'rpu', 'l', 'lpy', 'l', 'lpu', 'l')
    };

    return me;
})();

misc.exporter(module, app);
<commit_msg>Split genes on punctuation.<commit_after>"use strict";

if(typeof module !== 'undefined'){
    var misc = require('./misc.js');
}

var app = (function(){
    var me = {};

    //make row
    var r = function(a, am, c, cm, g, gm, t, tm){
	return {'A': {cmd: me.cmd[a], turn: am, name: a},
		'C': {cmd: me.cmd[c], turn: cm, name: c},
		'G': {cmd: me.cmd[g], turn: gm, name: g},
		'T': {cmd: me.cmd[t], turn: tm, name: t}};
    };

    var turnMap = {
	's': 0, //straight
	'r': -1,//right
	'l': 1  //left
    };

    var complement = {
	'A': 'T',
	'T': 'A',
	'G': 'C',
	'C': 'G'
    };

    var noop = function(state){ return state; };

    me.getPairs = function(code){
	var pairs = [];
	for(var i = 0, j = 1;;){
	    if(j < code.length){
		pairs.push({ first: code[i], last: code[j], i: i, j: j });
	    }else{
		break;
	    }
	    i = j + 1;
	    j = i + 1;
	}
	return pairs;
    };

    me.getCmd = function(pair){
	return me.codeMap[pair.first][pair.last];
    };

    me.splitGeneOnPunctuation = function(code, pairs){
	var genes = [];
	var cj = 0, pi = 0, pj = 0;
	for(; pi < pairs.length; pi++){
	    if(me.getCmd(pairs[pi]).name === '   '){
		if(pi !== pj){
		    genes.push({
			pairs: pairs.slice(pj, pi),
			code: code.slice(cj, pairs[pi].i)
		    });
		}
		pj = pi + 1;
		cj = pairs[pi].j + 1;
	    }
	}
	if(pj < pi){
	    genes.push({
		pairs: pairs.slice(pj, pi),
		code: code.slice(cj, pairs[pi].i)
	    });
	}
	return genes;
    };

    me.getCommands = function(pairs){
	var cmds = [];
	misc.arrayEach(pairs, function(p){
	    cmds.push(me.getCmd(p));
	});
	return cmds;
    };

    me.getBindingPreference = function(commands){
	var dir = 0;
	misc.arrayEach(commands, function(c){
	    dir += turnMap[c.turn];
	});
	return (['A', 'C', 'T', 'G'])[(4 + (dir % 4)) % 4];
    };

    me.current = function(state){
	return state.code[state.curIndx];
    };

    me.onPreference = function(state){
	return me.current(state) === state.bindingPref;
    };

    me.bindToPreference = function(state){
	state.curIndx = 0;
	while(!me.onPreference(state)
	     && state.curIndx < state.code.length){
	    state.curIndx += 1;
	}
	if(!me.onPreference(state)){
	    state.curIndx = Math.round(state.code.length / 2) - 1;
	}
	return state;
    };

    me.cmd = {
	'cut': noop,
	'del': noop,
	'swi': noop,
	'mvr': noop,
	'mvl': noop,
	'cop': noop,
	'off': noop,
	'ina': noop,
	'inc': noop,
	'ing': noop,
	'int': noop,
	'rpy': noop,
	'rpu': noop,
	'lpy': noop,
	'lpu': noop,
	'   ': noop
    };

    me.doCommand = function(state){
	return me.cmd[state.command](state);
    };

    me.codeMap = {
	//       A           C           G           T
	'A': r('   ', ' ', 'cut', 's', 'del', 's', 'swi', 'r'),
	'C': r('mvr', 's', 'mvl', 's', 'cop', 'r', 'off', 'l'),
	'G': r('ina', 's', 'inc', 'r', 'ing', 'r', 'int', 'l'),
	'T': r('rpy', 'r', 'rpu', 'l', 'lpy', 'l', 'lpu', 'l')
    };

    return me;
})();

if(typeof module !== 'undefined'){
    misc.exporter(module, app);
}
<|endoftext|>


<commit_before>/*!
 * Copyright 2015 Digital Services, University of Cambridge Licensed
 * under the Educational Community 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://opensource.org/licenses/ECL-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.
 */

define(['gh.core'], function(gh) {

    /////////////////
    //  UTILITIES  //
    /////////////////

    /**
     * Render and play the video
     *
     * @private
     */
    var renderAndPlayVideo = function() {
        var youtubeId = gh.config.video.adminhowto;
        var videoURL = '//www.youtube.com/embed/' + youtubeId + '?enablejsapi=1&autoplay=1&hl=en-gb&modestbranding=1&rel=0&showinfo=0&color=white&theme=light';

        gh.utils.renderTemplate('admin-video', {
            'videoURL': videoURL
        }, $('#gh-video-container'), function() {
            $('.gh-video').addClass('isPlaying');
        });
    };

    /**
     * Stop the video by removing it from the page
     *
     * @private
     */
    var stopVideo = function() {
        $('.gh-video').removeClass('isPlaying');
        $('#gh-video-container').empty();
    };

    ///////////////
    //  BINDING  //
    ///////////////

    /**
     * Add handlers to various elements in the video component
     *
     * @private
     */
    var addBinding = function() {
        $(document).on('gh.video.play', renderAndPlayVideo);
        $(document).on('gh.video.stop', stopVideo);
    };

    //////////////////////
    //  INITIALISATION  //
    //////////////////////

    /**
     * Initialise the video component
     *
     * @private
     */
    var initialiseVideo = function() {
        addBinding();
    };

    initialiseVideo();
});
<commit_msg>Use configurable admin video ID<commit_after>/*!
 * Copyright 2015 Digital Services, University of Cambridge Licensed
 * under the Educational Community 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://opensource.org/licenses/ECL-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.
 */

define(['gh.core', 'gh.constants'], function(gh, constants) {

    /////////////////
    //  UTILITIES  //
    /////////////////

    /**
     * Render and play the video
     *
     * @private
     */
    var renderAndPlayVideo = function() {
        var youtubeId = constants.video.adminhowto;
        var videoURL = '//www.youtube.com/embed/' + youtubeId + '?enablejsapi=1&autoplay=1&hl=en-gb&modestbranding=1&rel=0&showinfo=0&color=white&theme=light';

        gh.utils.renderTemplate('admin-video', {
            'videoURL': videoURL
        }, $('#gh-video-container'), function() {
            $('.gh-video').addClass('isPlaying');
        });
    };

    /**
     * Stop the video by removing it from the page
     *
     * @private
     */
    var stopVideo = function() {
        $('.gh-video').removeClass('isPlaying');
        $('#gh-video-container').empty();
    };

    ///////////////
    //  BINDING  //
    ///////////////

    /**
     * Add handlers to various elements in the video component
     *
     * @private
     */
    var addBinding = function() {
        $(document).on('gh.video.play', renderAndPlayVideo);
        $(document).on('gh.video.stop', stopVideo);
    };

    //////////////////////
    //  INITIALISATION  //
    //////////////////////

    /**
     * Initialise the video component
     *
     * @private
     */
    var initialiseVideo = function() {
        addBinding();
    };

    initialiseVideo();
});
<|endoftext|>