<commit_before>var args = arguments[0] || {};
var radius = 20;

var letterCollection = getLetterCollection();
letterCollection.fetch();

var jsonCollection = letterCollection.toJSON();
Alloy.Globals.jsonCollection = jsonCollection;

var hotspotCollection = getHotspotCollection();

showMap();
createMapRoute();
var familyMap;
displayMarkers();
addClueZone();
//getGPSpos();

function startInteractive() {
	getGPSpos();
	loadClue();
}

function loadClue() {
	$.btnStartQuiz.hide();
	$.txtLetter.show();
	$.lblLetters.show();
	$.lblCollectedLetters.show();

	if (foundId == !null) {

		$.lblWelcome.text = "Nästa ledtråd: ";
		$.lblInfoText.text = jsonCollection[foundId - 1].clue;

	} else {
		Ti.API.info("foundId är null");
	}
}

function sendLetter() {
	checkLetter(getLetter());
	familyMap.removeAllAnnotations();
	addClueZone();
}

function getLetter() {
	var letter = $.txtLetter.value;
	return letter.toUpperCase();
	//};
}

//Sätta alert title

function checkLetter(letterToCheck) {

	if (Alloy.Globals.jsonCollection[foundId - 1].letter == letterToCheck) {
		lettersArray.push(Alloy.Globals.jsonCollection[foundId - 1].letter);
		$.lblCollectedLetters.text = $.lblCollectedLetters.text + letterToCheck;
		Alloy.Globals.jsonCollection[foundId - 1].found = 1;
		$.txtLetter.value = '';

	} else {
		alert("Är du säker på att " + letterToCheck + " är rätt bokstav?");
		$.txtLetter.value = '';
	}
}

function allLetters() {

	if (word.length == letterArray.length) {
		$.txtLetter.hide();
		$.txtWord.show();
		$.lblLetters.text = "Skicka ord!";
		$.lblLetters.onClick = checkWord;
	}
}

//-----------------------------------------------------------
// Kontrollerar det inskickade ordet mot "facit"
//-----------------------------------------------------------
function checkWord() {
	var check = $.txtWord.value;
	check.toLowerCase();

	if (check == word) {
		alert("Bra jobbat!");
	} else {
		alert("Försök igen!");
	}
}

//MAP STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

//-----------------------------------------------------------
// Visar markers för hotspots
//-----------------------------------------------------------
function displayMarkers() {
	try {
		var markerArray = [];
		hotspotCollection.fetch();

		var markersJSON = hotspotCollection.toJSON();
		for (var u = 0; u < markersJSON.length; u++) {

			if (OS_IOS) {
				var marker = MapModule.createAnnotation({
					id : markersJSON[u].name,
					latitude : markersJSON[u].xkoord,
					longitude : markersJSON[u].ykoord,
					title : markersJSON[u].name,
					subtitle : 'Läs mer om ' + markersJSON[u].name + ' här!',
					image : '/images/hot-icon-azure.png',
					// pincolor : MapModule.ANNOTATION_PURPLE,
					rightButton : '/images/arrow.png',
					name : 'hotspot'
				});
			}

			markerArray.push(marker);
		}

		familyMap.addAnnotations(markerArray);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - displayMarkers");
	}
}

//-----------------------------------------------------------
// Öppnar hotspotDetail med info om vald hotspot
//-----------------------------------------------------------
function showHotspot(myId) {
	try {
		hotspotCollection.fetch({
			query : 'SELECT id, infoTxt FROM hotspotModel where name = "' + myId + '"'
		});

		var jsonObjHot = hotspotCollection.toJSON();

		var hotspotTxt = {
			title : myId,
			infoTxt : jsonObjHot[0].infoTxt,
			id : jsonObjHot[0].id
		};

		var hotspotDetail = Alloy.createController("hotspotDetail", hotspotTxt).getView();
		Alloy.CFG.tabs.activeTab.open(hotspotDetail);
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - showHotspot");
	}
}

//-----------------------------------------------------------
// Eventlistener för klick på trail eller hotspot
//-----------------------------------------------------------
familyMap.addEventListener('click', function(evt) {
	if (evt.clicksource == 'rightButton') {
		showHotspot(evt.annotation.id);
	}
});

//-----------------------------------------
// Zoomar in kartan på äventyrsleden
//-----------------------------------------
function showMap() {
	try {
		familyMap = MapModule.createView({
			userLocation : true,
			mapType : MapModule.HYBRID_TYPE,
			animate : true,
			height : '100%',
			width : Ti.UI.FILL
		});
		$.showFamilyTrail.add(familyMap);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - showMap");
	}
}

//-----------------------------------------------------------
// Beräknar nivån av inzoomning på en vald led
//-----------------------------------------------------------
function calculateMapRegion(trailCoordinates) {
	try {
		if (trailCoordinates.length != 0) {
			var poiCenter = {};
			var delta = 0.02;
			var minLat = trailCoordinates[0].latitude,
			    maxLat = trailCoordinates[0].latitude,
			    minLon = trailCoordinates[0].longitude,
			    maxLon = trailCoordinates[0].longitude;
			for (var i = 0; i < trailCoordinates.length - 1; i++) {
				minLat = Math.min(trailCoordinates[i + 1].latitude, minLat);
				maxLat = Math.max(trailCoordinates[i + 1].latitude, maxLat);
				minLon = Math.min(trailCoordinates[i + 1].longitude, minLon);
				maxLon = Math.max(trailCoordinates[i + 1].longitude, maxLon);
			}

			var deltaLat = maxLat - minLat;
			var deltaLon = maxLon - minLon;

			delta = Math.max(deltaLat, deltaLon);
			// Ändra om det ska vara mer zoomat
			delta = delta * 1.5;

			poiCenter.lat = maxLat - parseFloat((maxLat - minLat) / 2);
			poiCenter.lon = maxLon - parseFloat((maxLon - minLon) / 2);

			region = {
				latitude : poiCenter.lat,
				longitude : poiCenter.lon,
				latitudeDelta : delta,
				longitudeDelta : delta

			};
		}
		return region;

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - calculateMapRegion");
	}

}

//-----------------------------------------------------------
// skapar vandringsleden och sätter den på kartan
//-----------------------------------------------------------
function createMapRoute() {
	try {
		var zoomedRoute = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory + "/routes/adventureroute.json").read().text;
		var parsedRoute = JSON.parse(zoomedRoute);

		var geoArray = [];
		geoArray.push(parsedRoute);

		var coordArray = [];

		for (var u = 0; u < geoArray.length; u++) {
			var coords = geoArray[0].features[0].geometry.paths[u];

			for (var i = 0; i < coords.length; i++) {

				var point = {
					latitude : coords[i][1],
					longitude : coords[i][0]
				};
				coordArray.push(point);
			}

			var route = {
				name : 'Äventyrsleden',
				points : coordArray,
				color : 'purple',
				width : 2.0
			};

			familyMap.addRoute(MapModule.createRoute(route));
		}

		familyMap.region = calculateMapRegion(coordArray);
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - createMapRoute");
	}
}

//-----------------------------------------------------------
// Visar marker för vandringsleden
//-----------------------------------------------------------
function displayTrailMarkers() {
	try {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : 58.893198,
			longitude : 11.047852,
			title : 'Äventyrsleden',
			pincolor : MapModule.ANNOTATION_PURPLE,
			subtitle : 'Vandringsleden startar här!',
			font : {
				fontFamily : 'Raleway-Light'
			}
		});

		familyMap.addAnnotation(markerAnnotation);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - displayTrailMarkers");
	}
}

function addClueZone() {

	for (var c = 0; c < Alloy.Globals.jsonCollection.length; c++) {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : Alloy.Globals.jsonCollection[c].latitude,
			longitude : Alloy.Globals.jsonCollection[c].longitude,
			title : Alloy.Globals.jsonCollection[c].id,
			subtitle : Alloy.Globals.jsonCollection[c].letter
		});

		if (Alloy.Globals.jsonCollection[c].found == 0) {
			markerAnnotation.image = '/images/red.png';
		} else {
			markerAnnotation.image = '/images/green.png';
		}

		familyMap.addAnnotation(markerAnnotation);
	}
}

//GEO STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

function getGPSpos() {
	try {

		Ti.Geolocation.getCurrentPosition(function(e) {
			if (e.error) {
				Ti.API.info('Get current position' + e.error);
				getGPSpos();
			}
		});

		if (Ti.Geolocation.locationServicesEnabled) {
			Titanium.Geolocation.preferredProvider = Titanium.Geolocation.PROVIDER_GPS;
			Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_NEAREST_TEN_METERS;
			Titanium.Geolocation.pauseLocationUpdateAutomatically = true;
			Titanium.Geolocation.distanceFilter = 3;

			Ti.Geolocation.addEventListener('location', function(e) {
				if (e.error) {
					Ti.API.info('Kan inte sätta eventListener ' + e.error);
				} else {
					getPosition(e.coords);
					$.coords.text = 'Lat: ' + JSON.stringify(e.coords.latitude + 'Lon: ' + JSON.stringify(e.coords.longitude));

				}
			});

		} else {
			alert('Tillåt gpsen, tack');
		}
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "Map - get current position GPS");
	}

}

//-----------------------------------------------------------
// Hämtar enhetens position och kontrollerar mot punkter
//-----------------------------------------------------------
function getPosition(coordinatesObj) {
	try {
		gLat = coordinatesObj.latitude;
		gLon = coordinatesObj.longitude;

		isNearPoint();

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - getPosition");
	}
}

//-----------------------------------------------------------
// Beräknar avståndet mellan enhetens koordinater och de punkter som håller info
//-----------------------------------------------------------
function distanceInM(lat1, lon1, GLat, GLon) {
	try {
		if (lat1 == null || lon1 == null || GLat == null || GLat == null) {
			alert("Det finns inga koordinater att titta efter");
		}

		var R = 6371;
		var a = 0.5 - Math.cos((GLat - lat1) * Math.PI / 180) / 2 + Math.cos(lat1 * Math.PI / 180) * Math.cos(GLat * Math.PI / 180) * (1 - Math.cos((GLon - lon1) * Math.PI / 180)) / 2;
		var distance = (R * 2 * Math.asin(Math.sqrt(a))) * 1000;

		return distance;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - distanceInM");
	}
}

//-----------------------------------------------------------
// Kontrollerar om enhetens position är inom radien för en utsatt punkt
//-----------------------------------------------------------
function isInsideRadius(lat1, lon1, rad) {
	try {

		var isInside = false;
		var distance = distanceInM(lat1, lon1, gLat, gLon);

		if (distance <= rad) {
			isInside = true;
		}
		return isInside;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isInsideRadius");
	}
}

//-----------------------------------------------------------
// Sätter ut punkterna som ska kontrolleras, loopar
//-----------------------------------------------------------
function isNearPoint() {
	try {
		for (var i = 0; i < Alloy.Globals.jsonCollection.length; i++) {

			if (Alloy.Globals.jsonCollection[i].found == 0) {
				var lat = Alloy.Globals.jsonCollection[i].latitude;
				var lon = Alloy.Globals.jsonCollection[i].longitude;
				foundId = Alloy.Globals.jsonCollection[i].id;
				$.lblInfoText.text = Alloy.Globals.jsonCollection[i].clue;

				var message = Ti.UI.createAlertDialog({
					message : Alloy.Globals.jsonCollection[i].clue,
					title : 'Ny bokstav i närheten!'
				});
				message.show();

				Alloy.Globals.jsonCollection[i].found = 1;
			}
		}

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isNearPoint");
	}
}<commit_msg>jhgfd<commit_after>var args = arguments[0] || {};
var radius = 20;

var jsonCollection = letterCollection.toJSON();
Alloy.Globals.jsonCollection = jsonCollection;

var hotspotCollection = getHotspotCollection();

showMap();
createMapRoute();
var familyMap;
displayMarkers();
addClueZone();
//getGPSpos();

function startInteractive() {
	getGPSpos();
	loadClue();
}

function loadClue() {
	$.btnStartQuiz.hide();
	$.txtLetter.show();
	$.lblLetters.show();
	$.lblCollectedLetters.show();

	if (foundId == !null) {

		$.lblWelcome.text = "Nästa ledtråd: ";
		$.lblInfoText.text = jsonCollection[foundId - 1].clue;

	} else {
		Ti.API.info("foundId är null");
	}
}

function sendLetter() {
	checkLetter(getLetter());
	familyMap.removeAllAnnotations();
	addClueZone();
}

function getLetter() {
	var letter = $.txtLetter.value;
	return letter.toUpperCase();
	//};
}

//Sätta alert title

function checkLetter(letterToCheck) {

	if (Alloy.Globals.jsonCollection[foundId - 1].letter == letterToCheck) {
		lettersArray.push(Alloy.Globals.jsonCollection[foundId - 1].letter);
		$.lblCollectedLetters.text = $.lblCollectedLetters.text + letterToCheck;
		Alloy.Globals.jsonCollection[foundId - 1].found = 1;
		$.txtLetter.value = '';

	} else {
		alert("Är du säker på att " + letterToCheck + " är rätt bokstav?");
		$.txtLetter.value = '';
	}
}

function allLetters() {

	if (word.length == letterArray.length) {
		$.txtLetter.hide();
		$.txtWord.show();
		$.lblLetters.text = "Skicka ord!";
		$.lblLetters.onClick = checkWord;
	}
}

//-----------------------------------------------------------
// Kontrollerar det inskickade ordet mot "facit"
//-----------------------------------------------------------
function checkWord() {
	var check = $.txtWord.value;
	check.toLowerCase();

	if (check == word) {
		alert("Bra jobbat!");
	} else {
		alert("Försök igen!");
	}
}

//MAP STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

//-----------------------------------------------------------
// Visar markers för hotspots
//-----------------------------------------------------------
function displayMarkers() {
	try {
		var markerArray = [];
		hotspotCollection.fetch();

		var markersJSON = hotspotCollection.toJSON();
		for (var u = 0; u < markersJSON.length; u++) {

			if (OS_IOS) {
				var marker = MapModule.createAnnotation({
					id : markersJSON[u].name,
					latitude : markersJSON[u].xkoord,
					longitude : markersJSON[u].ykoord,
					title : markersJSON[u].name,
					subtitle : 'Läs mer om ' + markersJSON[u].name + ' här!',
					image : '/images/hot-icon-azure.png',
					// pincolor : MapModule.ANNOTATION_PURPLE,
					rightButton : '/images/arrow.png',
					name : 'hotspot'
				});
			}

			markerArray.push(marker);
		}

		familyMap.addAnnotations(markerArray);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - displayMarkers");
	}
}

//-----------------------------------------------------------
// Öppnar hotspotDetail med info om vald hotspot
//-----------------------------------------------------------
function showHotspot(myId) {
	try {
		hotspotCollection.fetch({
			query : 'SELECT id, infoTxt FROM hotspotModel where name = "' + myId + '"'
		});

		var jsonObjHot = hotspotCollection.toJSON();

		var hotspotTxt = {
			title : myId,
			infoTxt : jsonObjHot[0].infoTxt,
			id : jsonObjHot[0].id
		};

		var hotspotDetail = Alloy.createController("hotspotDetail", hotspotTxt).getView();
		Alloy.CFG.tabs.activeTab.open(hotspotDetail);
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - showHotspot");
	}
}

//-----------------------------------------------------------
// Eventlistener för klick på trail eller hotspot
//-----------------------------------------------------------
familyMap.addEventListener('click', function(evt) {
	if (evt.clicksource == 'rightButton') {
		showHotspot(evt.annotation.id);
	}
});

//-----------------------------------------
// Zoomar in kartan på äventyrsleden
//-----------------------------------------
function showMap() {
	try {
		familyMap = MapModule.createView({
			userLocation : true,
			mapType : MapModule.HYBRID_TYPE,
			animate : true,
			height : '100%',
			width : Ti.UI.FILL
		});
		$.showFamilyTrail.add(familyMap);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - showMap");
	}
}

//-----------------------------------------------------------
// Beräknar nivån av inzoomning på en vald led
//-----------------------------------------------------------
function calculateMapRegion(trailCoordinates) {
	try {
		if (trailCoordinates.length != 0) {
			var poiCenter = {};
			var delta = 0.02;
			var minLat = trailCoordinates[0].latitude,
			    maxLat = trailCoordinates[0].latitude,
			    minLon = trailCoordinates[0].longitude,
			    maxLon = trailCoordinates[0].longitude;
			for (var i = 0; i < trailCoordinates.length - 1; i++) {
				minLat = Math.min(trailCoordinates[i + 1].latitude, minLat);
				maxLat = Math.max(trailCoordinates[i + 1].latitude, maxLat);
				minLon = Math.min(trailCoordinates[i + 1].longitude, minLon);
				maxLon = Math.max(trailCoordinates[i + 1].longitude, maxLon);
			}

			var deltaLat = maxLat - minLat;
			var deltaLon = maxLon - minLon;

			delta = Math.max(deltaLat, deltaLon);
			// Ändra om det ska vara mer zoomat
			delta = delta * 1.5;

			poiCenter.lat = maxLat - parseFloat((maxLat - minLat) / 2);
			poiCenter.lon = maxLon - parseFloat((maxLon - minLon) / 2);

			region = {
				latitude : poiCenter.lat,
				longitude : poiCenter.lon,
				latitudeDelta : delta,
				longitudeDelta : delta

			};
		}
		return region;

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - calculateMapRegion");
	}

}

//-----------------------------------------------------------
// skapar vandringsleden och sätter den på kartan
//-----------------------------------------------------------
function createMapRoute() {
	try {
		var zoomedRoute = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory + "/routes/adventureroute.json").read().text;
		var parsedRoute = JSON.parse(zoomedRoute);

		var geoArray = [];
		geoArray.push(parsedRoute);

		var coordArray = [];

		for (var u = 0; u < geoArray.length; u++) {
			var coords = geoArray[0].features[0].geometry.paths[u];

			for (var i = 0; i < coords.length; i++) {

				var point = {
					latitude : coords[i][1],
					longitude : coords[i][0]
				};
				coordArray.push(point);
			}

			var route = {
				name : 'Äventyrsleden',
				points : coordArray,
				color : 'purple',
				width : 2.0
			};

			familyMap.addRoute(MapModule.createRoute(route));
		}

		familyMap.region = calculateMapRegion(coordArray);
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - createMapRoute");
	}
}

//-----------------------------------------------------------
// Visar marker för vandringsleden
//-----------------------------------------------------------
function displayTrailMarkers() {
	try {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : 58.893198,
			longitude : 11.047852,
			title : 'Äventyrsleden',
			pincolor : MapModule.ANNOTATION_PURPLE,
			subtitle : 'Vandringsleden startar här!',
			font : {
				fontFamily : 'Raleway-Light'
			}
		});

		familyMap.addAnnotation(markerAnnotation);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - displayTrailMarkers");
	}
}

function addClueZone() {

	for (var c = 0; c < Alloy.Globals.jsonCollection.length; c++) {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : Alloy.Globals.jsonCollection[c].latitude,
			longitude : Alloy.Globals.jsonCollection[c].longitude,
			title : Alloy.Globals.jsonCollection[c].id,
			subtitle : Alloy.Globals.jsonCollection[c].letter
		});

		if (Alloy.Globals.jsonCollection[c].found == 0) {
			markerAnnotation.image = '/images/red.png';
		} else {
			markerAnnotation.image = '/images/green.png';
		}

		familyMap.addAnnotation(markerAnnotation);
	}
}

//GEO STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

function getGPSpos() {
	try {

		Ti.Geolocation.getCurrentPosition(function(e) {
			if (e.error) {
				Ti.API.info('Get current position' + e.error);
				getGPSpos();
			}
		});

		if (Ti.Geolocation.locationServicesEnabled) {
			Titanium.Geolocation.preferredProvider = Titanium.Geolocation.PROVIDER_GPS;
			Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_NEAREST_TEN_METERS;
			Titanium.Geolocation.pauseLocationUpdateAutomatically = true;
			Titanium.Geolocation.distanceFilter = 3;

			Ti.Geolocation.addEventListener('location', function(e) {
				if (e.error) {
					Ti.API.info('Kan inte sätta eventListener ' + e.error);
				} else {
					getPosition(e.coords);
					$.coords.text = 'Lat: ' + JSON.stringify(e.coords.latitude + 'Lon: ' + JSON.stringify(e.coords.longitude));

				}
			});

		} else {
			alert('Tillåt gpsen, tack');
		}
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "Map - get current position GPS");
	}

}

//-----------------------------------------------------------
// Hämtar enhetens position och kontrollerar mot punkter
//-----------------------------------------------------------
function getPosition(coordinatesObj) {
	try {
		gLat = coordinatesObj.latitude;
		gLon = coordinatesObj.longitude;

		isNearPoint();

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - getPosition");
	}
}

//-----------------------------------------------------------
// Beräknar avståndet mellan enhetens koordinater och de punkter som håller info
//-----------------------------------------------------------
function distanceInM(lat1, lon1, GLat, GLon) {
	try {
		if (lat1 == null || lon1 == null || GLat == null || GLat == null) {
			alert("Det finns inga koordinater att titta efter");
		}

		var R = 6371;
		var a = 0.5 - Math.cos((GLat - lat1) * Math.PI / 180) / 2 + Math.cos(lat1 * Math.PI / 180) * Math.cos(GLat * Math.PI / 180) * (1 - Math.cos((GLon - lon1) * Math.PI / 180)) / 2;
		var distance = (R * 2 * Math.asin(Math.sqrt(a))) * 1000;

		return distance;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - distanceInM");
	}
}

//-----------------------------------------------------------
// Kontrollerar om enhetens position är inom radien för en utsatt punkt
//-----------------------------------------------------------
function isInsideRadius(lat1, lon1, rad) {
	try {

		var isInside = false;
		var distance = distanceInM(lat1, lon1, gLat, gLon);

		if (distance <= rad) {
			isInside = true;
		}
		return isInside;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isInsideRadius");
	}
}

//-----------------------------------------------------------
// Sätter ut punkterna som ska kontrolleras, loopar
//-----------------------------------------------------------
function isNearPoint() {
	try {
		for (var i = 0; i < Alloy.Globals.jsonCollection.length; i++) {

			if (Alloy.Globals.jsonCollection[i].found == 0) {
				var lat = Alloy.Globals.jsonCollection[i].latitude;
				var lon = Alloy.Globals.jsonCollection[i].longitude;
				foundId = Alloy.Globals.jsonCollection[i].id;
				$.lblInfoText.text = Alloy.Globals.jsonCollection[i].clue;

				var message = Ti.UI.createAlertDialog({
					message : Alloy.Globals.jsonCollection[i].clue,
					title : 'Ny bokstav i närheten!'
				});
				message.show();

				Alloy.Globals.jsonCollection[i].found = 1;
			}
		}

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isNearPoint");
	}
}<|endoftext|>


<commit_before>var
	StoryFixture = require("story_fixture"),
	currentStory;

$.storyInfoView.setTop(Alloy.Globals.windowTop);

function setupTransition(transition){
	Ti.API.info("KIND: " + transition.kind);
	switch (transition.kind) {
		case "next":
			setupNextTransition(transition.param1);
			break;
		case "random":
			setupRandomTransition(transition.param1);
			break;
		case "replay":
			setupReplayTransition(transition.param1);
			break;
		case "password":
			setupPasswordTransition(transition.param1);
			break;
		case "shake":
			setupShakeTransition(transition.param1);
			break;
		default:
			Ti.API.error("Application logic fell into the void with " + transition.kind);
	}
}
function setupNextTransition(loc) {
	Ti.API.info('Next Loc: '+loc);
	// show next
	// $.storyNext.show();
	$.storyNext.setVisible(true);
}
function setupRandomTransition(loc) {
	Ti.API.info('Random Loc: '+loc);
	// show next
	$.storyRandom.setVisible(true);
}
function setupReplayTransition(loc) {
	Ti.API.info('Replay Loc: '+loc);
	$.storyReplay.setVisible(true);
}
function setupPasswordTransition(loc) {
	Ti.API.info('Replay Loc: '+loc);
	$.storyPassword.setVisible(true);
}
function setupShakeTransition(loc) {
	Ti.API.info('Loc: '+loc);
	$.storyShake.setVisible(true);
	Ti.Gesture.addEventListener("shake", shakeEvent);
}

exports.setData = function(d){
	currentStory = StoryFixture.find(d.storyid);
	Ti.API.info("CURRENT CHAPTER: " + JSON.stringify(currentStory.getCurrentChapter(), null, 2));
	refreshHtml();
};

function refreshHtml() {
	hideActionButtons();
	$.storyView.html = currentStory.getCurrentChapter().body;
	setupTransition(currentStory.getCurrentChapter().transition);
}

function advanceChapter(next_chapter_id) {
	currentStory.setNextChapter(next_chapter_id);
	refreshHtml();
}

function hideActionButtons() {
	$.storyNext.setVisible(false);
	$.storyRandom.setVisible(false);
	$.storyReplay.setVisible(false);
	$.storyPassword.setVisible(false);
	$.storyShake.setVisible(false);
}

$.storyClose.addEventListener('click', function(e){
	removeShakeEvent();
	$.storyWin.close();
});

$.storyReplay.addEventListener('click', function(e){
//	alert('currentstoryid: '+Alloy.Globals.currentstoryid+" currentstep: " + JSON.stringify(Alloy.Globals.currentchapter));
	// hide next
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
	alert("BEGIN AGAIN");
});

$.storyNext.addEventListener('click', function(e){
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
});

$.storyRandom.addEventListener('click', function(e){
//	alert('currentstoryid: '+Alloy.Globals.currentstoryid+" currentstep: " + JSON.stringify(Alloy.Globals.currentchapter));
	// hide next
	var transition = currentStory.getCurrentChapter().transition;
	Ti.API.info("PARAM1: "+ transition.param1);
	var choices = transition.param1.split(",");
	var loc = choices[Math.floor(Math.random() * choices.length)];
	Ti.API.info("LOC: "+loc);
	advanceChapter(loc);
});

$.storyPassword.addEventListener('click', function(e){
	// TODO: get password and varify
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
});

function shakeEvent(e){
	removeShakeEvent();
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
	alert("New chapter unloced!");
}

function removeShakeEvent() {
	Ti.Gesture.removeEventListener("shake", shakeEvent);
}
<commit_msg>Fixes a broken shake bug<commit_after>var
	StoryFixture = require("story_fixture"),
	currentStory;

$.storyInfoView.setTop(Alloy.Globals.windowTop);

function setupTransition(transition){
	Ti.API.info("KIND: " + transition.kind);
	switch (transition.kind) {
		case "next":
			setupNextTransition(transition.param1);
			break;
		case "random":
			setupRandomTransition(transition.param1);
			break;
		case "replay":
			setupReplayTransition(transition.param1);
			break;
		case "password":
			setupPasswordTransition(transition.param1);
			break;
		case "shake":
			setupShakeTransition(transition.param1);
			break;
		default:
			Ti.API.error("Application logic fell into the void with " + transition.kind);
	}
}
function setupNextTransition(loc) {
	Ti.API.info('Next Loc: '+loc);
	// show next
	// $.storyNext.show();
	$.storyNext.setVisible(true);
}
function setupRandomTransition(loc) {
	Ti.API.info('Random Loc: '+loc);
	// show next
	$.storyRandom.setVisible(true);
}
function setupReplayTransition(loc) {
	Ti.API.info('Replay Loc: '+loc);
	$.storyReplay.setVisible(true);
}
function setupPasswordTransition(loc) {
	Ti.API.info('Replay Loc: '+loc);
	$.storyPassword.setVisible(true);
}
function setupShakeTransition(loc) {
	Ti.API.info('Loc: '+loc);
	$.storyShake.setVisible(true);
	Ti.Gesture.addEventListener("shake", shakeEvent);
}

exports.setData = function(d){
	currentStory = StoryFixture.find(d.storyid);
	Ti.API.info("CURRENT CHAPTER: " + JSON.stringify(currentStory.getCurrentChapter(), null, 2));
	refreshHtml();
};

function refreshHtml() {
	hideActionButtons();
	$.storyView.html = currentStory.getCurrentChapter().body;
	setupTransition(currentStory.getCurrentChapter().transition);
}

function advanceChapter(next_chapter_id) {
	currentStory.setNextChapter(next_chapter_id);
	refreshHtml();
}

function hideActionButtons() {
	$.storyNext.setVisible(false);
	$.storyRandom.setVisible(false);
	$.storyReplay.setVisible(false);
	$.storyPassword.setVisible(false);
	$.storyShake.setVisible(false);
}

$.storyClose.addEventListener('click', function(e){
	$.storyWin.close();
});

$.storyReplay.addEventListener('click', function(e){
//	alert('currentstoryid: '+Alloy.Globals.currentstoryid+" currentstep: " + JSON.stringify(Alloy.Globals.currentchapter));
	// hide next
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
	alert("BEGIN AGAIN");
});

$.storyNext.addEventListener('click', function(e){
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
});

$.storyRandom.addEventListener('click', function(e){
//	alert('currentstoryid: '+Alloy.Globals.currentstoryid+" currentstep: " + JSON.stringify(Alloy.Globals.currentchapter));
	// hide next
	var transition = currentStory.getCurrentChapter().transition;
	Ti.API.info("PARAM1: "+ transition.param1);
	var choices = transition.param1.split(",");
	var loc = choices[Math.floor(Math.random() * choices.length)];
	Ti.API.info("LOC: "+loc);
	advanceChapter(loc);
});

$.storyPassword.addEventListener('click', function(e){
	// TODO: get password and varify
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
});

function shakeEvent(e){
	removeShakeEvent();
	advanceChapter(currentStory.getCurrentChapter().transition.param1);
	alert("New chapter unloced!");
}

function removeShakeEvent() {
	Ti.Gesture.removeEventListener("shake", shakeEvent);
}
<|endoftext|>


<commit_before>/* @flow */
/* eslint-disable global-require, no-console */
const fs = require('fs-extra');
const openBrowser = require('react-dev-utils/openBrowser');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');

const configurations = {
  client: {
    development: require('./config/client/development'),
    production: require('./config/client/production'),
  },
  server: {
    development: require('./config/server/development'),
    production: require('./config/server/production'),
  },
};

function createRunOnceCompiler(webpackConfig: Object): Promise<any> {
  return new Promise((resolve, reject) => {
    try {
      webpack(webpackConfig, (err) => {
        if (err) {
          return reject(err);
        }

        return resolve();
      });
    } catch (e) {
      reject(e);
    }
  });
}

const plugin: Plugin = (
  env: Environment,
  runOnce: boolean = false,
  logger: Logger
): PluginController => {
  let clientLogger;
  let serverLogger;
  const { env: envVariables, settings } = env.getConfiguration();
  let serverCompiler;
  let clientDevServer;

  return {
    async build() {
      clientLogger = logger.createGroup('client');
      serverLogger = logger.createGroup('server');
      const clientConfig = configurations.client[env.getName()](env, clientLogger);
      const serverConfig = configurations.server[env.getName()](env, serverLogger);

      fs.removeSync(settings.client.bundleDir);
      fs.removeSync(settings.server.bundleDir);

      const compilers = [
        createRunOnceCompiler(clientConfig),
        createRunOnceCompiler(serverConfig),
      ];

      return await Promise.all(compilers);
    },

    async start() {
      clientLogger = logger.createGroup('client');
      serverLogger = logger.createGroup('server');
      const clientConfig = configurations.client[env.getName()](env, clientLogger);
      const serverConfig = configurations.server[env.getName()](env, serverLogger);

      return new Promise((resolve, reject) => {
        try {
          const clientCompiler = webpack(clientConfig);

          clientDevServer = new WebpackDevServer(clientCompiler, {
            clientLogLevel: 'none',
            contentBase: envVariables.PUBLIC_DIR,
            historyApiFallback: {
              disableDotRule: true,
            },
            https: settings.client.protocol === 'https',
            host: 'localhost',
            hot: true,
            proxy: {
              '!(/__webpack_hmr|**/*.*)': `http://localhost:${envVariables.SERVER_PORT}`,
            },
            publicPath: '/',
            quiet: true,
            watchOptions: {
              ignored: /node_modules/,
            },
          });

          clientDevServer.listen(envVariables.SERVER_PORT - 1, (err) => {
            if (err) {
              console.log(err);
              return reject(err);
            }

            return openBrowser(
              `${settings.client.protocol || 'http'}://localhost:${envVariables.SERVER_PORT - 1}/`
            );
          });

          serverCompiler = webpack({
            ...serverConfig,
            watchOptions: {
              ignored: /node_modules/,
            },
          }).watch({}, () => {});
        } catch (e) {
          reject(e);
        }

        resolve();
      });
    },

    async terminate() {
      clientLogger.remove();
      serverLogger.remove();

      if (serverCompiler) {
        return Promise.all([
          new Promise(resolve => serverCompiler.close(resolve)),
          new Promise(resolve => clientDevServer.close(resolve)),
        ]);
      }

      return true;
    },
  };
};

module.exports = plugin;
<commit_msg>:bug: terminate build command if build errors, closes #19<commit_after>/* @flow */
/* eslint-disable global-require, no-console */
const fs = require('fs-extra');
const openBrowser = require('react-dev-utils/openBrowser');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');

const configurations = {
  client: {
    development: require('./config/client/development'),
    production: require('./config/client/production'),
  },
  server: {
    development: require('./config/server/development'),
    production: require('./config/server/production'),
  },
};

function createRunOnceCompiler(webpackConfig: Object): Promise<any> {
  return new Promise((resolve, reject) => {
    try {
      webpack(webpackConfig, (err, stats) => {
        if (err || stats.hasErrors()) {
          return reject(err);
        }

        return resolve();
      });
    } catch (e) {
      reject(e);
    }
  });
}

const plugin: Plugin = (
  env: Environment,
  runOnce: boolean = false,
  logger: Logger
): PluginController => {
  let clientLogger;
  let serverLogger;
  const { env: envVariables, settings } = env.getConfiguration();
  let serverCompiler;
  let clientDevServer;

  return {
    async build() {
      clientLogger = logger.createGroup('client');
      serverLogger = logger.createGroup('server');
      const clientConfig = configurations.client[env.getName()](env, clientLogger);
      const serverConfig = configurations.server[env.getName()](env, serverLogger);

      fs.removeSync(settings.client.bundleDir);
      fs.removeSync(settings.server.bundleDir);

      const compilers = [
        createRunOnceCompiler(clientConfig),
        createRunOnceCompiler(serverConfig),
      ];

      return await Promise.all(compilers);
    },

    async start() {
      clientLogger = logger.createGroup('client');
      serverLogger = logger.createGroup('server');
      const clientConfig = configurations.client[env.getName()](env, clientLogger);
      const serverConfig = configurations.server[env.getName()](env, serverLogger);

      return new Promise((resolve, reject) => {
        try {
          const clientCompiler = webpack(clientConfig);

          clientDevServer = new WebpackDevServer(clientCompiler, {
            clientLogLevel: 'none',
            contentBase: envVariables.PUBLIC_DIR,
            historyApiFallback: {
              disableDotRule: true,
            },
            https: settings.client.protocol === 'https',
            host: 'localhost',
            hot: true,
            proxy: {
              '!(/__webpack_hmr|**/*.*)': `http://localhost:${envVariables.SERVER_PORT}`,
            },
            publicPath: '/',
            quiet: true,
            watchOptions: {
              ignored: /node_modules/,
            },
          });

          clientDevServer.listen(envVariables.SERVER_PORT - 1, (err) => {
            if (err) {
              console.log(err);
              return reject(err);
            }

            return openBrowser(
              `${settings.client.protocol || 'http'}://localhost:${envVariables.SERVER_PORT - 1}/`
            );
          });

          serverCompiler = webpack({
            ...serverConfig,
            watchOptions: {
              ignored: /node_modules/,
            },
          }).watch({}, () => {});
        } catch (e) {
          reject(e);
        }

        resolve();
      });
    },

    async terminate() {
      clientLogger.remove();
      serverLogger.remove();

      if (serverCompiler) {
        return Promise.all([
          new Promise(resolve => serverCompiler.close(resolve)),
          new Promise(resolve => clientDevServer.close(resolve)),
        ]);
      }

      return true;
    },
  };
};

module.exports = plugin;
<|endoftext|>


<commit_before>/* globals FileUploadBase:true, UploadFS */
/* exported FileUploadBase */

UploadFS.config.defaultStorePermissions = new UploadFS.StorePermissions({
	insert: function(userId/*, doc*/) {
		return userId;
	},
	update: function(userId, doc) {
		return userId === doc.userId;
	},
	remove: function(userId, doc) {
		return RocketChat.authz.hasPermission(Meteor.userId(), 'delete-message', doc.rid) || (RocketChat.settings.get('Message_AllowDeleting') && userId === doc.userId);
	}
});

FileUploadBase = class FileUploadBase {
	constructor(meta, file) {
		this.id = Random.id();
		this.meta = meta;
		this.file = file;
	}

	getProgress() {

	}

	getFileName() {
		return this.meta.name;
	}

	start() {

	}

	stop() {

	}
};
<commit_msg>Bugfix: Cannot remove uploads<commit_after>/* globals FileUploadBase:true, UploadFS */
/* exported FileUploadBase */

UploadFS.config.defaultStorePermissions = new UploadFS.StorePermissions({
	insert: function(userId/*, doc*/) {
		return userId;
	},
	update: function(userId, doc) {
		return RocketChat.authz.hasPermission(Meteor.userId(), 'delete-message', doc.rid) || (RocketChat.settings.get('Message_AllowDeleting') && userId === doc.userId);
	},
	remove: function(userId, doc) {
		return RocketChat.authz.hasPermission(Meteor.userId(), 'delete-message', doc.rid) || (RocketChat.settings.get('Message_AllowDeleting') && userId === doc.userId);
	}
});

FileUploadBase = class FileUploadBase {
	constructor(meta, file) {
		this.id = Random.id();
		this.meta = meta;
		this.file = file;
	}

	getProgress() {

	}

	getFileName() {
		return this.meta.name;
	}

	start() {

	}

	stop() {

	}
};
<|endoftext|>


<commit_before>/* globals loki, MongoInternals */
/* eslint new-cap: 0 */

const {EventEmitter} = Npm.require('events');
const objectPath = Npm.require('object-path');

const ignore = [
	'emit',
	'load',
	'on',
	'addToAllIndexes'
];

function traceMethodCalls(target) {
	target._stats = {};

	for (const property in target) {
		if (typeof target[property] === 'function' && ignore.indexOf(property) === -1) {
			target._stats[property] = {
				calls: 0,
				time: 0,
				avg: 0
			};
			const origMethod = target[property];
			target[property] = function(...args) {

				if (target.loaded !== true) {
					return origMethod.apply(target, args);
				}

				const startTime = RocketChat.statsTracker.now();
				const result = origMethod.apply(target, args);
				const time = Math.round(RocketChat.statsTracker.now() - startTime) / 1000;
				target._stats[property].time += time;
				target._stats[property].calls++;
				target._stats[property].avg = target._stats[property].time / target._stats[property].calls;

				return result;
			};
		}
	}

	setInterval(function() {
		for (const property in target._stats) {
			if (target._stats.hasOwnProperty(property) && target._stats[property].time > 0) {
				const tags = [`property:${property}`, `collection:${target.collectionName}`];
				RocketChat.statsTracker.timing('cache.methods.time', target._stats[property].avg, tags);
				RocketChat.statsTracker.increment('cache.methods.totalTime', target._stats[property].time, tags);
				RocketChat.statsTracker.increment('cache.methods.count', target._stats[property].calls, tags);
				target._stats[property].avg = 0;
				target._stats[property].time = 0;
				target._stats[property].calls = 0;
			}
		}
	}, 10000);

	target._getStatsAvg = function() {
		const stats = [];
		for (const property in target._stats) {
			if (target._stats.hasOwnProperty(property)) {
				stats.push([Math.round(target._stats[property].avg*100)/100, property]);
			}
		}
		return _.sortBy(stats, function(record) {
			return record[0];
		});
	};
}

RocketChat.cache = {};

class Adapter {
	loadDatabase(/*dbname, callback*/) {}
	saveDatabase(/*dbname, dbstring, callback*/) {}
	deleteDatabase(/*dbname, callback*/) {}
}

const db = new loki('rocket.chat.json', {adapter: Adapter});

RocketChat.cache._Base = (class CacheBase extends EventEmitter {
	constructor(collectionName) {
		super();

		traceMethodCalls(this);

		this.indexes = {
			_id: {type: 'unique'}
		};

		this.joins = {};

		this.db = db;
		this.collectionName = collectionName;
		this.register();
	}

	hasOne(join, {field, link}) {
		this.join({join, field, link, multi: false});
	}

	hasMany(join, {field, link}) {
		this.join({join, field, link, multi: true});
	}

	join({join, field, link, multi}) {
		if (!RocketChat.cache[join]) {
			console.log(`Invalid cache model ${join}`);
			return;
		}

		RocketChat.cache[join].on('inserted', (record) => {
			this.processRemoteJoinInserted({join, field, link, multi, record: record});
		});

		RocketChat.cache[join].on('beforeupdate', (record, diff) => {
			if (diff[link.remote]) {
				this.processRemoteJoinRemoved({join, field, link, multi, record: record});
			}
		});

		RocketChat.cache[join].on('updated', (record, diff) => {
			if (diff[link.remote]) {
				this.processRemoteJoinInserted({join, field, link, multi, record: record});
			}
		});

		RocketChat.cache[join].on('removed', (record) => {
			this.processRemoteJoinRemoved({join, field, link, multi, record: record});
		});

		this.on('inserted', (localRecord) => {
			this.processLocalJoinInserted({join, field, link, multi, localRecord: localRecord});
		});

		this.on('beforeupdate', (localRecord, diff) => {
			if (diff[link.local]) {
				if (multi === true) {
					localRecord[field] = [];
				} else {
					localRecord[field] = undefined;
				}
			}
		});

		this.on('updated', (localRecord, diff) => {
			if (diff[link.local]) {
				this.processLocalJoinInserted({join, field, link, multi, localRecord: localRecord});
			}
		});
	}

	processRemoteJoinInserted({field, link, multi, record}) {
		let localRecords = this.findByIndex(link.local, record[link.remote]);

		if (!localRecords) {
			return;
		}

		if (!Array.isArray(localRecords)) {
			localRecords = [localRecords];
		}

		for (var i = 0; i < localRecords.length; i++) {
			const localRecord = localRecords[i];
			if (multi === true && !localRecord[field]) {
				localRecord[field] = [];
			}

			if (typeof link.transform === 'function') {
				record = link.transform(localRecord, record);
			}

			if (multi === true) {
				localRecord[field].push(record);
			} else {
				localRecord[field] = record;
			}

			this.emit(`join:${field}:${localRecord._id}:inserted`, record);
		}
	}

	processLocalJoinInserted({join, field, link, multi, localRecord}) {
		let records = RocketChat.cache[join].findByIndex(link.remote, localRecord[link.local]);

		if (!Array.isArray(records)) {
			records = [records];
		}

		for (let i = 0; i < records.length; i++) {
			let record = records[i];

			if (typeof link.transform === 'function') {
				record = link.transform(localRecord, record);
			}

			if (multi === true) {
				localRecord[field].push(record);
			} else {
				localRecord[field] = record;
			}

			this.emit(`join:${field}:${localRecord._id}:inserted`, record);
		}
	}

	processRemoteJoinRemoved({field, link, multi, record}) {
		let localRecords = this.findByIndex(link.local, record[link.remote]);

		if (!localRecords) {
			return;
		}

		if (!Array.isArray(localRecords)) {
			localRecords = [localRecords];
		}

		for (var i = 0; i < localRecords.length; i++) {
			const localRecord = localRecords[i];

			if (multi === true) {
				if (Array.isArray(localRecord[field])) {
					if (typeof link.remove === 'function') {
						link.remove(localRecord[field], record);
					} else if (localRecord[field].indexOf(record) > -1) {
						localRecord[field].splice(localRecord[field].indexOf(record), 1);
					}
				}
			} else {
				localRecord[field] = undefined;
			}

			this.emit(`join:${field}:${localRecord._id}:removed`, record);
		}
	}

	addToAllIndexes(record) {
		for (const index in this.indexes) {
			if (this.indexes.hasOwnProperty(index)) {
				this.addToIndex(index, record);
			}
		}
	}

	addToIndex(index, record) {
		if (!this.indexes[index]) {
			console.error(`Index not defined ${index}`);
			return;
		}

		if (!this.indexes[index].data) {
			this.indexes[index].data = {};
		}

		if (this.indexes[index].type === 'unique') {
			this.indexes[index].data[record[index]] = record;
			return;
		}

		if (this.indexes[index].type === 'array') {
			if (!this.indexes[index].data[record[index]]) {
				this.indexes[index].data[record[index]] = [];
			}
			this.indexes[index].data[record[index]].push(record);
			return;
		}
	}

	removeFromAllIndexes(record) {
		for (const index in this.indexes) {
			if (this.indexes.hasOwnProperty(index)) {
				this.removeFromIndex(index, record);
			}
		}
	}

	removeFromIndex(index, record) {
		if (!this.indexes[index]) {
			console.error(`Index not defined ${index}`);
			return;
		}

		if (!this.indexes[index].data) {
			return;
		}

		if (this.indexes[index].type === 'unique') {
			this.indexes[index].data[record[index]] = undefined;
			return;
		}

		if (this.indexes[index].type === 'array') {
			if (!this.indexes[index].data[record[index]]) {
				return;
			}
			const i = this.indexes[index].data[record[index]].indexOf(record);
			if (i > -1) {
				this.indexes[index].data[record[index]].splice(i, 1);
			}
			return;
		}
	}

	findByIndex(index, key) {
		if (!this.indexes[index]) {
			return;
		}

		if (this.indexes[index].data) {
			const result = this.indexes[index].data[key];
			if (result) {
				return result;
			}
		}

		if (this.indexes[index].type === 'array') {
			return [];
		}
	}

	register() {
		this.model = RocketChat.models[this.collectionName];
		this.collection = this.db.addCollection(this.collectionName);
	}

	load() {
		this.emit('beforeload');
		this.loaded = false;
		const time = RocketChat.statsTracker.now();
		const data = this.model.find().fetch();
		for (let i=0; i < data.length; i++) {
			this.insert(data[i]);
		}
		RocketChat.statsTracker.timing('cache.load', RocketChat.statsTracker.now() - time, [`collection:${this.collectionName}`]);
		this.startOplog();
		this.loaded = true;
		this.emit('afterload');
	}

	startOplog() {
		const query = {
			collection: this.model.model._name
		};

		MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle.onOplogEntry(query, (record) => {
			this.processOplogRecord(record);
		});
	}

	processOplogRecord(action) {
		// console.log(this.collectionName, JSON.stringify(action, null, 2));
		if (action.op.op === 'i') {
			this.insert(action.op.o);
			return;
		}

		if (action.op.op === 'u') {
			let diff = {};

			if (!action.op.o.$set && !action.op.o.$set) {
				diff = action.op.o;
			} else {
				if (action.op.o.$set) {
					for (let key in action.op.o.$set) {
						if (action.op.o.$set.hasOwnProperty(key)) {
							diff[key] = action.op.o.$set[key];
						}
					}
				}

				if (action.op.o.$unset) {
					for (let key in action.op.o.$unset) {
						if (action.op.o.$set.hasOwnProperty(key)) {
							diff[key] = undefined;
						}
					}
				}
			}

			this.updateDiffById(action.id, diff);
			return;
		}

		if (action.op.op === 'd') {
			this.removeById(action.id);
			return;
		}
	}

	find(...findArguments) {
		return {
			fetch: () => {
				return this.collection.find(...findArguments);
			},

			count: () => {
				return this.collection.find(...findArguments).length;
			},

			forEach: (fn) => {
				return this.collection.find(...findArguments).forEach(fn);
			}
		};
	}

	findOne() {
		return this.collection.findOne(...arguments);
	}

	findWhere() {
		return this.collection.findWhere(...arguments);
	}

	addDynamicView() {
		return this.collection.addDynamicView(...arguments);
	}

	getDynamicView() {
		return this.collection.getDynamicView(...arguments);
	}

	insert(record) {
		if (Array.isArray(record)) {
			for (let i=0; i < record.length; i++) {
				this.addToAllIndexes(record[i]);
				this.collection.insert(record[i]);
				this.emit('inserted', record[i]);
			}
		} else {
			this.addToAllIndexes(record);
			this.collection.insert(record);
			this.emit('inserted', record);
		}
	}

	updateDiffById(id, diff) {
		const record = this.collection.findOne({_id: id});
		this.emit('beforeupdate', record, diff);

		for (let key in diff) {
			if (diff.hasOwnProperty(key)) {
				objectPath.set(record, key, diff[key]);
			}
		}

		this.collection.update(record);

		this.emit('updated', record, diff);
	}

	removeById(id) {
		const record = this.findByIndex('_id', id);
		if (record) {
			this.collection.removeWhere({_id: id});
			this.removeFromAllIndexes(record);
			this.emit('removed', record);
		}
	}
});
<commit_msg>Add option to select fields when querying from cache<commit_after>/* globals loki, MongoInternals */
/* eslint new-cap: 0 */

const {EventEmitter} = Npm.require('events');
const objectPath = Npm.require('object-path');

const ignore = [
	'emit',
	'load',
	'on',
	'addToAllIndexes'
];

function traceMethodCalls(target) {
	target._stats = {};

	for (const property in target) {
		if (typeof target[property] === 'function' && ignore.indexOf(property) === -1) {
			target._stats[property] = {
				calls: 0,
				time: 0,
				avg: 0
			};
			const origMethod = target[property];
			target[property] = function(...args) {

				if (target.loaded !== true) {
					return origMethod.apply(target, args);
				}

				const startTime = RocketChat.statsTracker.now();
				const result = origMethod.apply(target, args);
				const time = Math.round(RocketChat.statsTracker.now() - startTime) / 1000;
				target._stats[property].time += time;
				target._stats[property].calls++;
				target._stats[property].avg = target._stats[property].time / target._stats[property].calls;

				return result;
			};
		}
	}

	setInterval(function() {
		for (const property in target._stats) {
			if (target._stats.hasOwnProperty(property) && target._stats[property].time > 0) {
				const tags = [`property:${property}`, `collection:${target.collectionName}`];
				RocketChat.statsTracker.timing('cache.methods.time', target._stats[property].avg, tags);
				RocketChat.statsTracker.increment('cache.methods.totalTime', target._stats[property].time, tags);
				RocketChat.statsTracker.increment('cache.methods.count', target._stats[property].calls, tags);
				target._stats[property].avg = 0;
				target._stats[property].time = 0;
				target._stats[property].calls = 0;
			}
		}
	}, 10000);

	target._getStatsAvg = function() {
		const stats = [];
		for (const property in target._stats) {
			if (target._stats.hasOwnProperty(property)) {
				stats.push([Math.round(target._stats[property].avg*100)/100, property]);
			}
		}
		return _.sortBy(stats, function(record) {
			return record[0];
		});
	};
}

RocketChat.cache = {};

class Adapter {
	loadDatabase(/*dbname, callback*/) {}
	saveDatabase(/*dbname, dbstring, callback*/) {}
	deleteDatabase(/*dbname, callback*/) {}
}

const db = new loki('rocket.chat.json', {adapter: Adapter});

RocketChat.cache._Base = (class CacheBase extends EventEmitter {
	constructor(collectionName) {
		super();

		traceMethodCalls(this);

		this.indexes = {
			_id: {type: 'unique'}
		};

		this.joins = {};

		this.db = db;
		this.collectionName = collectionName;
		this.register();
	}

	hasOne(join, {field, link}) {
		this.join({join, field, link, multi: false});
	}

	hasMany(join, {field, link}) {
		this.join({join, field, link, multi: true});
	}

	join({join, field, link, multi}) {
		if (!RocketChat.cache[join]) {
			console.log(`Invalid cache model ${join}`);
			return;
		}

		RocketChat.cache[join].on('inserted', (record) => {
			this.processRemoteJoinInserted({join, field, link, multi, record: record});
		});

		RocketChat.cache[join].on('beforeupdate', (record, diff) => {
			if (diff[link.remote]) {
				this.processRemoteJoinRemoved({join, field, link, multi, record: record});
			}
		});

		RocketChat.cache[join].on('updated', (record, diff) => {
			if (diff[link.remote]) {
				this.processRemoteJoinInserted({join, field, link, multi, record: record});
			}
		});

		RocketChat.cache[join].on('removed', (record) => {
			this.processRemoteJoinRemoved({join, field, link, multi, record: record});
		});

		this.on('inserted', (localRecord) => {
			this.processLocalJoinInserted({join, field, link, multi, localRecord: localRecord});
		});

		this.on('beforeupdate', (localRecord, diff) => {
			if (diff[link.local]) {
				if (multi === true) {
					localRecord[field] = [];
				} else {
					localRecord[field] = undefined;
				}
			}
		});

		this.on('updated', (localRecord, diff) => {
			if (diff[link.local]) {
				this.processLocalJoinInserted({join, field, link, multi, localRecord: localRecord});
			}
		});
	}

	processRemoteJoinInserted({field, link, multi, record}) {
		let localRecords = this.findByIndex(link.local, record[link.remote]);

		if (!localRecords) {
			return;
		}

		if (!Array.isArray(localRecords)) {
			localRecords = [localRecords];
		}

		for (var i = 0; i < localRecords.length; i++) {
			const localRecord = localRecords[i];
			if (multi === true && !localRecord[field]) {
				localRecord[field] = [];
			}

			if (typeof link.transform === 'function') {
				record = link.transform(localRecord, record);
			}

			if (multi === true) {
				localRecord[field].push(record);
			} else {
				localRecord[field] = record;
			}

			this.emit(`join:${field}:${localRecord._id}:inserted`, record);
		}
	}

	processLocalJoinInserted({join, field, link, multi, localRecord}) {
		let records = RocketChat.cache[join].findByIndex(link.remote, localRecord[link.local]);

		if (!Array.isArray(records)) {
			records = [records];
		}

		for (let i = 0; i < records.length; i++) {
			let record = records[i];

			if (typeof link.transform === 'function') {
				record = link.transform(localRecord, record);
			}

			if (multi === true) {
				localRecord[field].push(record);
			} else {
				localRecord[field] = record;
			}

			this.emit(`join:${field}:${localRecord._id}:inserted`, record);
		}
	}

	processRemoteJoinRemoved({field, link, multi, record}) {
		let localRecords = this.findByIndex(link.local, record[link.remote]);

		if (!localRecords) {
			return;
		}

		if (!Array.isArray(localRecords)) {
			localRecords = [localRecords];
		}

		for (var i = 0; i < localRecords.length; i++) {
			const localRecord = localRecords[i];

			if (multi === true) {
				if (Array.isArray(localRecord[field])) {
					if (typeof link.remove === 'function') {
						link.remove(localRecord[field], record);
					} else if (localRecord[field].indexOf(record) > -1) {
						localRecord[field].splice(localRecord[field].indexOf(record), 1);
					}
				}
			} else {
				localRecord[field] = undefined;
			}

			this.emit(`join:${field}:${localRecord._id}:removed`, record);
		}
	}

	addToAllIndexes(record) {
		for (const index in this.indexes) {
			if (this.indexes.hasOwnProperty(index)) {
				this.addToIndex(index, record);
			}
		}
	}

	addToIndex(index, record) {
		if (!this.indexes[index]) {
			console.error(`Index not defined ${index}`);
			return;
		}

		if (!this.indexes[index].data) {
			this.indexes[index].data = {};
		}

		if (this.indexes[index].type === 'unique') {
			this.indexes[index].data[record[index]] = record;
			return;
		}

		if (this.indexes[index].type === 'array') {
			if (!this.indexes[index].data[record[index]]) {
				this.indexes[index].data[record[index]] = [];
			}
			this.indexes[index].data[record[index]].push(record);
			return;
		}
	}

	removeFromAllIndexes(record) {
		for (const index in this.indexes) {
			if (this.indexes.hasOwnProperty(index)) {
				this.removeFromIndex(index, record);
			}
		}
	}

	removeFromIndex(index, record) {
		if (!this.indexes[index]) {
			console.error(`Index not defined ${index}`);
			return;
		}

		if (!this.indexes[index].data) {
			return;
		}

		if (this.indexes[index].type === 'unique') {
			this.indexes[index].data[record[index]] = undefined;
			return;
		}

		if (this.indexes[index].type === 'array') {
			if (!this.indexes[index].data[record[index]]) {
				return;
			}
			const i = this.indexes[index].data[record[index]].indexOf(record);
			if (i > -1) {
				this.indexes[index].data[record[index]].splice(i, 1);
			}
			return;
		}
	}

	findByIndex(index, key) {
		if (!this.indexes[index]) {
			return;
		}

		if (this.indexes[index].data) {
			const result = this.indexes[index].data[key];
			if (result) {
				return result;
			}
		}

		if (this.indexes[index].type === 'array') {
			return [];
		}
	}

	register() {
		this.model = RocketChat.models[this.collectionName];
		this.collection = this.db.addCollection(this.collectionName);
	}

	load() {
		this.emit('beforeload');
		this.loaded = false;
		const time = RocketChat.statsTracker.now();
		const data = this.model.find().fetch();
		for (let i=0; i < data.length; i++) {
			this.insert(data[i]);
		}
		RocketChat.statsTracker.timing('cache.load', RocketChat.statsTracker.now() - time, [`collection:${this.collectionName}`]);
		this.startOplog();
		this.loaded = true;
		this.emit('afterload');
	}

	startOplog() {
		const query = {
			collection: this.model.model._name
		};

		MongoInternals.defaultRemoteCollectionDriver().mongo._oplogHandle.onOplogEntry(query, (record) => {
			this.processOplogRecord(record);
		});
	}

	processOplogRecord(action) {
		// console.log(this.collectionName, JSON.stringify(action, null, 2));
		if (action.op.op === 'i') {
			this.insert(action.op.o);
			return;
		}

		if (action.op.op === 'u') {
			let diff = {};

			if (!action.op.o.$set && !action.op.o.$set) {
				diff = action.op.o;
			} else {
				if (action.op.o.$set) {
					for (let key in action.op.o.$set) {
						if (action.op.o.$set.hasOwnProperty(key)) {
							diff[key] = action.op.o.$set[key];
						}
					}
				}

				if (action.op.o.$unset) {
					for (let key in action.op.o.$unset) {
						if (action.op.o.$set.hasOwnProperty(key)) {
							diff[key] = undefined;
						}
					}
				}
			}

			this.updateDiffById(action.id, diff);
			return;
		}

		if (action.op.op === 'd') {
			this.removeById(action.id);
			return;
		}
	}

	find(query, options={}) {
		return {
			fetch: () => {
				if (!options.fields) {
					options.fields = {
						$loki: 0
					};
				}

				const fieldsToRemove = [];
				const fieldsToGet = [];

				for (const field in options.fields) {
					if (options.fields.hasOwnProperty(field)) {
						if (options.fields[field] === 0) {
							fieldsToRemove.push(field);
						} else if (options.fields[field] === 1) {
							fieldsToGet.push(field);
						}
					}
				}

				if (fieldsToRemove.length > 0 && fieldsToGet.length > 0) {
					console.error('Can\'t mix remove and get fields');
					fieldsToRemove.splice(0, fieldsToRemove.length);
				}

				const result = this.collection.find(query).map((record) => {
					if (fieldsToRemove.length > 0) {
						return _.omit(record, ...fieldsToRemove);
					}

					if (fieldsToGet.length > 0) {
						return _.pick(record, ...fieldsToGet);
					}
				});

				return result;
			},

			count: () => {
				return this.collection.find(query).length;
			},

			forEach: (fn) => {
				return this.find(query, options).fetch().forEach(fn);
			}
		};
	}

	findOne() {
		return this.collection.findOne(...arguments);
	}

	findWhere() {
		return this.collection.findWhere(...arguments);
	}

	addDynamicView() {
		return this.collection.addDynamicView(...arguments);
	}

	getDynamicView() {
		return this.collection.getDynamicView(...arguments);
	}

	insert(record) {
		if (Array.isArray(record)) {
			for (let i=0; i < record.length; i++) {
				this.addToAllIndexes(record[i]);
				this.collection.insert(record[i]);
				this.emit('inserted', record[i]);
			}
		} else {
			this.addToAllIndexes(record);
			this.collection.insert(record);
			this.emit('inserted', record);
		}
	}

	updateDiffById(id, diff) {
		const record = this.collection.findOne({_id: id});
		this.emit('beforeupdate', record, diff);

		for (let key in diff) {
			if (diff.hasOwnProperty(key)) {
				objectPath.set(record, key, diff[key]);
			}
		}

		this.collection.update(record);

		this.emit('updated', record, diff);
	}

	removeById(id) {
		const record = this.findByIndex('_id', id);
		if (record) {
			this.collection.removeWhere({_id: id});
			this.removeFromAllIndexes(record);
			this.emit('removed', record);
		}
	}
});
<|endoftext|>


<commit_before>/* eslint-env browser */

const STYLES_HYDRATOR = /\.([^{:]+)(:[^{]+)?{(?:[^}]*;)?([^}]*?)}/g;
const KEYFRAMES_HYRDATOR = /@keyframes ([^{]+)\{((?:[^{]+\{[^}]*\})*)\}/g;
const FONT_FACE_HYDRATOR = /@font-face\{font-family:([^;]+);([^}]*)\}/g;

type hydratorT =
  | typeof STYLES_HYDRATOR
  | typeof KEYFRAMES_HYRDATOR
  | typeof FONT_FACE_HYDRATOR;

function hydrateStyles<T>(cache: Cache<T>, hydrator: hydratorT, css: string) {
  let match;
  while ((match = hydrator.exec(css))) {
    const [, id, pseudo, key] = match;
    const fullKey = pseudo ? `${pseudo}${key}` : key;
    cache.cache[fullKey] = id; // set cache without triggering side effects
    cache.idGenerator.increment(); // increment id
  }
}

function hydrate<T>(cache: Cache<T>, hydrator: hydratorT, css: string) {
  let match;
  while ((match = hydrator.exec(css))) {
    const [, id, key] = match;
    cache.cache[key] = id; // set cache without triggering side effects
    cache.idGenerator.increment(); // increment id
  }
}

import SequentialIDGenerator from "../sequential-id-generator.js";

import type {
  StandardEngine,
  keyframesT,
  fontFaceT,
  baseStyleT,
} from "styletron-standard";

import {Cache, MultiCache} from "../cache.js";

import injectStylePrefixed from "../inject-style-prefixed.js";

import {
  styleBlockToRule,
  atomicSelector,
  keyframesBlockToRule,
  declarationsToBlock,
  keyframesToBlock,
  fontFaceBlockToRule,
} from "../css.js";

type hydrateT =
  | HTMLCollection<HTMLStyleElement>
  | Array<HTMLStyleElement>
  | NodeList<HTMLStyleElement>;

type optionsT = {
  hydrate?: hydrateT,
  container?: Element,
  prefix?: string,
};

class StyletronClient implements StandardEngine {
  container: Element;
  styleElements: {[string]: HTMLStyleElement};
  fontFaceSheet: HTMLStyleElement;
  keyframesSheet: HTMLStyleElement;

  styleCache: MultiCache<{pseudo: string, block: string}>;
  keyframesCache: Cache<keyframesT>;
  fontFaceCache: Cache<fontFaceT>;

  constructor(opts?: optionsT = {}) {
    this.styleElements = {};

    const styleIdGenerator = new SequentialIDGenerator(opts.prefix);
    const onNewStyle = (cache, id, value) => {
      const {pseudo, block} = value;
      const sheet: CSSStyleSheet = (this.styleElements[cache.key].sheet: any);
      sheet.insertRule(
        styleBlockToRule(atomicSelector(id, pseudo), block),
        sheet.cssRules.length,
      );
    };

    // Setup style cache
    this.styleCache = new MultiCache(
      styleIdGenerator,
      media => {
        const styleElement = document.createElement("style");
        styleElement.media = media;
        this.container.appendChild(styleElement);
        this.styleElements[media] = styleElement;
      },
      onNewStyle,
    );

    this.keyframesCache = new Cache(
      new SequentialIDGenerator(opts.prefix),
      (cache, id, value) => {
        this.styleCache.getCache("");
        const sheet: CSSStyleSheet = (this.styleElements[""].sheet: any);
        sheet.insertRule(
          keyframesBlockToRule(id, keyframesToBlock(value)),
          sheet.cssRules.length,
        );
      },
    );

    this.fontFaceCache = new Cache(
      new SequentialIDGenerator(opts.prefix),
      (cache, id, value) => {
        this.styleCache.getCache("");
        const sheet: CSSStyleSheet = (this.styleElements[""].sheet: any);
        sheet.insertRule(
          fontFaceBlockToRule(id, declarationsToBlock(value)),
          sheet.cssRules.length,
        );
      },
    );

    if (opts.container) {
      this.container = opts.container;
    }

    // Hydrate
    if (opts.hydrate && opts.hydrate.length > 0) {
      // infer container from parent element
      if (!this.container) {
        const parentElement = opts.hydrate[0].parentElement;
        if (parentElement !== null && parentElement !== void 0) {
          this.container = parentElement;
        }
      }

      for (let i = 0; i < opts.hydrate.length; i++) {
        const element = opts.hydrate[i];
        const hydrateType = element.dataset.hydrate;
        if (hydrateType === "font-face") {
          hydrate(this.fontFaceCache, FONT_FACE_HYDRATOR, element.textContent);
          continue;
        }
        if (hydrateType === "keyframes") {
          hydrate(this.keyframesCache, KEYFRAMES_HYRDATOR, element.textContent);
          continue;
        }
        const key = element.media ? element.media : "";
        this.styleElements[key] = element;
        const cache = new Cache(styleIdGenerator, onNewStyle);
        cache.key = key;
        hydrateStyles(cache, STYLES_HYDRATOR, element.textContent);
        this.styleCache.caches[key] = cache;
      }
    }

    if (!this.container) {
      if (document.head === null) {
        throw new Error("No container provided and `document.head` was null");
      }
      this.container = document.head;
    }
  }

  renderStyle(style: baseStyleT): string {
    return injectStylePrefixed(this.styleCache, style, "", "");
  }

  renderFontFace(fontFace: fontFaceT): string {
    const key = declarationsToBlock(fontFace);
    return this.fontFaceCache.addValue(key, fontFace);
  }

  renderKeyframes(keyframes: keyframesT): string {
    const key = keyframesToBlock(keyframes);
    return this.keyframesCache.addValue(key, keyframes);
  }
}

export default StyletronClient;
<commit_msg>Annotate styletron-engine-atomic/src/client.js with @flow to ensure types can be used in consumers<commit_after>// @flow

/* eslint-env browser */

const STYLES_HYDRATOR = /\.([^{:]+)(:[^{]+)?{(?:[^}]*;)?([^}]*?)}/g;
const KEYFRAMES_HYRDATOR = /@keyframes ([^{]+)\{((?:[^{]+\{[^}]*\})*)\}/g;
const FONT_FACE_HYDRATOR = /@font-face\{font-family:([^;]+);([^}]*)\}/g;

type hydratorT =
  | typeof STYLES_HYDRATOR
  | typeof KEYFRAMES_HYRDATOR
  | typeof FONT_FACE_HYDRATOR;

function hydrateStyles<T>(cache: Cache<T>, hydrator: hydratorT, css: string) {
  let match;
  while ((match = hydrator.exec(css))) {
    const [, id, pseudo, key] = match;
    const fullKey = pseudo ? `${pseudo}${key}` : key;
    cache.cache[fullKey] = id; // set cache without triggering side effects
    cache.idGenerator.increment(); // increment id
  }
}

function hydrate<T>(cache: Cache<T>, hydrator: hydratorT, css: string) {
  let match;
  while ((match = hydrator.exec(css))) {
    const [, id, key] = match;
    cache.cache[key] = id; // set cache without triggering side effects
    cache.idGenerator.increment(); // increment id
  }
}

import SequentialIDGenerator from "../sequential-id-generator.js";

import type {
  StandardEngine,
  keyframesT,
  fontFaceT,
  baseStyleT,
} from "styletron-standard";

import {Cache, MultiCache} from "../cache.js";

import injectStylePrefixed from "../inject-style-prefixed.js";

import {
  styleBlockToRule,
  atomicSelector,
  keyframesBlockToRule,
  declarationsToBlock,
  keyframesToBlock,
  fontFaceBlockToRule,
} from "../css.js";

type hydrateT =
  | HTMLCollection<HTMLStyleElement>
  | Array<HTMLStyleElement>
  | NodeList<HTMLStyleElement>;

type optionsT = {
  hydrate?: hydrateT,
  container?: Element,
  prefix?: string,
};

class StyletronClient implements StandardEngine {
  container: Element;
  styleElements: {[string]: HTMLStyleElement};
  fontFaceSheet: HTMLStyleElement;
  keyframesSheet: HTMLStyleElement;

  styleCache: MultiCache<{pseudo: string, block: string}>;
  keyframesCache: Cache<keyframesT>;
  fontFaceCache: Cache<fontFaceT>;

  constructor(opts?: optionsT = {}) {
    this.styleElements = {};

    const styleIdGenerator = new SequentialIDGenerator(opts.prefix);
    const onNewStyle = (cache, id, value) => {
      const {pseudo, block} = value;
      const sheet: CSSStyleSheet = (this.styleElements[cache.key].sheet: any);
      sheet.insertRule(
        styleBlockToRule(atomicSelector(id, pseudo), block),
        sheet.cssRules.length,
      );
    };

    // Setup style cache
    this.styleCache = new MultiCache(
      styleIdGenerator,
      media => {
        const styleElement = document.createElement("style");
        styleElement.media = media;
        this.container.appendChild(styleElement);
        this.styleElements[media] = styleElement;
      },
      onNewStyle,
    );

    this.keyframesCache = new Cache(
      new SequentialIDGenerator(opts.prefix),
      (cache, id, value) => {
        this.styleCache.getCache("");
        const sheet: CSSStyleSheet = (this.styleElements[""].sheet: any);
        sheet.insertRule(
          keyframesBlockToRule(id, keyframesToBlock(value)),
          sheet.cssRules.length,
        );
      },
    );

    this.fontFaceCache = new Cache(
      new SequentialIDGenerator(opts.prefix),
      (cache, id, value) => {
        this.styleCache.getCache("");
        const sheet: CSSStyleSheet = (this.styleElements[""].sheet: any);
        sheet.insertRule(
          fontFaceBlockToRule(id, declarationsToBlock(value)),
          sheet.cssRules.length,
        );
      },
    );

    if (opts.container) {
      this.container = opts.container;
    }

    // Hydrate
    if (opts.hydrate && opts.hydrate.length > 0) {
      // infer container from parent element
      if (!this.container) {
        const parentElement = opts.hydrate[0].parentElement;
        if (parentElement !== null && parentElement !== void 0) {
          this.container = parentElement;
        }
      }

      for (let i = 0; i < opts.hydrate.length; i++) {
        const element = opts.hydrate[i];
        const hydrateType = element.dataset.hydrate;
        if (hydrateType === "font-face") {
          hydrate(this.fontFaceCache, FONT_FACE_HYDRATOR, element.textContent);
          continue;
        }
        if (hydrateType === "keyframes") {
          hydrate(this.keyframesCache, KEYFRAMES_HYRDATOR, element.textContent);
          continue;
        }
        const key = element.media ? element.media : "";
        this.styleElements[key] = element;
        const cache = new Cache(styleIdGenerator, onNewStyle);
        cache.key = key;
        hydrateStyles(cache, STYLES_HYDRATOR, element.textContent);
        this.styleCache.caches[key] = cache;
      }
    }

    if (!this.container) {
      if (document.head === null) {
        throw new Error("No container provided and `document.head` was null");
      }
      this.container = document.head;
    }
  }

  renderStyle(style: baseStyleT): string {
    return injectStylePrefixed(this.styleCache, style, "", "");
  }

  renderFontFace(fontFace: fontFaceT): string {
    const key = declarationsToBlock(fontFace);
    return this.fontFaceCache.addValue(key, fontFace);
  }

  renderKeyframes(keyframes: keyframesT): string {
    const key = keyframesToBlock(keyframes);
    return this.keyframesCache.addValue(key, keyframes);
  }
}

export default StyletronClient;
<|endoftext|>


<commit_before>exports.version=1440565677
<commit_msg>update version<commit_after>exports.version=1440808866
<|endoftext|>


<commit_before>/* eslint-disable func-names, comma-dangle, new-cap, no-new, max-len */
/* global ResolveCount */

import $ from 'jquery';
import Vue from 'vue';
import './models/discussion';
import './models/note';
import './stores/comments';
import './services/resolve';
import './mixins/discussion';
import './components/comment_resolve_btn';
import './components/jump_to_discussion';
import './components/resolve_btn';
import './components/resolve_count';
import './components/resolve_discussion_btn';
import './components/diff_note_avatars';
import './components/new_issue_for_discussion';
import { hasVueMRDiscussionsCookie } from '../lib/utils/common_utils';

export default () => {
  const projectPathHolder = document.querySelector('.merge-request') || document.querySelector('.commit-box');
  const projectPath = projectPathHolder.dataset.projectPath;
  const COMPONENT_SELECTOR = 'resolve-btn, resolve-discussion-btn, jump-to-discussion, comment-and-resolve-btn, new-issue-for-discussion-btn';

  window.gl = window.gl || {};
  window.gl.diffNoteApps = {};

  window.ResolveService = new gl.DiffNotesResolveServiceClass(projectPath);

  gl.diffNotesCompileComponents = () => {
    $('diff-note-avatars').each(function () {
      const tmp = Vue.extend({
        template: $(this).get(0).outerHTML
      });
      const tmpApp = new tmp().$mount();

      $(this).replaceWith(tmpApp.$el);
      $(tmpApp.$el).one('remove.vue', () => {
        tmpApp.$destroy();
        tmpApp.$el.remove();
      });
    });

    const $components = $(COMPONENT_SELECTOR).filter(function () {
      return $(this).closest('resolve-count').length !== 1;
    });

    if ($components) {
      $components.each(function () {
        const $this = $(this);
        const noteId = $this.attr(':note-id');
        const discussionId = $this.attr(':discussion-id');

        if ($this.is('comment-and-resolve-btn') && !discussionId) return;

        const tmp = Vue.extend({
          template: $this.get(0).outerHTML
        });
        const tmpApp = new tmp().$mount();

        if (noteId) {
          gl.diffNoteApps[`note_${noteId}`] = tmpApp;
        }

        $this.replaceWith(tmpApp.$el);
      });
    }
  };

  gl.diffNotesCompileComponents();

  const resolveCountAppEl = document.querySelector('#resolve-count-app');
  if (!hasVueMRDiscussionsCookie() && resolveCountAppEl) {
    new Vue({
      el: resolveCountAppEl,
      components: {
        'resolve-count': ResolveCount
      },
    });
  }

  $(window).trigger('resize.nav');
};
<commit_msg>Revert diff notes bundle change<commit_after>/* eslint-disable func-names, comma-dangle, new-cap, no-new, max-len */
/* global ResolveCount */

import $ from 'jquery';
import Vue from 'vue';
import './models/discussion';
import './models/note';
import './stores/comments';
import './services/resolve';
import './mixins/discussion';
import './components/comment_resolve_btn';
import './components/jump_to_discussion';
import './components/resolve_btn';
import './components/resolve_count';
import './components/resolve_discussion_btn';
import './components/diff_note_avatars';
import './components/new_issue_for_discussion';
import { hasVueMRDiscussionsCookie } from '../lib/utils/common_utils';

export default () => {
  const projectPathHolder = document.querySelector('.merge-request') || document.querySelector('.commit-box');
  const projectPath = projectPathHolder.dataset.projectPath;
  const COMPONENT_SELECTOR = 'resolve-btn, resolve-discussion-btn, jump-to-discussion, comment-and-resolve-btn, new-issue-for-discussion-btn';

  window.gl = window.gl || {};
  window.gl.diffNoteApps = {};

  window.ResolveService = new gl.DiffNotesResolveServiceClass(projectPath);

  gl.diffNotesCompileComponents = () => {
    $('diff-note-avatars').each(function () {
      const tmp = Vue.extend({
        template: $(this).get(0).outerHTML
      });
      const tmpApp = new tmp().$mount();

      $(this).replaceWith(tmpApp.$el);
      $(tmpApp.$el).one('remove.vue', () => {
        tmpApp.$destroy();
        tmpApp.$el.remove();
      });
    });

    const $components = $(COMPONENT_SELECTOR).filter(function () {
      return $(this).closest('resolve-count').length !== 1;
    });

    if ($components) {
      $components.each(function () {
        const $this = $(this);
        const noteId = $this.attr(':note-id');
        const discussionId = $this.attr(':discussion-id');

        if ($this.is('comment-and-resolve-btn') && !discussionId) return;

        const tmp = Vue.extend({
          template: $this.get(0).outerHTML
        });
        const tmpApp = new tmp().$mount();

        if (noteId) {
          gl.diffNoteApps[`note_${noteId}`] = tmpApp;
        }

        $this.replaceWith(tmpApp.$el);
      });
    }
  };

  gl.diffNotesCompileComponents();

  if (!hasVueMRDiscussionsCookie()) {
    new Vue({
      el: '#resolve-count-app',
      components: {
        'resolve-count': ResolveCount
      },
    });
  }

  $(window).trigger('resize.nav');
};
<|endoftext|>


<commit_before>OFFSET = 0;

function getLocation(callback) {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(callback);
    } else {
        callback(false);
    }
}

function calculateOffset(position) {
    var fraction = position.coords.longitude / 180.0;
    // milliseconds * seconds * minutes * hours
    var multiplicand = 1000 * 60 * 60 * 12;
    var milliseconds = fraction * multiplicand;
    return milliseconds;
}

function pad(n) {
    return (n < 10) ? ("0" + n) : n;
}

function formatDate(date) {
    return pad(date.getUTCHours()) + ':' + pad(date.getUTCMinutes()) + ':' + pad(date.getUTCSeconds());
}

function formatDelta(ms) {
    var date = new Date(ms);
    return formatDate(date);
}

function displayOffset(position) {
    var milliseconds = calculateOffset(position);
    OFFSET = milliseconds;
    var message;
    if (milliseconds > 0.0) {
        message = formatDelta(milliseconds) + ' ahead of UTC';
    }
    else if (milliseconds < 0.0) {
        message = formatDelta(milliseconds) + ' behind UTC';
    }
    else {
        message = ' even with UTC';
    }
    element = document.getElementById('localoffset');
    element.innerText = message;
}

function startTime() {
    var today=Date.now();
    today += OFFSET;
    today = new Date(today);
    document.getElementById('localtime').innerHTML = formatDate(today);
    var t = setTimeout(function(){startTime()},500);
}

getLocation(displayOffset);
<commit_msg>Use absolute value when creating pretty time display to avoid 23:59:59 or similar showing for negative offsets<commit_after>OFFSET = 0;

function getLocation(callback) {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(callback);
    } else {
        callback(false);
    }
}

function calculateOffset(position) {
    var fraction = position.coords.longitude / 180.0;
    // milliseconds * seconds * minutes * hours
    var multiplicand = 1000 * 60 * 60 * 12;
    var milliseconds = fraction * multiplicand;
    return milliseconds;
}

function pad(n) {
    return (n < 10) ? ("0" + n) : n;
}

function formatDate(date) {
    return pad(date.getUTCHours()) + ':' + pad(date.getUTCMinutes()) + ':' + pad(date.getUTCSeconds());
}

function formatDelta(ms) {
    var date = new Date(Math.abs(ms));
    return formatDate(date);
}

function displayOffset(position) {
    var milliseconds = calculateOffset(position);
    OFFSET = milliseconds;
    var message;
    if (milliseconds > 0.0) {
        message = formatDelta(milliseconds) + ' ahead of UTC';
    }
    else if (milliseconds < 0.0) {
        message = formatDelta(milliseconds) + ' behind UTC';
    }
    else {
        message = ' even with UTC';
    }
    element = document.getElementById('localoffset');
    element.innerText = message;
}

function startTime() {
    var today=Date.now();
    today += OFFSET;
    today = new Date(today);
    document.getElementById('localtime').innerHTML = formatDate(today);
    var t = setTimeout(function(){startTime()},500);
}

getLocation(displayOffset);
<|endoftext|>


<commit_before>import {cube}          from './primitiveShapes/cube';
import {gridPlane}     from './primitiveShapes/gridPlane';
import {lineStrip}     from './primitiveShapes/lineStrip';
import {line}          from './primitiveShapes/line';
import {plane}         from './primitiveShapes/plane';
import {point}         from './primitiveShapes/point';
import {polygon}       from './primitiveShapes/polygon';
import {triangle}      from './primitiveShapes/triangle';

import {drawLineStrip} from './draw/drawLineStrip';
import {drawPlane}     from './draw/drawPlane';
import {drawPolygon}   from './draw/drawPolygon';
import {drawTriangle}  from './draw/drawTriangle';

import {orthographic}  from './projection-orthographic';

import {x as px, y as py, z as pz } from './point';

/**
* @author Stefan Nieke / http://niekes.com/
*/

export default function() {

    var origin          = [0, 0],
        scale           = 1,
        projection      = orthographic,
        angleX          = 0,
        angleY          = 0,
        angleZ          = 0,
        rotateCenter    = [0,0,0],
        x               = px,
        y               = py,
        z               = pz,
        row             = undefined,
        shape           = 'POINT',
        processData = {
            'CUBE'       : cube,
            'GRID'       : gridPlane,
            'LINE'       : line,
            'LINE_STRIP' : lineStrip,
            'PLANE'      : plane,
            'POINT'      : point,
            'POLYGON'    : polygon,
            'SURFACE'    : gridPlane,
            'TRIANGLE'   : triangle,
        },
        draw = {
            'CUBE'       : drawPlane,
            'GRID'       : drawPlane,
            'LINE_STRIP' : drawLineStrip,
            'PLANE'      : drawPlane,
            'POLYGON'    : drawPolygon,
            'TRIANGLE'   : drawTriangle,
        };

    function _3d(data){
        return processData[shape](
            data,
            { scale: scale, origin: origin, project: projection, row: row },
            { x: x, y: y, z: z },
            { x: angleX, y: angleY, z: angleZ, rotateCenter: rotateCenter }
        );
    }

    _3d.origin = function(_){
        return arguments.length ? (origin = _, _3d) : origin;
    };

    _3d.scale = function(_){
        return arguments.length ? (scale = _, _3d) : scale;
    };

    _3d.rotateX = function(_){
        return arguments.length ? (angleX = _, _3d) : angleX;
    };

    _3d.rotateY = function(_){
        return arguments.length ? (angleY = _, _3d) : angleY;
    };

    _3d.rotateZ = function(_){
        return arguments.length ? (angleZ = _, _3d) : angleZ;
    };

    _3d.shape = function(_, r){
        return arguments.length ? (shape = _, row = r, _3d) : shape;
    };

    _3d.rotateCenter = function(_){
        return arguments.length ? (rotateCenter = _, _3d) : rotateCenter;
    };

    _3d.x = function(_){
        return arguments.length ? (x = typeof _ === 'function' ? _ : +_, _3d) : x;
    };

    _3d.y = function(_){
        return arguments.length ? (y = typeof _ === 'function' ? _ : +_, _3d) : y;
    };

    _3d.z = function(_){
        return arguments.length ? (z = typeof _ === 'function' ? _ : +_, _3d) : z;
    };

    _3d.sort = function(a, b){
        var _a = a.centroid.z, _b = b.centroid.z;
        return _a < _b ? -1 : _a > _b ? 1 : _a >= _b ? 0 : NaN;
    };

    _3d.draw = function(d){
        if(!((shape === 'POINT') || (shape === 'LINE'))){
            return draw[shape](d);
        }
    };

    return _3d;
}
<commit_msg>add draw method for `surface`<commit_after>import {cube}          from './primitiveShapes/cube';
import {gridPlane}     from './primitiveShapes/gridPlane';
import {lineStrip}     from './primitiveShapes/lineStrip';
import {line}          from './primitiveShapes/line';
import {plane}         from './primitiveShapes/plane';
import {point}         from './primitiveShapes/point';
import {polygon}       from './primitiveShapes/polygon';
import {triangle}      from './primitiveShapes/triangle';

import {drawLineStrip} from './draw/drawLineStrip';
import {drawPlane}     from './draw/drawPlane';
import {drawPolygon}   from './draw/drawPolygon';
import {drawTriangle}  from './draw/drawTriangle';

import {orthographic}  from './projection-orthographic';

import {x as px, y as py, z as pz } from './point';

/**
* @author Stefan Nieke / http://niekes.com/
*/

export default function() {

    var origin          = [0, 0],
        scale           = 1,
        projection      = orthographic,
        angleX          = 0,
        angleY          = 0,
        angleZ          = 0,
        rotateCenter    = [0,0,0],
        x               = px,
        y               = py,
        z               = pz,
        row             = undefined,
        shape           = 'POINT',
        processData = {
            'CUBE'       : cube,
            'GRID'       : gridPlane,
            'LINE'       : line,
            'LINE_STRIP' : lineStrip,
            'PLANE'      : plane,
            'POINT'      : point,
            'POLYGON'    : polygon,
            'SURFACE'    : gridPlane,
            'TRIANGLE'   : triangle,
        },
        draw = {
            'CUBE'       : drawPlane,
            'GRID'       : drawPlane,
            'LINE_STRIP' : drawLineStrip,
            'PLANE'      : drawPlane,
            'POLYGON'    : drawPolygon,
            'SURFACE'    : drawPlane,
            'TRIANGLE'   : drawTriangle,
        };

    function _3d(data){
        return processData[shape](
            data,
            { scale: scale, origin: origin, project: projection, row: row },
            { x: x, y: y, z: z },
            { x: angleX, y: angleY, z: angleZ, rotateCenter: rotateCenter }
        );
    }

    _3d.origin = function(_){
        return arguments.length ? (origin = _, _3d) : origin;
    };

    _3d.scale = function(_){
        return arguments.length ? (scale = _, _3d) : scale;
    };

    _3d.rotateX = function(_){
        return arguments.length ? (angleX = _, _3d) : angleX;
    };

    _3d.rotateY = function(_){
        return arguments.length ? (angleY = _, _3d) : angleY;
    };

    _3d.rotateZ = function(_){
        return arguments.length ? (angleZ = _, _3d) : angleZ;
    };

    _3d.shape = function(_, r){
        return arguments.length ? (shape = _, row = r, _3d) : shape;
    };

    _3d.rotateCenter = function(_){
        return arguments.length ? (rotateCenter = _, _3d) : rotateCenter;
    };

    _3d.x = function(_){
        return arguments.length ? (x = typeof _ === 'function' ? _ : +_, _3d) : x;
    };

    _3d.y = function(_){
        return arguments.length ? (y = typeof _ === 'function' ? _ : +_, _3d) : y;
    };

    _3d.z = function(_){
        return arguments.length ? (z = typeof _ === 'function' ? _ : +_, _3d) : z;
    };

    _3d.sort = function(a, b){
        var _a = a.centroid.z, _b = b.centroid.z;
        return _a < _b ? -1 : _a > _b ? 1 : _a >= _b ? 0 : NaN;
    };

    _3d.draw = function(d){
        if(!((shape === 'POINT') || (shape === 'LINE'))){
            return draw[shape](d);
        }
    };

    return _3d;
}
<|endoftext|>


<commit_before>var express = require('express');
var url = require('url');
var app = express();

app.use(function(req,res,next){
  var urlObj = url.parse(req.url);
  req.path1 = urlObj.pathname;
  req.query1 = urlObj.query;
  var host = req.headers['host'].split(':');
  req.hostname1 = host[0];
  req.port1 = host[1];
    next();
});
//获取 请求中的参数
app.get('/',function(req,res){
   console.log(req.method);//请求的方法
   console.log(req.path1);//请求的路径
   console.log(req.hostname1);//请求主机名
    console.log(req.port1);//请求端口号
    console.log(req.query1);//请求的查询字符转成的对象
    res.end('hello');
});

app.listen(9090);<commit_msg>页签 切换效果<commit_after>var express = require('express');
var url = require('url');
var util = require('util');
var app = express();

app.use(function(req,res,next){
  var urlObj = url.parse(req.url);
  req.path1 = urlObj.pathname;
  req.query1 = urlObj.query;
  var host = req.headers['host'].split(':');
  req.hostname1 = host[0];
  req.port1 = host[1];
    next();
});
//获取 请求中的参数
app.get('/',function(req,res){
   console.log(req.method);//请求的方法
   console.log(req.path1);//请求的路径
   console.log(req.hostname1);//请求主机名
    console.log(req.port1);//请求端口号
    console.log(req.query1);//请求的查询字符转成的对象
    res.end('hello');
});
//路径参数
app.get('/users/:id/:name',function(req,res){
    //req.params = {id:undefined,name:undefined}
    console.log(req.params.id,req.params.name);
    res.end(req.params.id+req.params.name);
});
app.use(function(req,res,next){
    res.send = function(body){
       var type = typeof body;
        if(type == 'object'){
            res.setHeader('Content-Type','text/html');
            res.end(util.inspect(body));
        }else if (type == 'number'){
            res.end(""+body);
        }
    }
});
app.get('/date',function(req,res){
    //res.send(new Date());
    //res.send([{id:1},{id:2}]);
    //res.send({"id":2});
    //res.send(200);
    //res.sendStatus(200);//如果返回响应码的时候必须用
});
app.listen(9090);<|endoftext|>


<commit_before>import {points}         from './primitiveTypes/points.js';
import {lines}          from './primitiveTypes/lines.js';
import {linesLoop}      from './primitiveTypes/linesLoop.js';
import {linesStrip}     from './primitiveTypes/linesStrip.js';
import {triangles}      from './primitiveTypes/triangles.js';
import {trianglesStrip} from './primitiveTypes/trianglesStrip.js';
import {trianglesFan}   from './primitiveTypes/trianglesFan.js';
import {drawTriangles}  from './draw/drawTriangles.js';

export default function() {

    var origin          = [0, 0],
        scale           = 1,
        distance        = 1,
        angleX          = 0,
        angleY          = 0,
        angleZ          = 0,
        primitiveType   = 'POINTS',
        processData = {
            POINTS          : points,
            LINES           : lines,
            LINES_LOOP      : linesLoop,
            LINES_STRIP     : linesStrip,
            TRIANGLES       : triangles,
            TRIANGLES_STRIP : trianglesStrip,
            TRIANGLES_FAN   : trianglesFan
        },
        draw = {
            TRIANGLES   : drawTriangles
        };

    function _3d(data){
        return processData[primitiveType](data, angleX, angleY, angleZ, origin, scale, distance);
    }

    _3d.origin = function(_){
        return arguments.length ? (origin = _, _3d) : origin;
    };

    _3d.scale = function(_){
        return arguments.length ? (scale = _, _3d) : scale;
    };

    _3d.distance = function(_){
        return arguments.length ? (distance = _, _3d) : distance;
    };

    _3d.rotateX = function(_){
        return arguments.length ? (angleX = _, _3d) : angleX;
    };

    _3d.rotateY = function(_){
        return arguments.length ? (angleY = _, _3d) : angleY;
    };

    _3d.rotateZ = function(_){
        return arguments.length ? (angleZ = _, _3d) : angleZ;
    };

    _3d.primitiveType = function(_){
        return arguments.length ? (primitiveType = _, _3d) : primitiveType;
    };

    _3d.draw = function(d){
        if(primitiveType !== 'POINTS' || primitiveType !== 'LINES'){
            return draw[primitiveType](d);
        }
    };

    return _3d;
}
<commit_msg>add author<commit_after>import {points}         from './primitiveTypes/points.js';
import {lines}          from './primitiveTypes/lines.js';
import {linesLoop}      from './primitiveTypes/linesLoop.js';
import {linesStrip}     from './primitiveTypes/linesStrip.js';
import {triangles}      from './primitiveTypes/triangles.js';
import {trianglesStrip} from './primitiveTypes/trianglesStrip.js';
import {trianglesFan}   from './primitiveTypes/trianglesFan.js';
import {drawTriangles}  from './draw/drawTriangles.js';

/**
 * @author niekes / http://niekes.com/
 */

export default function() {

    var origin          = [0, 0],
        scale           = 1,
        distance        = 1,
        angleX          = 0,
        angleY          = 0,
        angleZ          = 0,
        primitiveType   = 'POINTS',
        processData = {
            POINTS          : points,
            LINES           : lines,
            LINES_LOOP      : linesLoop,
            LINES_STRIP     : linesStrip,
            TRIANGLES       : triangles,
            TRIANGLES_STRIP : trianglesStrip,
            TRIANGLES_FAN   : trianglesFan
        },
        draw = {
            TRIANGLES   : drawTriangles
        };

    function _3d(data){
        return processData[primitiveType](data, angleX, angleY, angleZ, origin, scale, distance);
    }

    _3d.origin = function(_){
        return arguments.length ? (origin = _, _3d) : origin;
    };

    _3d.scale = function(_){
        return arguments.length ? (scale = _, _3d) : scale;
    };

    _3d.distance = function(_){
        return arguments.length ? (distance = _, _3d) : distance;
    };

    _3d.rotateX = function(_){
        return arguments.length ? (angleX = _, _3d) : angleX;
    };

    _3d.rotateY = function(_){
        return arguments.length ? (angleY = _, _3d) : angleY;
    };

    _3d.rotateZ = function(_){
        return arguments.length ? (angleZ = _, _3d) : angleZ;
    };

    _3d.primitiveType = function(_){
        return arguments.length ? (primitiveType = _, _3d) : primitiveType;
    };

    _3d.draw = function(d){
        if(primitiveType !== 'POINTS' || primitiveType !== 'LINES'){
            return draw[primitiveType](d);
        }
    };

    return _3d;
}
<|endoftext|>


<commit_before>// Enemy info
var level1Life = [10, 20];
var level1Damage = [5, 15]; // the damage for all enemies
var level1Speed = [1, 1.5]; // the speed for all enemies

// Spawning info
var level1Enemies = [1, 1, 2, 2]; // the sequence of enemies to be generated
var level1Times = [5, 3, 1]; // the sequence of times in seconds in between each enemy generation. The first number determines how long a wait there is before the first enemy is spawned.

var controller = new Object(); // an object to control all global game vars
controller.health = 100;
controller.currency = 0;
controller.wave = 1;

var num = 0; // The enemy in the sequence we have just created, starting with the first.

function makeEnemy(type, level) {
  //future enemy object
  $('#lv1bgimg').append('
');
  level1Path(num);

}

function level1Path(num) {
  $('.enemy').each(function() {
    if ($(this).attr('data-num') == num) {
      $(this).animate({'left': '500'}, 2500 / $(this).attr('data-speed'), 'linear', function() {
        $(this).animate({'top': '200'}, 1500 / $(this).attr('data-speed'), 'linear', function() {
          $(this).animate({'top': '0', 'left': '0'}, 2690 / $(this).attr('data-speed'), 'linear', function() {

            controller.health -= $(this).attr('data-damage');
            $('#health').html(controller.health);

            $(this).remove();

          });
        });
      });
    }
  });
}

function level1() {
  makeEnemy(level1Enemies[num], 1);

  var creationTimer = setInterval(function() {
    num += 1;
    makeEnemy(level1Enemies[num], 1);
    if (num > level1Times.length) {
      clearInterval(creationTimer);
    }
  }, level1Times[num]*1000);

}

function main() {
  level1();
}
<commit_msg>Final Pathing 2.0 Commit<commit_after>// Enemy info
var level1Life = [10, 20];
var level1Damage = [5, 15]; // the damage for all enemies
var level1Speed = [1, 1.5]; // the speed for all enemies

// Spawning info
var level1Enemies = [1, 1, 2, 2]; // the sequence of enemies to be generated
var level1Times = [5, 3, 1, 1]; // the sequence of times in seconds in between each enemy generation. The first number determines how long a wait there is before the first enemy is spawned.

var controller = new Object(); // an object to control all global game vars
controller.health = 100;
controller.currency = 0;
controller.wave = 1;

var num = 0; // The enemy in the sequence we have just created, starting with the first.

function makeEnemy(type, level) {
  //future enemy object
  $('#lv1bgimg').append('
');
  level1Path(num);

}

function level1Path(num) {
  $('.enemy').each(function() {
    if ($(this).attr('data-num') == num) {
      $(this).animate({'left': '500'}, 2500 / $(this).attr('data-speed'), 'linear', function() {
        $(this).animate({'top': '200'}, 1500 / $(this).attr('data-speed'), 'linear', function() {
          $(this).animate({'top': '0', 'left': '0'}, 2690 / $(this).attr('data-speed'), 'linear', function() {

            controller.health -= $(this).attr('data-damage');
            $('#health').html(controller.health);

            $(this).remove();

          });
        });
      });
    }
  });
}

function level1() {
  makeEnemy(level1Enemies[num], 1);

  var creationTimer = setInterval(function() {
    num += 1;
    makeEnemy(level1Enemies[num], 1);
    if (num > level1Times.length) {
      clearInterval(creationTimer);
    }
  }, level1Times[num]*1000);

}

function main() {
  level1();
}
<|endoftext|>