diff --git a/js/script.js b/js/script.js
new file mode 100644
index 0000000..1493ae1
--- /dev/null
+++ b/js/script.js
@@ -0,0 +1,551 @@
+// *********** HERE STARTS circle-mode.js *************
+
+window.addEventListener("load", initCircleMode);
+
+circleMode = false;
+
+function initCircleMode() {
+	document.querySelector("#circle-mode").addEventListener('click', function() {		
+		if(circleMode) {
+			circleMode = false;
+			document.querySelector("#circle-mode i").innerText = "trip_origin";
+
+			s.graph.nodes().forEach(function(n) {
+				n.x = n.originalX;
+				n.y = n.originalY;
+				n.size = 10;
+			});
+			
+			s.refresh();
+			
+		}
+		else {	
+			circleMode = true;
+			document.querySelector("#circle-mode i").innerText = "shuffle";
+			
+			s.graph.nodes().forEach(function(n) {
+				n.x = n.circleX;
+				n.y = n.circleY;		
+			});
+			
+			s.refresh();
+		}
+	});
+}
+
+function isInRect (x, y, rect) {
+	if (x < -10000 || x > 10000) return true;
+	if (y < -10000 || y > 10000) return true;
+	
+	var ans = true;
+	var c = crossProd (rect[0], rect[1], x, y);
+	
+	for(var i=1; i<4; i++) {	
+		var temp = crossProd (rect[i], rect[(i+1)%4], x, y);
+		if (c*temp < 0) ans = false;
+	}
+	return ans;
+}
+
+function crossProd(r1, r2, x, y) {
+	return r1[0]*r2[1] + r2[0]*y + x*r1[1] - r1[0]*y - r2[0]*r1[1] - x*r2[1]; 
+}
+
+
+// *********** HERE STARTS graf.js *************
+
+window.addEventListener("load", initGraf);
+
+// s is the sigma graph
+// graf is the JSON graph
+var s, graf;
+
+// query dario JSON for the graph information
+function xhr(method, url, params, callback) {
+	var http = new XMLHttpRequest();
+	if (method == "POST") {
+		http.open(method, url, true);
+	} else {
+		if (params != "") {
+			http.open(method, url+"?"+params, true);
+		} else {
+			http.open(method, url, true);
+		}
+	}
+	http.onload = function() {
+		if(this.status != 200) {
+			console.warn("Attention, status code "+this.status+" when loading via xhr url "+url);
+		}
+		callback(this.responseText, this.status);
+	};
+	if (method == "POST") {
+		http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
+		http.send(params);
+	} else {
+		http.send();
+	}
+}
+
+
+function initGraf() {
+	// create new methods for sigma library
+	updateSigma();
+	
+	// create graf, s is the sigma graf
+	s = new sigma({
+		renderers: [{
+			container: "graf",
+			type: "webgl"
+		}],
+		settings: {
+			defaultEdgeColor: "#fff",
+			edgeColor: "default",
+			defaultLabelColor: "#fff",
+			autoRescale: false,
+			zoomMax: 30,
+			// enableEdgeHovering: true,
+			font: "Roboto",
+			labelThreshold: 5
+		}
+	});
+
+	
+	// query for JSON for graph data
+	xhr("GET", "api.php", "action=getgraf", function(responseText, status) {
+		// graf is the JSON data
+		graf = JSON.parse(responseText);
+
+		// does graf.nodes have a size attribute?
+		var rectBorrar = [[0,0], [0,0], [0,0], [0,0]];
+		for (var i in graf.nodes) {
+			if (graf.nodes[i].name == "Erase")    rectBorrar[0] = [ graf.nodes[i].x , graf.nodes[i].y ];
+			if (graf.nodes[i].name == "Borrar")   rectBorrar[1] = [ graf.nodes[i].x , graf.nodes[i].y ];
+			if (graf.nodes[i].name == "Esborrar") rectBorrar[2] = [ graf.nodes[i].x , graf.nodes[i].y ];
+			if (graf.nodes[i].name == "Delete")   rectBorrar[3] = [ graf.nodes[i].x , graf.nodes[i].y ];
+		}
+		
+		var sizegraf = 0;
+		for (var i in graf.nodes) {
+			if ( isInRect(graf.nodes[i].x, graf.nodes[i].y, rectBorrar) ) continue;	
+			sizegraf++;
+		}		
+		var nnode = 0;
+		for (var i in graf.nodes) {
+			var ncolor = null;
+			
+			if(graf.nodes[i].sex =="F") ncolor = "#d61c08";
+			else if(graf.nodes[i].sex == "M") ncolor = "#0159aa";
+			else ncolor = "#0ca80a";
+			
+			// post-processing for year corrections
+			if(1970 < graf.nodes[i].year && graf.nodes[i].year < 2004) graf.nodes[i].year += 18;
+			
+			var newX = 5000*Math.cos( 2*Math.PI*nnode/sizegraf );
+			var newY = 5000*Math.sin( 2*Math.PI*nnode/sizegraf );	
+			
+			if (isInRect(graf.nodes[i].x, graf.nodes[i].y, rectBorrar) ) continue;	
+			
+			s.graph.addNode({
+				// we add color, originalColor, size, originalX..Y, circleX..Y atributes
+				id: graf.nodes[i].id,
+				year: graf.nodes[i].year,
+				sex: graf.nodes[i].sex,
+				label: graf.nodes[i].name,
+				x: graf.nodes[i].x,
+				y: graf.nodes[i].y, 
+				circleX: newX,
+				circleY: newY,
+				originalX: graf.nodes[i].x,
+				originalY: graf.nodes[i].y, 
+				size: 10,
+				color: ncolor,
+				originalColor: ncolor
+			});
+			nnode++;
+		
+		}
+
+		for (var i in graf.edges) {
+			if (isInRect(graf.nodes[graf.edges[i].a].x, graf.nodes[graf.edges[i].a].y, rectBorrar)) continue;	
+			if (isInRect(graf.nodes[graf.edges[i].b].x, graf.nodes[graf.edges[i].b].y, rectBorrar)) continue;	
+			
+			s.graph.addEdge({
+				id: i,
+				source: graf.edges[i].a,
+				target: graf.edges[i].b,
+				size: Math.min(4, Math.max((7/(2*Math.pow(20, 2)))*Math.pow(graf.edges[i].votes, 2) + 1/2, 0.5))
+			});
+		
+		}
+
+		s.bind('clickNode', function(e) {			
+			var nodeId = e.data.node.id,
+				toKeep = s.graph.neighbors(nodeId);
+				// toKeep[nodeId] = e.data.node;
+			
+			
+			s.graph.nodes().forEach(function(n) {
+				if (toKeep[n.id] || n.id == nodeId) {
+					n.color = n.originalColor;
+				} else {
+					n.color = '#333';
+				}
+			});
+
+			s.graph.edges().forEach(function(e) {
+				if ((e.source == nodeId || e.target == nodeId) && (toKeep[e.source] || toKeep[e.target])) {
+					e.color = '#fff';
+				} else {
+					e.color = '#333';
+				}
+			});
+			
+			if (circleMode) {
+				s.graph.nodes().forEach(function (n) {
+					n.x = n.circleX;
+					n.y = n.circleY;
+					n.size = 10;
+				});
+				
+				e.data.node.x = 0;
+				e.data.node.y = 0;
+				e.data.node.size = 30;
+			}
+			
+			s.refresh();
+
+			dialog.show(nodeId, toKeep);
+		});
+
+
+		s.refresh();
+		initSearchBar();
+
+		autocomplete(document.querySelector("#search-input"), graf.nodes, "search");
+	});
+}
+
+function updateSigma() {
+	// returns set of neighouts
+	sigma.classes.graph.addMethod("neighbors", function(nodeId) {
+		var k,
+		neighbors = {},
+		index = this.allNeighborsIndex[nodeId] || [];
+
+		for (k in index) {
+			neighbors[k] = this.nodesIndex[k];
+		}
+
+		return neighbors;
+	});
+	
+	// returns number of neighbours from a set of years
+	sigma.classes.graph.addMethod("numNeighborsFromYears", function(nodeId, showYearsCopy) {
+		var k,
+		neighbors = 0,
+		index = this.allNeighborsIndex[nodeId] || [];
+
+		for (k in index) {
+			if(this.nodesIndex){
+				if (showYearsCopy.has("" + this.nodesIndex[k].year)) neighbors++;
+				else if (this.nodesIndex[k].year == 0) neighbors++;
+			}
+		}
+		
+		return neighbors;
+	});
+}
+
+
+// *********** HERE STARTS limit-years.js *************
+
+window.addEventListener("load", addYearList);
+
+var limitYears = false;
+var showYears = new Set();
+
+function repaint() {
+	//targetYear: graf.nodes[e.source].year,
+	if(limitYears) {
+		var added = new Set();
+		
+		s.graph.nodes().forEach(function(n) {
+			var numNeig = s.graph.numNeighborsFromYears(n.id, showYears);
+			
+			if ((n.year == 0 && (n.sex == 'F' || n.sex == 'M') )
+					|| numNeig == 0
+					|| (!showYears.has("" + n.year) && (n.year != 0) )) {
+				n.hidden = true;
+			}
+			else {
+				n.hidden = false;
+				added.add(n.id);
+			}
+		});
+		
+		s.graph.edges().forEach(function(e) {
+			if(!added.has(e.source) && !added.has(e.target)){
+				e.hidden = true;
+			}
+			else e.hidden = false;
+		}); 
+	}
+	else {
+		s.graph.nodes().forEach(function(n) {
+			n.hidden = false;
+		});
+		
+		s.graph.edges().forEach(function(e) {
+			e.hidden = false;
+		});
+	}
+}
+
+function altYearList() {
+	var yearlist = document.querySelector("#year-list");
+	
+	if(yearlist.style.display == "none"){
+		yearlist.style.display = "block";
+		document.querySelector("#settings i").innerText = "close";
+		yearLimits = true;
+	}
+	else{
+		yearlist.style.display = "none";
+		document.querySelector("#settings i").innerText = "settings";
+		yearLimits = true;
+	}
+}
+
+function addYearList() {	
+	var ylistspan = document.querySelector("#year-list-span")
+	for(var year=2006; year<2019; year++) {
+		var yin = document.createElement("input");
+		yin.type = "checkbox";
+		yin.class = "mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored";
+		yin.name = "" + year;
+		yin.addEventListener("change", function(){ 
+			limitYears = true;
+			
+			if(this.checked) {
+				showYears.add(this.name);
+			}
+			else {
+				showYears.delete(this.name);
+			}
+			
+			if(showYears.size == 0) limitYears = false;
+			
+			repaint();
+			
+			s.refresh();
+		});
+		
+		var lab = document.createElement("label");
+		lab.innerHTML = "" + year + "<br>";
+		
+		ylistspan.appendChild(yin);
+		ylistspan.appendChild(lab);
+	}
+	
+	document.querySelector("#settings").addEventListener("click", altYearList);
+}
+
+// *********** HERE STARTS search-bar.js *************
+
+
+function altSearchBar() {
+	if (document.querySelector(".md-google-search__metacontainer").style.display == "none") {
+		document.querySelector(".md-google-search__metacontainer").style.display = "block";
+		document.querySelector("#search i").innerText = "fullscreen";
+	} else {
+		document.querySelector(".md-google-search__metacontainer").style.display = "none";
+		document.querySelector(".autocomplete-container").style.display = "none";
+		document.querySelector("#search i").innerText = "search";
+	}
+}
+
+function initSearchBar() {
+	document.querySelector("#search").addEventListener("click", altSearchBar);
+	if (window.innerWidth > 700) altSearchBar();
+}
+// *********** HERE STARTS dialog.js *************
+
+window.addEventListener("load", initDialog);
+
+var dialog = {
+	fill: function(data, text, html=false) {
+		var el = document.querySelectorAll("*[data-fill=\""+data+"\"]");
+		for (var i in el) {
+			if (html === true) {
+				el[i].innerHTML = text;
+			} else {
+				el[i].innerText = text;
+			}
+		}
+	},
+	show: function(id, neighbors) {
+		var neighbors = Object.values(neighbors);
+
+		this.fill("name", graf.nodes[id].name);
+		this.fill("year", graf.nodes[id].year);
+		this.fill("sex", graf.nodes[id].sex);
+		this.fill("id", "#"+id);
+		this.fill("n-edges", neighbors.length);
+
+		var list = "";
+		neighbors.forEach(function (a) {
+			list += "<li><b>"+graf.nodes[id].name+" - "+a.label+":</b> "+(graf.edges[id+"_"+a.id] ? graf.edges[id+"_"+a.id].votes : graf.edges[a.id+"_"+id].votes)+" vots</li>";
+		});
+		this.fill("edges", list, true);
+
+		if (window.innerWidth > 700) {
+			document.querySelector("#dialog").style.display = "block";
+			document.querySelector("#backdrop-container").style.display = "block";
+		} else {
+			document.querySelector("#summary-dialog").style.display = "block";
+		}
+	},
+	close: function() {
+		document.querySelector("#dialog").style.display = "none";
+		document.querySelector("#summary-dialog").style.display = "none";
+		document.querySelector("#backdrop-container").style.display = "none";
+
+		s.graph.nodes().forEach(function(n) {
+			n.color = n.originalColor;
+		});
+
+		s.graph.edges().forEach(function(e) {
+			e.color = e.originalColor;
+		});
+
+		if(circleMode) {
+			s.graph.nodes().forEach(function (n) {
+				n.x = n.circleX;
+				n.y = n.circleY;
+				n.size = 10;
+			});
+		}
+		else {
+			s.graph.nodes().forEach(function (n) {
+				n.x = n.originalX;
+				n.y = n.originalY;
+				n.size = 10;
+			});
+		}
+		s.refresh();
+
+	},
+	max: function() {
+		document.querySelector("#summary-dialog").style.display = "none";
+		document.querySelector("#dialog").style.display = "block";
+	},
+	min: function() {
+		document.querySelector("#dialog").style.display = "none";
+		document.querySelector("#summary-dialog").style.display = "block";
+	}
+};
+
+
+function initDialog() {
+	document.querySelector("#quit-dialog").addEventListener("click", dialog.close);
+	document.querySelector("#quit2-dialog").addEventListener("click", dialog.close);
+	document.querySelector("#max-dialog").addEventListener("click", dialog.max);
+	document.querySelector("#min-dialog").addEventListener("click", dialog.min);
+}
+
+// *********** HERE STARTS camera.js *************
+
+
+window.addEventListener('load', initCamera);
+
+function cameraGoto(nodeX, nodeY) {
+	sigma.misc.animation.camera( s.camera,
+		{ x: nodeX, y: nodeY, ratio: 1 },
+		{ duration: s.settings('animationsTime') || 300 }
+	);
+}
+
+function is_touch_device() {
+	  var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
+	  var mq = function(query) {
+	    return window.matchMedia(query).matches;
+	  }
+
+	  if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
+	    return true;
+	  }
+
+	  // include the 'heartz' as a way to have a non matching MQ to help terminate the join
+	  // https://git.io/vznFH
+	  var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
+	  return mq(query);
+}
+
+function initCamera() {
+	
+	if(!is_touch_device()) {
+		
+		document.querySelector("#zoomin").addEventListener("click", function() {
+			s.camera.goTo({
+				ratio: Math.max(s.camera.settings("zoomMin"), s.camera.ratio / Math.sqrt(2))
+			});
+		});
+	
+		document.querySelector("#zoomout").addEventListener("click", function() {
+			s.camera.goTo({
+				ratio: Math.min(s.camera.settings("zoomMax"), s.camera.ratio * Math.sqrt(2))
+			});
+		});
+	}
+	else{
+		document.querySelector("#zoomin").style.display = "none";
+		document.querySelector("#zoomout").style.display = "none";
+		
+		document.querySelector("#circle-mode").style.bottom = "110px";
+		document.querySelector("#settings").style.bottom = "60px";
+		document.querySelector("#search").style.bottom = "10px";
+	}
+}
+
+// *********** HERE STARTS easter-egg.js *************
+
+window.addEventListener("load", initEasterEgg);
+
+var seq = [38, 38, 40, 40, 37, 39, 37, 39, 65, 66, 13];
+var cur = 0;
+
+function justdoit() {
+	s.graph.nodes().forEach(function(n) {
+		switch(n.color) {
+			case "#d61c08":
+			n.color = "#0159aa";
+			break;
+
+			case "#0159aa":
+			n.color = "#0ca80a";
+			break;
+
+			case "#0ca80a":
+			n.color = "#d61c08";
+			break;
+		}
+	});
+
+	s.refresh();
+	setTimeout(justdoit, 333);
+}
+
+
+function initEasterEgg() {
+	document.addEventListener("keydown", function() {
+		if (event.key == "f" && event.target.getAttribute("id") != "search-input") altSearchBar();
+		if (event.which == seq[cur]) {
+			if (cur < seq.length) {
+				++cur;
+				if (cur == seq.length) {
+					justdoit();
+				}
+			}
+		} else cur = 0;
+	});
+}
