<commit_before>var cymineDataFormatter = require('./dataFormatter'),
imjs          = require('./../bower_components/imjs/js/im.js'),
cytoscape     = require('cytoscape'),
_             = require('underscore'),
strings       = require('./strings'),
query         = require('./query'),
cymineDisplay = require('./ui');

function Cymine(args) {

  var ui,
  graph = _.extend({},args);
  init();

/**
 * Checks if there is indeed an element to attach to, and failing that tries a default.
 * @return {boolean} whether or not we've found an element to attach to. Allows you to cancel the xhr
 *                          since there's nowhere to render it to.
 */
  function validateParent() {
    if(!graph.parentElem){
      var defaultElem = document.getElementById('cymine');
      if(defaultElem) {
        graph.parentElem = defaultElem;
        console.info(strings.dev.noParent.usingDefault);
      } else {
        console.error(strings.dev.noParent.noDefault);
        return false;
      }
    }
    return true;
  }
  function validateServiceRoot(){
    if(graph.service){
      return new imjs.Service({
        token: graph.service.token,
        root: graph.service.root,
        errorHandler : badServiceError
      });
    } else {
      throw new initError('noServiceUrl');
      return false;
    }

  }
  function prepQuery() {
    if(graph.queryOn) {
      debugger;
      _.extend(query.where[0],graph.queryOn);
      return true;
    } else {
      throw new initError('noQueryData');
      return false;
    }
  }
  function init(){
    debugger;
    if(validateParent()) {
      ui = new cymineDisplay(graph);
      var mine = validateServiceRoot();
      if(prepQuery() && mine) {
        mine.records(query).then(function(response) {
          if (response.length > 0) {
            graph.data = new cymineDataFormatter(response);
            ui.init();
            console.debug('response:', response, 'graphdata:', graph);
          } else {
            ui.init(strings.user.noResults);
          }
        });
      }
    }
  }
  /**
   * throw this error to console.error and display a user-facing error too
   * @param  {string} devMessage  this should be the key to a string in the strings.dev object.
   * @param  {[type]} userMessage optional - this should be the key to a string in the strings.user object. If not set, it will use the generic strings.user.noQuery message.
   */
  function initError(devMessage, userMessage){
    var um = userMessage ? userMessage : "noQueryData";
    ui.init(strings.user[um]);
    console.error(strings.dev[devMessage]);
  }
}
/**
 * helper method for calling services from imjs. Useful because we can only pass a reference to a functtion (without args) to imjs, so passing initError wouldn't allow us to set the dev error message.
 * @return {[type]} [description]
 */
function badServiceError(){
    throw new initError('badServiceUrl');
}

module.exports = Cymine;
<commit_msg>Removed debugger statemen (oops).<commit_after>var cymineDataFormatter = require('./dataFormatter'),
imjs          = require('./../bower_components/imjs/js/im.js'),
cytoscape     = require('cytoscape'),
_             = require('underscore'),
strings       = require('./strings'),
query         = require('./query'),
cymineDisplay = require('./ui');

function Cymine(args) {

  var ui,
  graph = _.extend({},args);
  init();

/**
 * Checks if there is indeed an element to attach to, and failing that tries a default.
 * @return {boolean} whether or not we've found an element to attach to. Allows you to cancel the xhr
 *                          since there's nowhere to render it to.
 */
  function validateParent() {
    if(!graph.parentElem){
      var defaultElem = document.getElementById('cymine');
      if(defaultElem) {
        graph.parentElem = defaultElem;
        console.info(strings.dev.noParent.usingDefault);
      } else {
        console.error(strings.dev.noParent.noDefault);
        return false;
      }
    }
    return true;
  }
  function validateServiceRoot(){
    if(graph.service){
      return new imjs.Service({
        token: graph.service.token,
        root: graph.service.root,
        errorHandler : badServiceError
      });
    } else {
      throw new initError('noServiceUrl');
      return false;
    }

  }
  function prepQuery() {
    if(graph.queryOn) {
      debugger;
      _.extend(query.where[0],graph.queryOn);
      return true;
    } else {
      throw new initError('noQueryData');
      return false;
    }
  }
  function init(){
    if(validateParent()) {
      ui = new cymineDisplay(graph);
      var mine = validateServiceRoot();
      if(prepQuery() && mine) {
        mine.records(query).then(function(response) {
          if (response.length > 0) {
            graph.data = new cymineDataFormatter(response);
            ui.init();
            console.debug('response:', response, 'graphdata:', graph);
          } else {
            ui.init(strings.user.noResults);
          }
        });
      }
    }
  }
  /**
   * throw this error to console.error and display a user-facing error too
   * @param  {string} devMessage  this should be the key to a string in the strings.dev object.
   * @param  {[type]} userMessage optional - this should be the key to a string in the strings.user object. If not set, it will use the generic strings.user.noQuery message.
   */
  function initError(devMessage, userMessage){
    var um = userMessage ? userMessage : "noQueryData";
    ui.init(strings.user[um]);
    console.error(strings.dev[devMessage]);
  }
}
/**
 * helper method for calling services from imjs. Useful because we can only pass a reference to a functtion (without args) to imjs, so passing initError wouldn't allow us to set the dev error message.
 * @return {[type]} [description]
 */
function badServiceError(){
    throw new initError('badServiceUrl');
}

module.exports = Cymine;
<|endoftext|>


<commit_before>$(function() {
    var sentences = [
        "Let me put on my slippers first.",
        "I don't want to sit next to Dominik.",
        "Skype me a Hipchat message on my e-mail.",
        "Sorry, reinstalling Windows. Try again in 8 hours.",
        "Try Google.",
        "Are you still chewing? Let me know when your mouth is ready.",
        "Are you sure your computer is plugged in?",
        "Boot in safe mode.",
        "Call the care police.",
        "I can grill some meat."
    ];
    var getRandomInteger = function(min, max) {
        return Math.floor((Math.random() * max) + min);
    };

    var randomInteger = getRandomInteger(0, sentences.length - 1);

    var randomSentence = sentences[getRandomInteger(0, sentences.length - 1)];

    $(".sentence").append(randomSentence);
});<commit_msg>Updated with more phrases<commit_after>$(function() {
    var sentences = [
        "Let me put on my slippers first.",
        "I don't want to sit next to Dominik.",
        "Skype me a Hipchat message on my e-mail.",
        "Sorry, reinstalling Windows. Try again in 8 hours.",
        "I can grill some meat.",
        "Only if you have an ID and are above 18 y.o.",
        "Sorry, I don't know how giftcards work. Can't help you.",
        "Just use duct tape.",
        "One Mozzarella salad.",
        "Live long and prosper.",
        "My old PC is VR-ready"
    ];
    var getRandomInteger = function(min, max) {
        return Math.floor((Math.random() * max) + min);
    };

    var randomInteger = getRandomInteger(0, sentences.length - 1);

    var randomSentence = sentences[getRandomInteger(0, sentences.length - 1)];

    $(".sentence").append(randomSentence);
});
<|endoftext|>


<commit_before>var map;
function init() {
    var apisToLoad;
    var loadCallback = function() {
        if (--apisToLoad == 0) {
            signin(true, userAuthed);
        }
    };
    $("#signInButton").text("Signing in ...");
    apisToLoad = 2;
    apiRoot = 'https://donate-backend.appspot.com/_ah/api';
    apiRoot = 'http://192.168.42.46:8080/_ah/api';
    gapi.client.load('donate', 'v1', loadCallback, apiRoot);
    gapi.client.load('oauth2', 'v2', loadCallback);
}

function signin(mode, authorizeCallback) {
    gapi.auth.authorize({client_id:"760560844994-04u6qkvpf481an26cnhkaauaf2dvjfk0.apps.googleusercontent.com",
        scope: "profile", immediate: mode},
        authorizeCallback);
}

function userAuthed() {
    var request =
    gapi.client.oauth2.userinfo.get().execute(function(resp) {
        if (!resp.code) {
            signedIn();
        }
    });
}

function auth() {
    signin(false, userAuthed);
};

function deauth() {
    gapi.auth.setToken(null)
    $("#signInButton").show();
    $("#signInButton").text("Sign in");
    $("#signOutButton").hide();
};

function signedIn() {
    $("#signInButton").hide();
    $("#signOutButton").show();
}

$("#faq_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#faq_link').parent().addClass('active');
    loadFAQ();
});
$("#home_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#home_link').parent().addClass('active');
    showHome();
});
$("#sharing_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#sharing_link').parent().addClass('active');
    loadSharing();
});
$("#map_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#map_link').parent().addClass('active');
});
function loadFAQ() {
    $("#home").hide();
    $("#sharing").hide();
    $("#faq").show();
    $("#map_container").hide();
    gapi.client.donate.faqcat.list().execute(function(cats) {
        gapi.client.donate.faqitem.list().execute(function(items) {
            var items_by_cat = {};
            var html = "";
            items.items.forEach(function parseItems(item, index, all) {
                console.log(item);
                if (item.category in items_by_cat) {
                    items_by_cat[item.category].push(item);
                } else {
                    items_by_cat[item.category] = [item];
                }
            })
            cats.items.forEach(function generateHTML(cat, catindex, all) {
                console.log(cat);
                html += "
"+cat.name+"
";
                items = items_by_cat[cat.id];
                if (items != undefined) {
                    html += "
";
                    items.forEach(function addQuestionToHTML(item, index, all) {
                        html += '

';
                        html += item.question;
                        html += '

';
                        html += item.answer;
                        html += '

';
                    })
                    html += '
';
                }

            })
            $("#faq").html(html);
        });
    });

}
function loadSharing() {
    $("#home").hide();
    $("#sharing").show();
    $("#faq").hide();
    $("#map_container").hide();
}
function showHome() {
    $("#home").show();
    $("#sharing").hide();
    $("#faq").hide();
    $("#map_container").hide();
}
function showMap() {
    $("#home").hide();
    $("#sharing").hide();
    $("#faq").hide();
    $("#map_container").show();
    loadMapIfNeeded();
}
function onLocationFound(e) {
    var radius = e.accuracy / 2;

    L.circle(e.latlng, radius).addTo(map);
}
function insertJSON() {
  $.getJSON('https://raw.githubusercontent.com/germany-says-welcome/refugees-welcome-app/master/app/src/main/assets/authorities.json', function(data) {
    data.forEach(function (entry) {
      var popup = entry.telefon ? entry.adresse + '
' : '';
      popup += entry.telefon ? ' ' + entry.telefon + '   ' : '';
      popup += entry.fax ? ' ' + entry.fax + '
' : '';
      popup += entry.offnungszeiten ? ' ' + entry.offnungszeiten + '
' : '';
      popup += entry.website ? ' ' + entry.website + '
' : '';
      popup += 'Data from www.amt-de.com';

      L.marker([entry.location.lat, entry.location.lng]).addTo(map)
        .bindPopup(popup);
    });
  });
}
function loadMap() {
    map = L.map('map').setView([50.9485795, 6.9448561], 13);
    mapLink =
        'OpenStreetMap';
    L.tileLayer(
        'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© ' + mapLink + ' Contributors',
        maxZoom: 18,
        }).addTo(map);
    map.locate({setView: true, maxZoom: 16});
    map.on('locationfound', onLocationFound);
    insertJSON();
}
function loadMapIfNeeded() {
    if (map == undefined) {
        loadMap();
    }
}
$("#map_container").hide();<commit_msg>dont push lokal ip<commit_after>var map;
function init() {
    var apisToLoad;
    var loadCallback = function() {
        if (--apisToLoad == 0) {
            signin(true, userAuthed);
        }
    };
    $("#signInButton").text("Signing in ...");
    apisToLoad = 2;
    apiRoot = 'https://donate-backend.appspot.com/_ah/api';
    //apiRoot = 'http://192.168.42.46:8080/_ah/api';
    gapi.client.load('donate', 'v1', loadCallback, apiRoot);
    gapi.client.load('oauth2', 'v2', loadCallback);
}

function signin(mode, authorizeCallback) {
    gapi.auth.authorize({client_id:"760560844994-04u6qkvpf481an26cnhkaauaf2dvjfk0.apps.googleusercontent.com",
        scope: "profile", immediate: mode},
        authorizeCallback);
}

function userAuthed() {
    var request =
    gapi.client.oauth2.userinfo.get().execute(function(resp) {
        if (!resp.code) {
            signedIn();
        }
    });
}

function auth() {
    signin(false, userAuthed);
};

function deauth() {
    gapi.auth.setToken(null)
    $("#signInButton").show();
    $("#signInButton").text("Sign in");
    $("#signOutButton").hide();
};

function signedIn() {
    $("#signInButton").hide();
    $("#signOutButton").show();
}

$("#faq_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#faq_link').parent().addClass('active');
    loadFAQ();
});
$("#home_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#home_link').parent().addClass('active');
    showHome();
});
$("#sharing_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#sharing_link').parent().addClass('active');
    loadSharing();
});
$("#map_link").click(function() {
    $('nav').removeClass('fixed');
    $('nav li.active').removeClass('active');
    $('nav a#map_link').parent().addClass('active');
});
function loadFAQ() {
    $("#home").hide();
    $("#sharing").hide();
    $("#faq").show();
    $("#map_container").hide();
    gapi.client.donate.faqcat.list().execute(function(cats) {
        gapi.client.donate.faqitem.list().execute(function(items) {
            var items_by_cat = {};
            var html = "";
            items.items.forEach(function parseItems(item, index, all) {
                console.log(item);
                if (item.category in items_by_cat) {
                    items_by_cat[item.category].push(item);
                } else {
                    items_by_cat[item.category] = [item];
                }
            })
            cats.items.forEach(function generateHTML(cat, catindex, all) {
                console.log(cat);
                html += "
"+cat.name+"
";
                items = items_by_cat[cat.id];
                if (items != undefined) {
                    html += "
";
                    items.forEach(function addQuestionToHTML(item, index, all) {
                        html += '

';
                        html += item.question;
                        html += '

';
                        html += item.answer;
                        html += '

';
                    })
                    html += '
';
                }

            })
            $("#faq").html(html);
        });
    });

}
function loadSharing() {
    $("#home").hide();
    $("#sharing").show();
    $("#faq").hide();
    $("#map_container").hide();
}
function showHome() {
    $("#home").show();
    $("#sharing").hide();
    $("#faq").hide();
    $("#map_container").hide();
}
function showMap() {
    $("#home").hide();
    $("#sharing").hide();
    $("#faq").hide();
    $("#map_container").show();
    loadMapIfNeeded();
}
function onLocationFound(e) {
    var radius = e.accuracy / 2;

    L.circle(e.latlng, radius).addTo(map);
}
function insertJSON() {
  $.getJSON('https://raw.githubusercontent.com/germany-says-welcome/refugees-welcome-app/master/app/src/main/assets/authorities.json', function(data) {
    data.forEach(function (entry) {
      var popup = entry.telefon ? entry.adresse + '
' : '';
      popup += entry.telefon ? ' ' + entry.telefon + '   ' : '';
      popup += entry.fax ? ' ' + entry.fax + '
' : '';
      popup += entry.offnungszeiten ? ' ' + entry.offnungszeiten + '
' : '';
      popup += entry.website ? ' ' + entry.website + '
' : '';
      popup += 'Data from www.amt-de.com';

      L.marker([entry.location.lat, entry.location.lng]).addTo(map)
        .bindPopup(popup);
    });
  });
}
function loadMap() {
    map = L.map('map').setView([50.9485795, 6.9448561], 13);
    mapLink =
        'OpenStreetMap';
    L.tileLayer(
        'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© ' + mapLink + ' Contributors',
        maxZoom: 18,
        }).addTo(map);
    map.locate({setView: true, maxZoom: 16});
    map.on('locationfound', onLocationFound);
    insertJSON();
}
function loadMapIfNeeded() {
    if (map == undefined) {
        loadMap();
    }
}
$("#map_container").hide();<|endoftext|>


<commit_before>
// Wait for user to finish typing
// callback: The callback function
// wait: The number of milliseconds to wait after the the last key press before firing the callback
// highlight: Highlights the element when it receives focus
// allowSubmit: Allows a non-multiline element to be submitted (enter key) regardless of captureLength
// captureLength: Minimum # of characters necessary to fire the callback

$(document).ready(function() {

	//stop loader.gif and overlay
	stop_loader();
	//enable typewatch
	//$('#street').typeWatch({
	//	captureLength: 2,
	//	wait: 1750,
    	//	highlight: true,
	//	callback: function(value) {
	//		//alert("typing finished");
	//		street_to_geo(value);
	//	}
	//});
});

function start_loader(){
	$('#loader').fadeIn('slow');
	$('#overlay').fadeIn('slow');
}

function stop_loader(){
	$('#loader').fadeOut('slow');
	$('#overlay').fadeOut('slow');
}

function addMyRoute(id, name, street, rating, lat, lng){
	$.ajax({
  		method: "GET",
  		url: "/php/addMyRoute.php",
  		data: { id: id, name: name, street: street, rating: rating, lat: lat, lng: lng}
	})
  	.done(function( msg ) {
		//alert("finished");
    	alert(msg);
  	});
}

function showDetails(id){

}

function geo_to_street(lat,long){
	var uri = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" + lat + "&lon=" + long + "&zoom=18&addressdetails=1";
	$.getJSON(uri, function(data) {

        var obj = {road: data.address.road, city: data.address.city, house_number: data.address.house_number, country: data.address.country };

		var string = obj.road + " " + obj.house_number + " " + obj.city + " " + obj.country;
		$('#street').val(string);
		stop_loader();
    });
}

function street_to_geo(){
    start_loader();
    var street = $('#street').val();
    if(street == "") {alert("please enter your starting position!"); stop_loader(); return;}
    //encodes the street string into url friendly format
    var street_encoded = encodeURIComponent(street);
    var uri = "https://nominatim.openstreetmap.org/search/" + street_encoded + "?format=json";
    //alert(uri);
    //makes the the jquery call and gets json back
    $.getJSON(uri, function(data) {
	    //make js obj containing lat and long
		if(data==""){alert("starting position not found"); stop_loader(); return;}

	    var obj = {latitude: data[0].lat, longitude: data[0].lon};
		//return obj;
		//stop_loader();
	        //alert(obj.latitude + " " + obj.longitude);

		get_places2(obj.latitude, obj.longitude);

		//get_places(obj.latitude, obj.longitude);
	        //return obj;
    });
}

function calc_distance(lat1, lon1, lat2, lon2) {
	var unit = "K";
	var radlat1 = Math.PI * lat1/180;
	var radlat2 = Math.PI * lat2/180;
	var theta = lon1-lon2;
	var radtheta = Math.PI * theta/180;
	var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
	dist = Math.acos(dist);
	dist = dist * 180/Math.PI;
	dist = dist * 60 * 1.1515;
	if (unit=="K") { dist = dist * 1.609344; }
	if (unit=="N") { dist = dist * 0.8684; }
	return dist;
}

function get_places(lat, long) {
	var category = $('#category').val();

	$.ajax({
  		method: "GET",
  		url: "/php/get_places.php",
  		data: { lat: lat, long: long, radius: "1000", type: category }
	})
  	.done(function( msg ) {
		//alert("finished");
    	$('#main-area').html(msg);
		stop_loader();
  	});
}

function get_places2(lat, long) {
	var category = $('#category').val();

	$.ajax({
  		method: "GET",
  		url: "/php/get_places2.php",
  		data: { lat: lat, long: long, radius: "1000", type: category }
	})
  	.done(function( msg ) {
  		msg = JSON.parse(msg)
		//alert("finished");
    	//$('#main-area').html(msg);
    	add_details(msg, lat, long)
    	sort_json(msg, 'rating_over_distance', false);
    	$('#main-area').html(json_to_table(msg));
		stop_loader();
  	});
}

function json_to_table(json_object) {
	var str = "
";
	str += "

Name

Street

Rating

Distance

is open?

";

	for(i in json_object) {
		var placeid = json_object[i].place_id;
		if(placeid == "") {break;}
		str += "

";
		str += "
" + json_object[i].name + "
";
		str += "
" + json_object[i].vicinity + "
";
		str += "
" + json_object[i].rating + "
";
		str += "
" + json_object[i].distance + "
";
		if (json_object[i].opening_hours) {
			if (json_object[i].opening_hours.open_now) {
				str += "
" +
					""
					+ "
";
			} else {
				str += "
" +
					""
					+ "
";
			}
		}
		str +="
";
		var name = encodeURI(json_object[i].name);
		var street = encodeURI(json_object[i].vicinity);
		street = street.replace(",","-");
		var rating = json_object[i].rating;
		var lat = json_object[i].geometry.location.lat;
		var lng = json_object[i].geometry.location.lng;

		str += "
 add
";
		str += "
";
	}

	return str;
}

function add_details(json_object, lat, long) {
	for (x in json_object) {
		json_object[x].distance = Math.round(1000 * calc_distance(lat, long, json_object[x].geometry.location.lat, json_object[x].geometry.location.lng));
		json_object[x].rating_over_distance = json_object[x].rating/json_object[x].distance;
	}
}

function sort_json(json_object, key_to_sort_by, ascending) {
    function sortByKey(a, b) {
        var x = a[key_to_sort_by];
        var y = b[key_to_sort_by];
        if (ascending ==  true) {
        	return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        } else {
        	return ((x > y) ? -1 : ((x < y) ? 1 : 0));
        }
    }
    json_object.sort(sortByKey);
}

//returns a Coordinate, could add some other functionality of what to do when geolocation is not supported
var pos;
function get_my_location(){
	start_loader();
	var options = {
	    enableHighAccuracy: true
	};
	if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
	        pos = {
	            lat: position.coords.latitude,
	            lng: position.coords.longitude
	        };

		    // return pos;
		    $('#street').val("");
			var location = pos.lat + " " + pos.lng;
		    geo_to_street(pos.lat,pos.lng);
		    //stop_loader();
			//alert(location);
		    //get_places(pos.lat,pos.lng);
        },
        function(err){
	        stop_loader(); alert("could not get device position");
      	},
        options);
    }
}

function get_weather(lat, lon){
	//if the function does not work, maybe the get_json.php should be in root, or path should be js/get_json.php
    var api_url = "js/get_json.php?";
    var type = "type=weather"

	api_request = api_url;
    api_request += type;
    api_request += "&lat="
    api_request += lat;
    api_request += "&lon="
    api_request += lon;

    //document.write(api_request);

    $(function () {
        $.getJSON(
            api_request,
            function (data) {
                $("#reply").html(JSON.stringify(data));
                return(JSON.stringify(data.weather[0].main));
            });
    });
}
<commit_msg>Update main.js<commit_after>
// Wait for user to finish typing
// callback: The callback function
// wait: The number of milliseconds to wait after the the last key press before firing the callback
// highlight: Highlights the element when it receives focus
// allowSubmit: Allows a non-multiline element to be submitted (enter key) regardless of captureLength
// captureLength: Minimum # of characters necessary to fire the callback

$(document).ready(function() {

	//stop loader.gif and overlay
	stop_loader();
	//enable typewatch
	//$('#street').typeWatch({
	//	captureLength: 2,
	//	wait: 1750,
    	//	highlight: true,
	//	callback: function(value) {
	//		//alert("typing finished");
	//		street_to_geo(value);
	//	}
	//});
});

function start_loader(){
	$('#loader').fadeIn('slow');
	$('#overlay').fadeIn('slow');
}

function stop_loader(){
	$('#loader').fadeOut('slow');
	$('#overlay').fadeOut('slow');
}

function addMyRoute(id, name, street, rating, lat, lng){
	$.ajax({
  		method: "GET",
  		url: "/php/addMyRoute.php",
  		data: { id: id, name: name, street: street, rating: rating, lat: lat, lng: lng}
	})
  	.done(function( msg ) {
		//alert("finished");
    	alert(msg);
  	});
}

function showDetails(id){

}

function geo_to_street(lat,long){
	var uri = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" + lat + "&lon=" + long + "&zoom=18&addressdetails=1";
	$.getJSON(uri, function(data) {

        var obj = {road: data.address.road, city: data.address.city, house_number: data.address.house_number, country: data.address.country };

		var string = obj.road + " " + obj.house_number + " " + obj.city + " " + obj.country;
		$('#street').val(string);
		stop_loader();
    });
}

function street_to_geo(){
    start_loader();
    var street = $('#street').val();
    if(street == "") {alert("please enter your starting position!"); stop_loader(); return;}
    //encodes the street string into url friendly format
    var street_encoded = encodeURIComponent(street);
    var uri = "https://nominatim.openstreetmap.org/search/" + street_encoded + "?format=json";
    //alert(uri);
    //makes the the jquery call and gets json back
    $.getJSON(uri, function(data) {
	    //make js obj containing lat and long
		if(data==""){alert("starting position not found"); stop_loader(); return;}

	    var obj = {latitude: data[0].lat, longitude: data[0].lon};
		//return obj;
		//stop_loader();
	        //alert(obj.latitude + " " + obj.longitude);

		get_places2(obj.latitude, obj.longitude);

		//get_places(obj.latitude, obj.longitude);
	        //return obj;
    });
}

function calc_distance(lat1, lon1, lat2, lon2) {
	var unit = "K";
	var radlat1 = Math.PI * lat1/180;
	var radlat2 = Math.PI * lat2/180;
	var theta = lon1-lon2;
	var radtheta = Math.PI * theta/180;
	var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
	dist = Math.acos(dist);
	dist = dist * 180/Math.PI;
	dist = dist * 60 * 1.1515;
	if (unit=="K") { dist = dist * 1.609344; }
	if (unit=="N") { dist = dist * 0.8684; }
	return dist;
}

function get_places(lat, long) {
	var category = $('#category').val();

	$.ajax({
  		method: "GET",
  		url: "/php/get_places.php",
  		data: { lat: lat, long: long, radius: "1000", type: category }
	})
  	.done(function( msg ) {
		//alert("finished");
    	$('#main-area').html(msg);
		stop_loader();
  	});
}

function get_places2(lat, long) {
	var category = $('#category').val();

	$.ajax({
  		method: "GET",
  		url: "/php/get_places2.php",
  		data: { lat: lat, long: long, radius: "1000", type: category }
	})
  	.done(function( msg ) {
  		msg = JSON.parse(msg)
		//alert("finished");
    	//$('#main-area').html(msg);
    	add_details(msg, lat, long)
    	sort_json(msg, 'rating_over_distance', false);
    	$('#main-area').html(json_to_table(msg));
		stop_loader();
  	});
}

function json_to_table(json_object) {
	var str = "
";
	str += "

Name

Street

Rating

Distance

is open?

";

	for(i in json_object) {
		var placeid = json_object[i].place_id;
		if(placeid == "") {break;}
		str += "

";
		str += "
" + json_object[i].name + "
";
		str += "
" + json_object[i].vicinity + "
";
		str += "
" + json_object[i].rating + "
";
		str += "
" + json_object[i].distance + "
";
		if (json_object[i].opening_hours) {
			if (json_object[i].opening_hours.open_now) {
				str += "
" +
					""
					+ "
";
			} else {
				str += "
" +
					""
					+ "
";
			}
		}
		str +="
";
		var name = encodeURI(json_object[i].name);
		var street = encodeURI(json_object[i].vicinity);
		//street = street.replace(",","-");
		var rating = json_object[i].rating;
		var lat = json_object[i].geometry.location.lat;
		var lng = json_object[i].geometry.location.lng;

		str += "
 add
";
		str += "
";
	}

	return str;
}

function add_details(json_object, lat, long) {
	for (x in json_object) {
		json_object[x].distance = Math.round(1000 * calc_distance(lat, long, json_object[x].geometry.location.lat, json_object[x].geometry.location.lng));
		json_object[x].rating_over_distance = json_object[x].rating/json_object[x].distance;
	}
}

function sort_json(json_object, key_to_sort_by, ascending) {
    function sortByKey(a, b) {
        var x = a[key_to_sort_by];
        var y = b[key_to_sort_by];
        if (ascending ==  true) {
        	return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        } else {
        	return ((x > y) ? -1 : ((x < y) ? 1 : 0));
        }
    }
    json_object.sort(sortByKey);
}

//returns a Coordinate, could add some other functionality of what to do when geolocation is not supported
var pos;
function get_my_location(){
	start_loader();
	var options = {
	    enableHighAccuracy: true
	};
	if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
	        pos = {
	            lat: position.coords.latitude,
	            lng: position.coords.longitude
	        };

		    // return pos;
		    $('#street').val("");
			var location = pos.lat + " " + pos.lng;
		    geo_to_street(pos.lat,pos.lng);
		    //stop_loader();
			//alert(location);
		    //get_places(pos.lat,pos.lng);
        },
        function(err){
	        stop_loader(); alert("could not get device position");
      	},
        options);
    }
}

function get_weather(lat, lon){
	//if the function does not work, maybe the get_json.php should be in root, or path should be js/get_json.php
    var api_url = "js/get_json.php?";
    var type = "type=weather"

	api_request = api_url;
    api_request += type;
    api_request += "&lat="
    api_request += lat;
    api_request += "&lon="
    api_request += lon;

    //document.write(api_request);

    $(function () {
        $.getJSON(
            api_request,
            function (data) {
                $("#reply").html(JSON.stringify(data));
                return(JSON.stringify(data.weather[0].main));
            });
    });
}
<|endoftext|>


<commit_before>var currentRecipe = null;
var currentState = null;

var updateView = function(text)
{
  $('#slideContent').html('
' + text.toUpperCase() + '
');
}

var applyRecipeData = function(recipeData)
{
  var stateArray = [];

  recipeData.steps.forEach(function(step)
  {
    stateArray[step.name] = step;
  });

  recipeData.steps = stateArray;

  currentRecipe = recipeData;
  currentState = currentRecipe.firstStep;

  updateView(currentRecipe.steps[currentState].content.mainText);
}

var nextState = function()
{
  if (currentState != null && currentRecipe != null)
  {
    currentState = currentRecipe.steps[currentState].nextStep;

    if (currentState != null)
    {
      updateView(currentRecipe.steps[currentState].content.mainText);
    }
    else
    {
      updateView('You\'re done!');
    }
  }
}

var requestFailed = function(jqxhr, textStatus, error)
{
  var err = textStatus + ", " + error;
  console.log( "Request Failed: " + err );
}

updateView('brekkie');

$.getJSON('recipes/crepes.json').done(applyRecipeData).fail(requestFailed);

$('#slideContent').click(nextState);
<commit_msg>did some moving/refactoring<commit_after>var currentRecipe = null;
var currentState = null;

var requestFailed = function(jqxhr, textStatus, error)
{
  var err = textStatus + ", " + error;
  console.log( "Request Failed: " + err );
}

var updateView = function(text)
{
  $('#slideContent').html('
' + text.toUpperCase() + '
');
}

var applyRecipeData = function(recipeData)
{
  var stateArray = [];

  recipeData.steps.forEach(function(step)
  {
    stateArray[step.name] = step;
  });

  recipeData.steps = stateArray;

  currentRecipe = recipeData;
  currentState = currentRecipe.firstStep;

  updateView(currentRecipe.steps[currentState].content.mainText);
}

var loadRecipe = function(recipeFileName)
{
  $.getJSON('recipes/' + recipeFileName + '.json').done(applyRecipeData).fail(requestFailed);
}

var nextState = function()
{
  if (currentState != null && currentRecipe != null)
  {
    currentState = currentRecipe.steps[currentState].nextStep;

    if (currentState != null)
    {
      updateView(currentRecipe.steps[currentState].content.mainText);
    }
    else
    {
      updateView('You\'re done!');
    }
  }
}

updateView('brekkie');

loadRecipe('crepes');

$('#slideContent').click(nextState);
<|endoftext|>


<commit_before>(function(globals){ // IIFE: Immediately Invoked Function Expression
})(window || module && module.exports || this);

(function(globals){ // IIFE: Immediately Invoked Function Expression
// Don't worry if that seems a little funky...

  /**
   * Internal representation of the game board in its current state.
   *
   * @see game.board
   * @see game.tracer
   * @see initial
   * @var {Array} of {Array} of {String|null}
   */
  var board = initial(); // initialize the `board`

  /**
   * List of moves for the "Catalan Opening: Closed Variation" suitable for use
   * as arguments to `applyMove` below.
   *
   * @see applyMove
   * @var {Array} of...?
   */
  var moves = [
    { from: { rank: 6, file: 3},
      to: { rank: 4, file: 3}
    },

    { from: { rank: 0, file: 6},
      to: { rank: 2, file: 5}
    },

    { from: { rank: 6, file: 2},
      to: { rank: 4, file: 2}
    },

    { from: { rank: 1, file: 4},
      to: { rank: 2, file: 4}
    },

    { from: { rank: 6, file: 6},
      to: { rank: 5, file: 6}
    },

    { from: { rank: 1, file: 3},
      to: { rank: 3, file: 3}
    },

    { from: { rank: 7, file: 5},
      to: { rank: 6, file: 6}
    },

    { from: { rank: 0, file: 5},
      to: { rank: 1, file: 4}
    },

    { from: { rank: 7, file: 6},
      to: { rank: 5, file: 5}
    }

    ]; // END moves

    // console.log(moves);
// [[6,3], [0,6], [6,2], [1,4], [6,6], [1,3], [7,5], [0,5], [7,6]],
// [[4,3], [2,5], [4,2], [2,4], [5,6], [3,3], [6,6], [1,4], [5,5]]
// var from = moves[0];
// var to = moves[1];
// console.log(from[[0]], to[[0]]);

  // var current = [[4,3], [2,5], [4,2], [2,4], [5,6], [3,3], [6,6], [1,4], [5,5]];

  // You don't need to understand `globals` yet...
  var game = (globals.game = {
    /**
     * Provide a _copy_ of the game board in order to update the View from it
     *
     * @return {Array} of {Array} of {String|null}
     */
    board: function(){
      return board.map(function(row){
        return row.slice();
      });
    },
    /**
     * Reset the internal game board to it's initial state.
     *
     * @return {Object} the game object for Method Chaining
     */
    reset: function(){
      board = initial();

      return this; // `this` referes to the object `reset` belongs to... AKA `game`
    },
    /**
     * Advance the internal game board to the next move.
     *
     * @return {Object} the game object for Method Chaining
     * @todo Make this work!
     */
    next: function(){
      // Doesn't this seem to be missing something?
      return this;
    },
    /**
     * Advance the internal game board to the previous move.
     *
     * @return {Object} the game object for Method Chaining
     * @todo Make this work!
     */
    prev: function(){
      // Another good place for code...
      return this;
    },
    /**
     * Advance the internal game board to the last move.
     *
     * @return {Object} the game object for Method Chaining
     * @todo Make this work!
     */
    end: function(){
      // Write some code here...
      return this;
    },
    /**
     * Provide a printable representation of the game board for use as a tracer
     *
     * @return {String} representation of `board`
     * @todo Refactor to use Array methods?
     */
    tracer: function(){
      var bullet = '';

      for ( var rank = 0; rank < board.length; rank++ ){
        bullet += '|';
        for ( var file = 0; file < board[rank].length; file++ ){
          bullet += (board[rank][file] || ' ') + '|';
        }
        bullet += '\n';
      }

      return bullet;
    },
    /**
     * Apply a move to the game board, given a `from` and `to` position that both
     * contain values for `rank` and `file`.
     *
     * @param {Object} from with `rank` and `file`
     * @param {Object} to with `rank` and `file`
     * @return undefined
     *
     * @todo Fill me in! ...and remove this comment.
     */
    applyMove: function(from, to) {
      // TODO: Apply the move `from` and `to` to the `board`
      board[4][3] = board[6][3];
      board[6][3] = null;
      // moves[0].to = moves[0].from; // place we are moving `to` is assigned piece we are moving `from`
      // moves[0].from = null;
      // console.log(moves.join('\n'));

      // for (var i = 0; i < from.length; i++) {
      //   for (var j = 0; j < to.length; j++) {
      //     from[[i]] = to[[j]];
      //   }
      //   return to[[j]];
      // }
    } // END applyMove
  }); // END game
  console.log(game.tracer());

  // console.log(game.applyMove.to);
  // return board.join('\n' + '|');
// console.log(board.from[j]);
// for (var i = 0; i < to.length; i++){
//   board.to[i] = board.from;
//     for (var j = 0; j < from.length; j++) {
//       board.from[j] = ' ';
//         return board.join('\n');
//     }
//     console.log(board.from[j]);
// }
  /**
   * Provide the initial state of the game board, useful for any game.
   *
   * @return {Array} of {Array} of {String|null}
   */
  function initial(){
    return [
      [ 'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R' ],
      [ 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' ],
      Array(8).fill(null),
      Array(8).fill(null),
      Array(8).fill(null),
      Array(8).fill(null),
      [ 'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p' ],
      [ 'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r' ],
    ];
  } // END initial

// You are not expected to understand anything below this line...
})(window || module && module.exports || this);

// ([6][3], [4][3]),
// ([0][6], [2][5]),
// ([6][2], [4][2]),
// ([1][4], [2][4]),
// ([6][6], [5][6]),
// ([1][3], [3][3]),
// ([7][5], [6][6]),
// ([0][5], [1][4]),
// ([7][6], [5][5])
<commit_msg>sup, var current<commit_after>(function(globals){ // IIFE: Immediately Invoked Function Expression
})(window || module && module.exports || this);

(function(globals){ // IIFE: Immediately Invoked Function Expression
// Don't worry if that seems a little funky...

  /**
   * Internal representation of the game board in its current state.
   *
   * @see game.board
   * @see game.tracer
   * @see initial
   * @var {Array} of {Array} of {String|null}
   */
  var board = initial(); // initialize the `board`

  /**
   * List of moves for the "Catalan Opening: Closed Variation" suitable for use
   * as arguments to `applyMove` below.
   *
   * @see applyMove
   * @var {Array} of...?
   */
  var moves = [
    { from: { rank: 6, file: 3},
      to: { rank: 4, file: 3}
    },

    { from: { rank: 0, file: 6},
      to: { rank: 2, file: 5}
    },

    { from: { rank: 6, file: 2},
      to: { rank: 4, file: 2}
    },

    { from: { rank: 1, file: 4},
      to: { rank: 2, file: 4}
    },

    { from: { rank: 6, file: 6},
      to: { rank: 5, file: 6}
    },

    { from: { rank: 1, file: 3},
      to: { rank: 3, file: 3}
    },

    { from: { rank: 7, file: 5},
      to: { rank: 6, file: 6}
    },

    { from: { rank: 0, file: 5},
      to: { rank: 1, file: 4}
    },

    { from: { rank: 7, file: 6},
      to: { rank: 5, file: 5}
    }

    ]; // END moves

    var current = 0;

    // console.log(moves);
// [[6,3], [0,6], [6,2], [1,4], [6,6], [1,3], [7,5], [0,5], [7,6]],
// [[4,3], [2,5], [4,2], [2,4], [5,6], [3,3], [6,6], [1,4], [5,5]]
// var from = moves[0];
// var to = moves[1];
// console.log(from[[0]], to[[0]]);

  // var current = [[4,3], [2,5], [4,2], [2,4], [5,6], [3,3], [6,6], [1,4], [5,5]];

  // You don't need to understand `globals` yet...
  var game = (globals.game = {
    /**
     * Provide a _copy_ of the game board in order to update the View from it
     *
     * @return {Array} of {Array} of {String|null}
     */
    board: function(){
      return board.map(function(row){
        return row.slice();
      });
    },
    /**
     * Reset the internal game board to it's initial state.
     *
     * @return {Object} the game object for Method Chaining
     */
    reset: function(){
      board = initial();

      return this; // `this` referes to the object `reset` belongs to... AKA `game`
    },
    /**
     * Advance the internal game board to the next move.
     *
     * @return {Object} the game object for Method Chaining
     * @todo Make this work!
     */
    next: function(){
      var from = moves[0];
      var to = moves[0];
      return this;
    },
    /**
     * Advance the internal game board to the previous move.
     *
     * @return {Object} the game object for Method Chaining
     * @todo Make this work!
     */
    prev: function(){
      // Another good place for code...
      return this;
    },
    /**
     * Advance the internal game board to the last move.
     *
     * @return {Object} the game object for Method Chaining
     * @todo Make this work!
     */
    end: function(){
      // Write some code here...
      return this;
    },
    /**
     * Provide a printable representation of the game board for use as a tracer
     *
     * @return {String} representation of `board`
     * @todo Refactor to use Array methods?
     */
    tracer: function(){
      var bullet = '';

      for ( var rank = 0; rank < board.length; rank++ ){
        bullet += '|';
        for ( var file = 0; file < board[rank].length; file++ ){
          bullet += (board[rank][file] || ' ') + '|';
        }
        bullet += '\n';
      }

      return bullet;
    },
    /**
     * Apply a move to the game board, given a `from` and `to` position that both
     * contain values for `rank` and `file`.
     *
     * @param {Object} from with `rank` and `file`
     * @param {Object} to with `rank` and `file`
     * @return undefined
     *
     * @todo Fill me in! ...and remove this comment.
     */
    applyMove: function(from, to) {
      // TODO: Apply the move `from` and `to` to the `board`
      board[4][3] = board[6][3];
      board[6][3] = null;
      // moves[0].to = moves[0].from; // place we are moving `to` is assigned piece we are moving `from`
      // moves[0].from = null;
      // console.log(moves.join('\n'));

    } // END applyMove
  }); // END game
  console.log(game.tracer());

  /**
   * Provide the initial state of the game board, useful for any game.
   *
   * @return {Array} of {Array} of {String|null}
   */
  function initial(){
    return [
      [ 'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R' ],
      [ 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' ],
      Array(8).fill(null),
      Array(8).fill(null),
      Array(8).fill(null),
      Array(8).fill(null),
      [ 'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p' ],
      [ 'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r' ],
    ];
  } // END initial

// You are not expected to understand anything below this line...
})(window || module && module.exports || this);

// ([6][3], [4][3]),
// ([0][6], [2][5]),
// ([6][2], [4][2]),
// ([1][4], [2][4]),
// ([6][6], [5][6]),
// ([1][3], [3][3]),
// ([7][5], [6][6]),
// ([0][5], [1][4]),
// ([7][6], [5][5])
<|endoftext|>


<commit_before>$(document).ready(()=>{
    const ss=ScreenShare.create({debug:true});

    let peer=null;
    let room=null;
    let localStream=null;
    let localScreenStream=null;
    let remoteStreams={};
    let userdata={
        username:'',
        usericon:null
    };
    let usersdata={};

    $('#usernameipt').val(localStorage.getItem('username'));

    $.getJSON('/js/apikey.json',(data)=>{
        peer=new Peer({
            key:data.key,
            debug:3
        });
        peer.on('open',id=>{
            $('#status-icon').removeClass('status-icon-offline');
            $('#status-icon').addClass('status-icon-online');
            $('#skyway-statustxt').text('SkyWay Status : online');
        });
        peer.on('disconnected',()=>{
            $('#status-icon').addClass('status-icon-offline');
            $('#status-icon').removeClass('status-icon-online');
            $('#skyway-statustxt').text('SkyWay Status : offline');
        })
    });
    $('#usericonpit').on('change',e=>{
        let file=e.target.files[0];
        userdata.usericon=file;
        $('#localusericon').attr('src',URL.createObjectURL(file));
        $('#localusericon').on('load',()=>{
            if($('#localusericon').get(0).width>256||$('#localusericon').get(0).height>256){
                swal({
                    title: 'Icon Size Error!',
                    text: 'Please use images of 256px or less in height and width.',
                    icon: 'error',
                });
                userdata.usericon=null;
                $('#localusericon').attr('src','./img/usericon.png');
            }
            if($('#localusericon').get(0).width!==$('#localusericon').get(0).height){
                swal({
                    title: 'Icon Size Error!',
                    text: 'Please use square image',
                    icon: 'error',
                });
                userdata.usericon=null;
                $('#localusericon').attr('src','./img/usericon.png');
            }
        });
    });
    $('#joinroombtn').on('click',()=>{
        let roomname=$('#roomnameipt').val();
        let username=$('#usernameipt').val();
        localStorage.setItem('username',username);
        userdata.username=username;
        usersdata[peer.id]=userdata;
        $('#localusername').text(username?username:peer.id);
        if(roomname){
            $('#roomnametxt').text(`Room : ${roomname}`);
            $('#joinroom').toggle();
            $('#chat').toggle();

            navigator.mediaDevices.getUserMedia({video:false,audio:true})
            .then(stream=>{
                localStream=stream;
                $('#myvideo').get(0).srcObject=stream;
                room=peer.joinRoom(roomname,{mode:'sfu',stream:stream});
                userdata.username=username;
                connect(room);
            })
            .catch(e=>{
                swal({
                    title: 'getUserMedia Error!',
                    text: 'Please check your microphone.',
                    icon: 'error',
                });
            });
        }
    });
    $('#leaveroombtn').on('click',()=>{
        room.close();
        room=null;
        localStream.getTracks().forEach(track => track.stop());
        localStream=null;
        ss.stop();
        localScreenStream=null;
        userdata={};
        usersdata={};
        $('#myvideo').get(0).srcObject=null;
        removeChatUserElms();
        $('#joinroom').toggle();
        $('#chat').toggle();
    });
    $('#local-mutebtn').on('click',()=>{
        if($('#local-mutebtn').text()==='Mute'){
            localStream.getTracks().forEach(track=>track.enabled=false);
            $('#local-mutebtn').text('Unmute');
        }else{
            localStream.getTracks().forEach(track=>track.enabled=true);
            $('#local-mutebtn').text('Mute');
        }
    });
    $('#screensharebtn').on('click',()=>{
        if(!localScreenStream){
            ss.start().then(stream=>{
                $('#myscreen').get(0).srcObject=stream;
                localScreenStream=stream;
            });
            $('#screensharebtn').text('Screen Share Stop');
        }else{
            ss.stop();
            $('#myscreen').get(0).srcObject=null;
            localScreenStream=null;
            $('#screensharebtn').text('Screen Share Start');
        }
    })

    let connect=_room=>{
        _room.on('open',()=>{
            _room.send(userdata);
        });
        _room.on('stream',stream=>{
            console.log(stream);
            addChatUserElm(stream.peerId);
            _room.send(userdata);
            remoteStreams[stream.peerId]=stream;
            $(`#${stream.peerId}-video`).get(0).srcObject=stream;
            $(`#${stream.peerId}-video`).get(0).play();
        })
        _room.on('data',msg=>{
            console.log(msg);
            if(msg.data.username){
                usersdata[msg.src]={
                    username:msg.data.username,
                    usericon:msg.data.usericon
                };
                $(`#${msg.src}-name`).text(msg.data.username);
                if(msg.data.usericon){
                    setTimeout(()=>{
                        const dataView = new Uint8Array(msg.data.usericon);
                        const dataBlob = new Blob([dataView]);
                        const url = URL.createObjectURL(dataBlob);
                        $(`#${msg.src}-icon`).attr('src',url);
                    },500);
                }
            }
        });
        _room.on('peerJoin',id=>{
            console.log(id);
        });
        _room.on('peerLeave',id=>{
            console.log(id);
            remoteStreams[id]=null;
            usersdata[id]=null;
            removeChatUserElm(id);
        });
    };
    let addChatUserElm=(id)=>{
        let _elm=`

${(usersdata[id]?usersdata[id].username:id)}

            <video id="${id}-video" autoplay></video>

                <button id="${id}-mutebtn" class="btn btn-secondary">Mute</button>

`;

        $('#chat-users').append(_elm);

        $(`#${id}-mutebtn`).on('click',()=>{
            if($(`#${id}-mutebtn`).text()==='Mute'){
                remoteStreams[id].getTracks().forEach(track=>track.enabled=false);
                $(`#${id}-mutebtn`).text('Unmute');
                $(`#${id}`).removeClass('active-user');
                $(`#${id}`).addClass('mute-user');
            }else{
                remoteStreams[id].getTracks().forEach(track=>track.enabled=true);
                $(`#${id}-mutebtn`).text('Mute');
                $(`#${id}`).removeClass('mute-user');
                $(`#${id}`).addClass('active-user');
            }
        })
    };

    let removeChatUserElm=(id)=>{
        $(`#${id}`).remove();
    }

    let removeChatUserElms=()=>{
        let elms=$('.chat-user');
        for(let i=0;i<elms.length;i++){
            if(elms[i].className.indexOf('local-user')===-1){
                elms[i].remove();
            }
        }
    };
});<commit_msg>add screenshare<commit_after>$(document).ready(()=>{
    const ss=ScreenShare.create({debug:true});

    let peer=null;
    let screensharepeer=null;
    let room=null;
    let screenshareroom=null;
    let localStream=null;
    let localScreenStream=null;
    let screensharinguserid='';
    let remoteStreams={};
    let userdata={
        username:'',
        usericon:null
    };
    let usersdata={};
    let roomname='';

    $('#usernameipt').val(localStorage.getItem('username'));

    $.getJSON('/js/apikey.json',(data)=>{
        peer=new Peer({
            key:data.key,
            debug:3
        });
        peer.on('open',id=>{
            $('#status-icon').removeClass('status-icon-offline');
            $('#status-icon').addClass('status-icon-online');
            $('#skyway-statustxt').text('SkyWay Status : online');
        });
        peer.on('disconnected',()=>{
            $('#status-icon').addClass('status-icon-offline');
            $('#status-icon').removeClass('status-icon-online');
            $('#skyway-statustxt').text('SkyWay Status : offline');
        });

        screensharepeer=new Peer({
            key:data.key,
            debug:3
        });
    });
    $('#usericonpit').on('change',e=>{
        let file=e.target.files[0];
        userdata.usericon=file;
        $('#localusericon').attr('src',URL.createObjectURL(file));
        $('#localusericon').on('load',()=>{
            if($('#localusericon').get(0).width>256||$('#localusericon').get(0).height>256){
                swal({
                    title: 'Icon Size Error!',
                    text: 'Please use images of 256px or less in height and width.',
                    icon: 'error',
                });
                userdata.usericon=null;
                $('#localusericon').attr('src','./img/usericon.png');
            }
            if($('#localusericon').get(0).width!==$('#localusericon').get(0).height){
                swal({
                    title: 'Icon Size Error!',
                    text: 'Please use square image',
                    icon: 'error',
                });
                userdata.usericon=null;
                $('#localusericon').attr('src','./img/usericon.png');
            }
        });
    });
    $('#joinroombtn').on('click',()=>{
        roomname=$('#roomnameipt').val();
        let username=$('#usernameipt').val();
        localStorage.setItem('username',username);
        userdata.username=username;
        usersdata[peer.id]=userdata;
        $('#localusername').text(username?username:peer.id);
        if(roomname){
            $('#roomnametxt').text(`Room : ${roomname}`);
            $('#joinroom').toggle();
            $('#chat').toggle();

            navigator.mediaDevices.getUserMedia({video:false,audio:true})
            .then(stream=>{
                localStream=stream;
                $('#myvideo').get(0).srcObject=stream;
                room=peer.joinRoom(roomname,{mode:'sfu',stream:stream});
                userdata.username=username;
                connect(room,true);
            })
            .catch(e=>{
                swal({
                    title: 'getUserMedia Error!',
                    text: `Please check your microphone.\n${e.toString()}`,
                    icon: 'error',
                });
            });
        }
    });
    $('#leaveroombtn').on('click',()=>{
        room.close();
        room=null;
        localStream.getTracks().forEach(track => track.stop());
        localStream=null;
        ss.stop();
        localScreenStream=null;
        userdata={};
        usersdata={};
        $('#myvideo').get(0).srcObject=null;
        removeChatUserElms();
        $('#joinroom').toggle();
        $('#chat').toggle();
    });
    $('#local-mutebtn').on('click',()=>{
        if($('#local-mutebtn').text()==='Mute'){
            localStream.getTracks().forEach(track=>track.enabled=false);
            $('#local-mutebtn').text('Unmute');
        }else{
            localStream.getTracks().forEach(track=>track.enabled=true);
            $('#local-mutebtn').text('Mute');
        }
    });
    $('#screensharebtn').on('click',()=>{
        if(!localScreenStream){
            ss.start().then(stream=>{
                $('#myscreen').get(0).srcObject=stream;
                localScreenStream=stream;
                screenshareroom=screensharepeer.joinRoom(roomname,{mode:'sfu',stream:stream});
                connect(screenshareroom,false);
            });
            $('#screensharebtn').text('Screen Share Stop');
        }else{
            ss.stop();
            screenshareroom.close();
            screenshareroom=null;
            localScreenStream.getTracks().forEach(track=>{
                track.stop();
            });
            $('#myscreen').get(0).srcObject=null;
            localScreenStream=null;
            $('#screensharebtn').text('Screen Share Start').toggle();
        }
    });

    let connect=(_room,isUser)=>{
        _room.on('open',()=>{
            if(isUser){
                _room.send(userdata);
            }
        });
        _room.on('stream',stream=>{
            if(stream.getAudioTracks()[0]&&isUser){
                addChatUserElm(stream.peerId);
                _room.send(userdata);
                remoteStreams[stream.peerId]=stream;
                $(`#${stream.peerId}-video`).get(0).srcObject=stream;
                $(`#${stream.peerId}-video`).get(0).play();
            }else{
                screensharinguserid=stream.peerId;
                $('#myscreen').get(0).srcObject=stream;
                $('#myscreen').get(0).play();
                if(!localScreenStream){
                    $('#screensharebtn').toggle();
                }
            }
        });
        _room.on('removeStream', stream => {
            console.log(stream);
        });
        _room.on('data',msg=>{
            if(isUser){
                console.log(msg);
                if(msg.data.username){
                    usersdata[msg.src]={
                        username:msg.data.username,
                        usericon:msg.data.usericon
                    };
                    $(`#${msg.src}-name`).text(msg.data.username);
                    if(msg.data.usericon){
                        setTimeout(()=>{
                            const dataView = new Uint8Array(msg.data.usericon);
                            const dataBlob = new Blob([dataView]);
                            const url = URL.createObjectURL(dataBlob);
                            $(`#${msg.src}-icon`).attr('src',url);
                        },500);
                    }
                }
            }
        });
        _room.on('peerJoin',id=>{
            console.log(id);
        });
        _room.on('peerLeave',id=>{
            console.log(id);
            if(isUser){
                remoteStreams[id]=null;
                usersdata[id]=null;
                removeChatUserElm(id);
            }
            if(id===screensharinguserid){
                $('#myscreen').get(0).srcObject=null;
                $('#screensharebtn').toggle();
                screensharinguserid='';
            }
        });
    };
    let addChatUserElm=(id)=>{
        let _elm=`

${(usersdata[id]?usersdata[id].username:id)}

            <video id="${id}-video" autoplay></video>

                <button id="${id}-mutebtn" class="btn btn-secondary">Mute</button>

`;

        $('#chat-users').append(_elm);

        $(`#${id}-mutebtn`).on('click',()=>{
            if($(`#${id}-mutebtn`).text()==='Mute'){
                remoteStreams[id].getTracks().forEach(track=>track.enabled=false);
                $(`#${id}-mutebtn`).text('Unmute');
                $(`#${id}`).removeClass('active-user');
                $(`#${id}`).addClass('mute-user');
            }else{
                remoteStreams[id].getTracks().forEach(track=>track.enabled=true);
                $(`#${id}-mutebtn`).text('Mute');
                $(`#${id}`).removeClass('mute-user');
                $(`#${id}`).addClass('active-user');
            }
        })
    };

    let removeChatUserElm=(id)=>{
        $(`#${id}`).remove();
    }

    let removeChatUserElms=()=>{
        let elms=$('.chat-user');
        for(let i=0;i<elms.length;i++){
            if(elms[i].className.indexOf('local-user')===-1){
                elms[i].remove();
            }
        }
    };
});<|endoftext|>


<commit_before>(function(i,s,o,g,r,a,m) {
	i['GoogleAnalyticsObject']=r;
	i[r]=i[r]||function() {
	(i[r].q=i[r].q||[]).push(arguments)}, i[r].l=1*new Date();
	a=s.createElement(o), m=s.getElementsByTagName(o)[0];
	a.async=1;a.src=g; m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-76075660-1', 'auto');
ga('send', 'pageview');
$(document).ready(function() {
    $('.empty').height($("#H").innerHeight());
    window.onresize = empty;
    $(window).scroll(function() {
		if ($(document).scrollTop() >= $("#H").innerHeight() - 100) {
			$(".navbar-fixed-top").css("background-color", "#393939");
		}
		else {
			$(".navbar-fixed-top").css("background-color", "transparent");
		}
	});
});
function empty(){
    $('.empty').height($("#H").innerHeight());
}
$(document).ready(function(){
   $('li img').on('click',function(){
        var src = $(this).attr('src');
        var img = '';
        $('#myModal').modal();
        $('#myModal').on('shown.bs.modal', function(){
            $('#myModal .modal-body').html(img);
        });
        $('#myModal').on('hidden.bs.modal', function(){
            $('#myModal .modal-body').html('');
        });
   });
})<commit_msg>Cleaned main.js<commit_after>(function(i,s,o,g,r,a,m) {
	i['GoogleAnalyticsObject'] = r;
	i[r] = i[r] || function() {
		(i[r].q = i[r].q || []).push(arguments)}, i[r].l = 1 * new Date();
		a = s.createElement(o), m = s.getElementsByTagName(o)[0];
		a.async = 1; a.src = g; m.parentNode.insertBefore(a,m)
	})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-76075660-1', 'auto');
ga('send', 'pageview');
$(document).ready(function() {
    $('.empty').height($("#H").innerHeight());
    window.onresize = empty;
    $(window).scroll(function() {
		if ($(document).scrollTop() >= $("#H").innerHeight() - 100) {
			$(".navbar-fixed-top").css("background-color", "#393939");
		}
		else {
			$(".navbar-fixed-top").css("background-color", "transparent");
		}
	});
});
function empty() {
    $('.empty').height($("#H").innerHeight());
}
$(document).ready(function() {
   $('li img').on('click', function() {
        var src = $(this).attr('src');
        var img = '';
        $('#myModal').modal();
        $('#myModal').on('shown.bs.modal', function() {
            $('#myModal .modal-body').html(img);
        });
        $('#myModal').on('hidden.bs.modal', function() {
            $('#myModal .modal-body').html('');
        });
   });
})
<|endoftext|>


<commit_before>var CURR_TIME = (Math.floor(Date.now() / 1000)+31536000) * 1000000000;
var NON_ACTIVE_NUMBERS = [0, 3, 4, 5, 72, 109, 110, 111, 112] //2 = on foot... not sure how to count that
var SLEEP_NUMBERS = [72, 109, 110, 111]
var DAY = 86400000 //number of milliseconds in a day

var weight_data;
var all_activity_data;
var id_token;
var graphs = {};

function ToggleFlipped(id) {
  d3.select(id).classed('flip', !d3.select(id).classed('flip'));
}

function onSignIn(googleUser) {
  d3.select("#sign-in-button").classed("visuallyhidden", true);
  var profile = googleUser.getBasicProfile();

  id_token = googleUser.getAuthResponse().id_token;

  d3.select("#settings-drawer-header")
    .append("img")
      .attr("id", "profile-pic")
      .attr("src", profile.getImageUrl())
      .classed("demo-avatar", true);

  d3.select("#settings-drawer-header")
    .append("a")
      .attr("href", "#")
      .attr("id", "signout-link")
      .attr("onclick", "signOut();")
      .text("Sign out");

  loadGapi();
}

function onFailure(error) {
  console.log(error);
}

function signOut() {
  id_token = null;
  var auth2 = gapi.auth2.getAuthInstance();
  auth2.signOut().then(function () {
    d3.select("#signout-link").remove();
    d3.select("#profile-pic").remove();
    d3.select("#sign-in-button").classed("visuallyhidden", false);
    console.log('User signed out.');
  });
}

function addCard(variable) {

  var card = d3.select("#card-area")
    .append("div")
      .classed("mdl-cell mdl-cell--12-col", true)
    .append("div")
      .attr("id", variable+"-card")
      .classed("click panel mdl-cell mdl-cell--12-col", true);

  var front = card.append("div")
                  .classed("mdl-card mdl-shadow--2dp front mdl-cell mdl-cell--12-col", true)

  front.append("div")
        .classed("mdl-card__title mdl-card--expand mdl-color--teal-300  mdl-cell mdl-cell--12-col", true)
      .append("h2")
        .classed("mdl-card__title-text", true)
        .text(variable.replace("-"," "));

  front.append("div")
      .classed("mdl-card__supporting-text mdl-color-text--grey-600  mdl-cell mdl-cell--12-col", true)
      .append("div")
      .attr("id", variable+"-graph");

  front.append("div")
      .classed("mdl-card__actions mdl-card--border  mdl-cell mdl-cell--12-col", true)
      .append("button")
      .classed("mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect", true)
      .attr("OnClick", "ToggleFlipped('#" + variable + "-card')")
      .text("Settings");

  var back = card.append("div")
                .classed("back mdl-card demo-options mdl-shadow--2dp mdl-color--deep-purple-500 mdl-cell mdl-cell--12-col", true)

  var settings_div = back.append("div");

  settings_div.classed("mdl-card__supporting-text mdl-color-text--blue-grey-50  mdl-cell mdl-cell--12-col", true);
  settings_div.append("h3").text("Settings");

  var settings_list = settings_div.append("ul");

  /// Y axis switch

  var label = settings_list.append("li")
               .append("label")
                  .attr("for", variable+"-y_axis-toggle")
                  .classed("mdl-switch mdl-js-switch mdl-js-ripple-effect", true);

  label.append("input")
       .classed("mdl-switch__input", true)
       .attr("type", "checkbox")
       .attr("id", variable+"-y_axis-toggle");

  label.append("span")
       .classed("mdl-switch__label", true)
       .text("Y-axis labels");

  // Points switch

  label = settings_list.append("li")
               .append("label")
               .attr("for", variable+"-plot-points-toggle")
               .classed("mdl-switch mdl-js-switch mdl-js-ripple-effect", true);

  label.append("input")
       .classed("mdl-switch__input", true)
       .attr("type", "checkbox")
       .attr("id", variable+"-plot-points-toggle");

  label.append("span")
       .classed("mdl-switch__label", true)
       .text("Plot points");

  // Confidence interval switch

  label = settings_list.append("li")
              .append("label")
              .attr("for", variable+"-plot-confint-toggle")
              .classed("mdl-switch mdl-js-switch mdl-js-ripple-effect", true);

  label.append("input")
      .classed("mdl-switch__input", true)
      .attr("type", "checkbox")
      .attr("id", variable+"-plot-confint-toggle");

  $("#"+variable+"-plot-confint-toggle").on("change", function(){ToggleConfInt(variable);});

  label.append("span")
      .classed("mdl-switch__label", true)
      .text("Plot confidence interval");

  // Loess bandwidth slider

  var list_el = settings_list.append("li");

  list_el.append("input")
         .attr("type", "range")
         .attr("min", 0)
         .attr("max", 10)
         .attr("value", .8)
         .attr("id", variable+"-smoothness-slider")
         .classed("mdl-slider mdl-js-slider", true);

  list_el.append("span")
         .classed("mdl-switch__label", true)
         .text("Smoothness");

  back.append("div")
      .classed("mdl-card__actions mdl-card--border mdl-cell mdl-cell--12-col", true)
      .append("button")
      .classed("mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect", true)
      .attr("OnClick", "ToggleFlipped('#" + variable + "-card')")
      .text("Back");

  if(!(typeof(componentHandler) == 'undefined')){
        componentHandler.upgradeAllRegistered();
    }

  options = {"smoothing":d3.select("#"+variable+"-smoothness-slider").attr("value"),
             "y_axis_ticks":d3.select("#"+variable+"-plot-confint-toggle").property("checked"),
             "confint":d3.select("#"+variable+"-plot-confint-toggle").property("checked"),
             "points":d3.select("#"+variable+"-y_axis-toggle").property("checked")
           };

  callMakeGraph(variable, options);
}

function callMakeGraph(variable, options){
  if (variable == "Sleep") {
    graphSleepData(options);
  } else if (variable == "Weight") {
    makeGraph(weight_data, "#Weight-graph", options);
  } else if (variable == "Active-time") {
    graphTotalActivityData(options);
  }
}

function ToggleConfInt(variable) {
  var g = graphs[variable+"-graph"];
  g.options.confint = !g.options.confint;
  g.vis.remove();
  callMakeGraph(variable, options);
}

function getWeight() {
  // 2. Initialize the JavaScript client library.
  gapi.client.request("https://www.googleapis.com/fitness/v1/users/me/dataSources?dataTypeName=com.google.weight")
    .then(function(response) {
      weight_sources = response.result;
      idlist = [];
      for (el in weight_sources.dataSource){
        streamId = weight_sources.dataSource[el].dataStreamId;
        if (streamId == "derived:com.google.weight:com.google.android.gms:merge_weight") {
          idlist = [streamId];
          break;
        } else {
          idlist.push(streamId);
        }
      }
      Promise.all(idlist.map(getDataFromStream)).then(function(values){
        var data = extractDataFromStreams(values);
        for (el in data) {
          // Extract data from JSON object and convert kg to pounds
          data[el] = [new Date(+data[el].endTimeNanos/1000000), data[el].value[0].fpVal*2.20462];
        }
        weight_data = data;
      });
  }, function(reason) {
    console.log('Error: ' + reason.result.error.message);
  });
};

function loadData() {
  // d3.selectAll(".getdata").classed("disabled", false);
  getWeight();
  getActivity();
}

function loadGapi() {
  gapi.load('client', loadData);
};

function getDataFromStream(streamId) {
  console.log("https://www.googleapis.com/fitness/v1/users/me/dataSources/"+streamId+"/datasets/0-"+CURR_TIME);
  return gapi.client.request("https://www.googleapis.com/fitness/v1/users/me/dataSources/"+streamId+"/datasets/0-"+CURR_TIME);
}

function getActivity(){

  var activity_data = gapi.client.request({
    "path" : "https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate",
    "method" : "POST",
    "body":{
      "aggregateBy": [
        {
          "dataTypeName": "com.google.activity.segment"
        }
      ],
      "endTimeMillis": Date.now(),
      "startTimeMillis": Date.now() - (30*DAY),
      "bucketByTime": {
        "period": {
          "type": "day",
          "value": 1,
          "timeZoneId": moment.tz.guess()
        }}
    }
  });
  activity_data.then(function(response){
    all_activity_data = response.result.bucket;

  }, function(reason) {
    console.log('Error: ' + reason.result.error.message);
  });
}

function graphSleepData(options){
  sleep_data = [];
  for (i in all_activity_data) {
    if (all_activity_data[i].dataset[0].point.length > 0) {
      sleep_data.push([new Date(+all_activity_data[i].dataset[0].point[0].startTimeNanos/1000000), 0]);
    }
    for (j in all_activity_data[i].dataset[0].point){
      if (SLEEP_NUMBERS.includes(+all_activity_data[i].dataset[0].point[j].value[0].intVal)) {
        sleep_data[sleep_data.length-1][1] += +all_activity_data[i].dataset[0].point[j].value[1].intVal/3600000;
      }
    }
  }
  makeGraph(sleep_data, "#Sleep-graph", options);
}

function graphTotalActivityData(options){
  data = [];
  for (i in all_activity_data) {
    if (all_activity_data[i].dataset[0].point.length > 0) {
      data.push([new Date(+all_activity_data[i].dataset[0].point[0].startTimeNanos/1000000), 0]);
    }
    for (j in all_activity_data[i].dataset[0].point){
      if (!NON_ACTIVE_NUMBERS.includes(+all_activity_data[i].dataset[0].point[j].value[0].intVal)) {
        data[data.length-1][1] += +all_activity_data[i].dataset[0].point[j].value[1].intVal/3600000;
      }
    }
  }
  makeGraph(data, "#Active-time-graph", options);
}

function extractDataFromStreams(streams) {
  var data = [];
  for (stream in streams) {
    var curr = streams[stream].result.point;
    if (curr.length > data.length) {
      data = curr;
    }
  }

  return data;
}

function toggleLabelYAxis() {
  $.ajax("http://www.stability-app.com/update_settings", {
      type:"POST",
      contentType:"application/json",
      data:JSON.stringify({"user":id_token, "value":true}),
      success:function() {alert("success");},
      error: function() {alert("failure");}
  });

  // var xmlHttp = new XMLHttpRequest();
  // xmlHttp.open( "POST", "http://stability-app.com/update_settings", true );
  // xmlHttp.send({"user":id_token, "value":true});
}

function makeGraph(data, svg_id, options){
  // Based on https://github.com/jasondavies/science.js/blob/master/examples/loess/loess.js

  var id_without_hash = svg_id.slice(1, svg_id.length);

  var w = document.getElementById(id_without_hash).offsetWidth,
      h = w/2,
      p = 35.5,
      n = 100;

  w -= 2*p; //margins need to come out of width

  var min_band = 2/data.length;

  var loess = science.stats.loess().bandwidth(d3.max([min_band, options.smoothing]));

  var zipped_data = d3.transpose(data);
  var original_data = data;
  var loess_result = loess(zipped_data[0], zipped_data[1]);

  zipped_data[1] = loess_result.loess;
  zipped_data.push(loess_result.confint);
  data = d3.zip(zipped_data[0], zipped_data[1], zipped_data[2]);

  max_y = d3.max(data, function(d){return d[2] ? d[1]+d[2] : d[1];});
  min_y = d3.min(data, function(d){return d[2] ? d[1]-d[2] : d[1];});

  //Add margins
  max_y += max_y*.2
  if (min_y > 0) {
    min_y -= min_y*.2;
  }

  var x = d3.scaleTime().domain([new Date(data[0][0]-86400000), new Date(data[data.length-1][0]+86400000)]).range([0, w]);
  var y = d3.scaleLinear().domain([min_y, max_y]).range([h, 0]);

  var xAxis = d3.axisBottom(x),
      yAxis = d3.axisLeft(y);

  var vis = d3.select(svg_id)
    .append("svg")
      .attr("width", w + p + p)
      .attr("height", h + p + p)
    .append("g")
      .attr("transform", "translate(" + p + "," + p + ")");

  var area = d3.area()
        .x(function(d) { return x(d[0]); })
        .y0(function(d) { return d[2] ? y(d[1]-d[2]) : y(d[1]);})
        .y1(function(d) { return d[2] ? y(d[1]+d[2]) : y(d[1]);});

  if (options.confint){
    vis.selectAll("path")
        .data([data])
      .enter().append("path")
        .attr("d", function(d){return area(d);})
        .attr("stroke", "black")
        .attr("fill", "purple")
        .attr("stroke-width", 1);
  }

  if (options.points){
    vis.selectAll("circle")
       .data(original_data)
       .enter()
       .append("circle")
       .attr("r", 5)
       .attr("cx", function(d){return x(d[0]);})
       .attr("cy", function(d){return y(d[1]);});
  }

  vis.append("g")
      .attr("class", "bottom axis")
      .attr("transform", "translate(0," + h + ")")
      .call(xAxis);

  if (!options.y_axis_ticks) {
    yAxis.ticks(0);
  }

  vis.append("g")
      .attr("class", "left axis")
      .call(yAxis);

  graphs[id_without_hash] = {"x_axis":xAxis, "y_axis":yAxis, "vis":vis, "options":options};
}
<commit_msg>Confint switch does something<commit_after>var CURR_TIME = (Math.floor(Date.now() / 1000)+31536000) * 1000000000;
var NON_ACTIVE_NUMBERS = [0, 3, 4, 5, 72, 109, 110, 111, 112] //2 = on foot... not sure how to count that
var SLEEP_NUMBERS = [72, 109, 110, 111]
var DAY = 86400000 //number of milliseconds in a day

var weight_data;
var all_activity_data;
var id_token;
var graphs = {};

function ToggleFlipped(id) {
  d3.select(id).classed('flip', !d3.select(id).classed('flip'));
}

function onSignIn(googleUser) {
  d3.select("#sign-in-button").classed("visuallyhidden", true);
  var profile = googleUser.getBasicProfile();

  id_token = googleUser.getAuthResponse().id_token;

  d3.select("#settings-drawer-header")
    .append("img")
      .attr("id", "profile-pic")
      .attr("src", profile.getImageUrl())
      .classed("demo-avatar", true);

  d3.select("#settings-drawer-header")
    .append("a")
      .attr("href", "#")
      .attr("id", "signout-link")
      .attr("onclick", "signOut();")
      .text("Sign out");

  loadGapi();
}

function onFailure(error) {
  console.log(error);
}

function signOut() {
  id_token = null;
  var auth2 = gapi.auth2.getAuthInstance();
  auth2.signOut().then(function () {
    d3.select("#signout-link").remove();
    d3.select("#profile-pic").remove();
    d3.select("#sign-in-button").classed("visuallyhidden", false);
    console.log('User signed out.');
  });
}

function addCard(variable) {

  var card = d3.select("#card-area")
    .append("div")
      .classed("mdl-cell mdl-cell--12-col", true)
    .append("div")
      .attr("id", variable+"-card")
      .classed("click panel mdl-cell mdl-cell--12-col", true);

  var front = card.append("div")
                  .classed("mdl-card mdl-shadow--2dp front mdl-cell mdl-cell--12-col", true)

  front.append("div")
        .classed("mdl-card__title mdl-card--expand mdl-color--teal-300  mdl-cell mdl-cell--12-col", true)
      .append("h2")
        .classed("mdl-card__title-text", true)
        .text(variable.replace("-"," "));

  front.append("div")
      .classed("mdl-card__supporting-text mdl-color-text--grey-600  mdl-cell mdl-cell--12-col", true)
      .append("div")
      .attr("id", variable+"-graph");

  front.append("div")
      .classed("mdl-card__actions mdl-card--border  mdl-cell mdl-cell--12-col", true)
      .append("button")
      .classed("mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect", true)
      .attr("OnClick", "ToggleFlipped('#" + variable + "-card')")
      .text("Settings");

  var back = card.append("div")
                .classed("back mdl-card demo-options mdl-shadow--2dp mdl-color--deep-purple-500 mdl-cell mdl-cell--12-col", true)

  var settings_div = back.append("div");

  settings_div.classed("mdl-card__supporting-text mdl-color-text--blue-grey-50  mdl-cell mdl-cell--12-col", true);
  settings_div.append("h3").text("Settings");

  var settings_list = settings_div.append("ul");

  /// Y axis switch

  var label = settings_list.append("li")
               .append("label")
                  .attr("for", variable+"-y_axis-toggle")
                  .classed("mdl-switch mdl-js-switch mdl-js-ripple-effect", true);

  label.append("input")
       .classed("mdl-switch__input", true)
       .attr("type", "checkbox")
       .attr("id", variable+"-y_axis-toggle");

  label.append("span")
       .classed("mdl-switch__label", true)
       .text("Y-axis labels");

  // Points switch

  label = settings_list.append("li")
               .append("label")
               .attr("for", variable+"-plot-points-toggle")
               .classed("mdl-switch mdl-js-switch mdl-js-ripple-effect", true);

  label.append("input")
       .classed("mdl-switch__input", true)
       .attr("type", "checkbox")
       .attr("id", variable+"-plot-points-toggle");

  label.append("span")
       .classed("mdl-switch__label", true)
       .text("Plot points");

  // Confidence interval switch

  label = settings_list.append("li")
              .append("label")
              .attr("for", variable+"-plot-confint-toggle")
              .classed("mdl-switch mdl-js-switch mdl-js-ripple-effect", true);

  label.append("input")
      .classed("mdl-switch__input", true)
      .attr("type", "checkbox")
      .attr("id", variable+"-plot-confint-toggle");

  $("#"+variable+"-plot-confint-toggle").on("change", function(){ToggleConfInt(variable);});

  label.append("span")
      .classed("mdl-switch__label", true)
      .text("Plot confidence interval");

  // Loess bandwidth slider

  var list_el = settings_list.append("li");

  list_el.append("input")
         .attr("type", "range")
         .attr("min", 0)
         .attr("max", 10)
         .attr("value", .8)
         .attr("id", variable+"-smoothness-slider")
         .classed("mdl-slider mdl-js-slider", true);

  list_el.append("span")
         .classed("mdl-switch__label", true)
         .text("Smoothness");

  back.append("div")
      .classed("mdl-card__actions mdl-card--border mdl-cell mdl-cell--12-col", true)
      .append("button")
      .classed("mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect", true)
      .attr("OnClick", "ToggleFlipped('#" + variable + "-card')")
      .text("Back");

  if(!(typeof(componentHandler) == 'undefined')){
        componentHandler.upgradeAllRegistered();
    }

  options = {"smoothing":d3.select("#"+variable+"-smoothness-slider").attr("value"),
             "y_axis_ticks":d3.select("#"+variable+"-plot-confint-toggle").property("checked"),
             "confint":d3.select("#"+variable+"-plot-confint-toggle").property("checked"),
             "points":d3.select("#"+variable+"-y_axis-toggle").property("checked")
           };

  callMakeGraph(variable, options);
}

function callMakeGraph(variable, options){
  if (variable == "Sleep") {
    graphSleepData(options);
  } else if (variable == "Weight") {
    makeGraph(weight_data, "#Weight-graph", options);
  } else if (variable == "Active-time") {
    graphTotalActivityData(options);
  }
}

function ToggleConfInt(variable) {
  var g = graphs[variable+"-graph"];
  g.options.confint = !g.options.confint;
  g.vis.remove();
  callMakeGraph(variable, options);
}

function getWeight() {
  // 2. Initialize the JavaScript client library.
  gapi.client.request("https://www.googleapis.com/fitness/v1/users/me/dataSources?dataTypeName=com.google.weight")
    .then(function(response) {
      weight_sources = response.result;
      idlist = [];
      for (el in weight_sources.dataSource){
        streamId = weight_sources.dataSource[el].dataStreamId;
        if (streamId == "derived:com.google.weight:com.google.android.gms:merge_weight") {
          idlist = [streamId];
          break;
        } else {
          idlist.push(streamId);
        }
      }
      Promise.all(idlist.map(getDataFromStream)).then(function(values){
        var data = extractDataFromStreams(values);
        for (el in data) {
          // Extract data from JSON object and convert kg to pounds
          data[el] = [new Date(+data[el].endTimeNanos/1000000), data[el].value[0].fpVal*2.20462];
        }
        weight_data = data;
      });
  }, function(reason) {
    console.log('Error: ' + reason.result.error.message);
  });
};

function loadData() {
  // d3.selectAll(".getdata").classed("disabled", false);
  getWeight();
  getActivity();
}

function loadGapi() {
  gapi.load('client', loadData);
};

function getDataFromStream(streamId) {
  console.log("https://www.googleapis.com/fitness/v1/users/me/dataSources/"+streamId+"/datasets/0-"+CURR_TIME);
  return gapi.client.request("https://www.googleapis.com/fitness/v1/users/me/dataSources/"+streamId+"/datasets/0-"+CURR_TIME);
}

function getActivity(){

  var activity_data = gapi.client.request({
    "path" : "https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate",
    "method" : "POST",
    "body":{
      "aggregateBy": [
        {
          "dataTypeName": "com.google.activity.segment"
        }
      ],
      "endTimeMillis": Date.now(),
      "startTimeMillis": Date.now() - (30*DAY),
      "bucketByTime": {
        "period": {
          "type": "day",
          "value": 1,
          "timeZoneId": moment.tz.guess()
        }}
    }
  });
  activity_data.then(function(response){
    all_activity_data = response.result.bucket;

  }, function(reason) {
    console.log('Error: ' + reason.result.error.message);
  });
}

function graphSleepData(options){
  sleep_data = [];
  for (i in all_activity_data) {
    if (all_activity_data[i].dataset[0].point.length > 0) {
      sleep_data.push([new Date(+all_activity_data[i].dataset[0].point[0].startTimeNanos/1000000), 0]);
    }
    for (j in all_activity_data[i].dataset[0].point){
      if (SLEEP_NUMBERS.includes(+all_activity_data[i].dataset[0].point[j].value[0].intVal)) {
        sleep_data[sleep_data.length-1][1] += +all_activity_data[i].dataset[0].point[j].value[1].intVal/3600000;
      }
    }
  }
  makeGraph(sleep_data, "#Sleep-graph", options);
}

function graphTotalActivityData(options){
  data = [];
  for (i in all_activity_data) {
    if (all_activity_data[i].dataset[0].point.length > 0) {
      data.push([new Date(+all_activity_data[i].dataset[0].point[0].startTimeNanos/1000000), 0]);
    }
    for (j in all_activity_data[i].dataset[0].point){
      if (!NON_ACTIVE_NUMBERS.includes(+all_activity_data[i].dataset[0].point[j].value[0].intVal)) {
        data[data.length-1][1] += +all_activity_data[i].dataset[0].point[j].value[1].intVal/3600000;
      }
    }
  }
  makeGraph(data, "#Active-time-graph", options);
}

function extractDataFromStreams(streams) {
  var data = [];
  for (stream in streams) {
    var curr = streams[stream].result.point;
    if (curr.length > data.length) {
      data = curr;
    }
  }

  return data;
}

function toggleLabelYAxis() {
  $.ajax("http://www.stability-app.com/update_settings", {
      type:"POST",
      contentType:"application/json",
      data:JSON.stringify({"user":id_token, "value":true}),
      success:function() {alert("success");},
      error: function() {alert("failure");}
  });

  // var xmlHttp = new XMLHttpRequest();
  // xmlHttp.open( "POST", "http://stability-app.com/update_settings", true );
  // xmlHttp.send({"user":id_token, "value":true});
}

function makeGraph(data, svg_id, options){
  // Based on https://github.com/jasondavies/science.js/blob/master/examples/loess/loess.js

  var id_without_hash = svg_id.slice(1, svg_id.length);

  var w = document.getElementById(id_without_hash).offsetWidth,
      h = w/2,
      p = 35.5,
      n = 100;

  w -= 2*p; //margins need to come out of width

  var min_band = 2/data.length;

  var loess = science.stats.loess().bandwidth(d3.max([min_band, options.smoothing]));

  var zipped_data = d3.transpose(data);
  var original_data = data;
  var loess_result = loess(zipped_data[0], zipped_data[1]);

  zipped_data[1] = loess_result.loess;
  zipped_data.push(loess_result.confint);
  data = d3.zip(zipped_data[0], zipped_data[1], zipped_data[2]);

  max_y = d3.max(data, function(d){return d[2] ? d[1]+d[2] : d[1];});
  min_y = d3.min(data, function(d){return d[2] ? d[1]-d[2] : d[1];});

  //Add margins
  max_y += max_y*.2
  if (min_y > 0) {
    min_y -= min_y*.2;
  }

  var x = d3.scaleTime().domain([new Date(data[0][0]-86400000), new Date(data[data.length-1][0]+86400000)]).range([0, w]);
  var y = d3.scaleLinear().domain([min_y, max_y]).range([h, 0]);

  var xAxis = d3.axisBottom(x),
      yAxis = d3.axisLeft(y);

  var vis = d3.select(svg_id)
    .append("svg")
      .attr("width", w + p + p)
      .attr("height", h + p + p)
    .append("g")
      .attr("transform", "translate(" + p + "," + p + ")");

  var area = d3.area()
        .x(function(d) { return x(d[0]); })
        .y0(function(d) { return d[2] ? y(d[1]-d[2]) : y(d[1]);})
        .y1(function(d) { return d[2] ? y(d[1]+d[2]) : y(d[1]);});

  if (options.confint){
    vis.selectAll("path")
        .data([data])
      .enter().append("path")
        .attr("d", function(d){return area(d);})
        .attr("stroke", "black")
        .attr("fill", "purple")
        .attr("stroke-width", 1);
  }

  if (options.points){
    vis.selectAll("circle")
       .data(original_data)
       .enter()
       .append("circle")
       .attr("r", 5)
       .attr("cx", function(d){return x(d[0]);})
       .attr("cy", function(d){return y(d[1]);});
  }

  vis.append("g")
      .attr("class", "bottom axis")
      .attr("transform", "translate(0," + h + ")")
      .call(xAxis);

  if (!options.y_axis_ticks) {
    yAxis.ticks(0);
  }

  vis.append("g")
      .attr("class", "left axis")
      .call(yAxis);

  graphs[id_without_hash] = {"x_axis":xAxis, "y_axis":yAxis, "vis":d3.select(svg_id), "options":options};
}
<|endoftext|>