<commit_before>$(function() {
        $.ajax({
                url: 'ajax.php',
		    type: 'post',
		    data: {get_nav: 1},
		    success: function(txt) {
		    var html = "
" + txt + "
";
		    $("#nav").html(html);
		}
	    });
    });

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

function doAssignmentAjax(action, title, errText,
			  edah, block) {
    var values = {};
    values[action] = 1;
    values["edah"] = edah;
    values["block"] = block;
    	$.ajax({
                url: 'levelingAjax.php',
                    type: 'post',
                    data: values,
                    success: function(data) {
		    if (action == "reassign") {
			// Fade and then reload with new data (for multiple clicks).
			$( "#results:visible" ).removeAttr( "style" ).fadeOut();
		    }
		    $( "#results" ).html(function() {
				    txt = "
" + title + "
";
				    txt += "
";
				    txt += "
Chugim under min: ";
				    txt += data.under_min_list;
				    txt += "
";
				    txt += "
Chugim over max: ";
				    txt += data.over_max_list;
				    txt += "
";
				    txt += "
Assignment Stats:
";
				    txt += data.statstxt;
				    txt += "

";
				    return txt;
			});
		    $( "#results" ).show("slide", 500);
		    $( "#results" ).attr('disabled', false);
		},
		    error: function(xhr, desc, err) {
		    errMsg = "The system was unable to ";
		    errMsg += errText;
		    errMsg += ". If the problem persists, please contact the administrator.  Error: ";
		    errMsg += err + " " + desc;
		    $( "#results" ).text(errMsg);
		    $( "#results" ).show("slide", 250 );
		}
	    });
}

// Get the current match and chug info for this edah/block, and display it by group.
// Also, display chugim with no matches, because the user needs the ability to drag
// to them.
function getAndDisplayCurrentMatches() {
        var curUrl = window.location.href;
        var curUrlBase = curUrl.substr(0, curUrl.lastIndexOf("/"));
	var editChugBase = curUrlBase + "/editChug.php?eid=";
        var edah = getParameterByName("edah");
        var block = getParameterByName("block");
	var succeeded = false;
	var camperId2Group2PrefList;
	var prefClasses = ["li_first_choice", "li_second_choice", "li_third_choice", "li_fourth_choice"];
	$.ajax({
                url: 'levelingAjax.php',
                    type: 'post',
                    data:{ matches_and_prefs: 1,
			edah_id: edah,
			block_id: block },
                    success: function(json) {
		    succeeded = true;
		    // Display a field for each chug.  The chug fields should be grouped
		    // by group (aleph, bet, gimel).  Each field should contain camper containers,
		    // according to how campers are currently matched.
		    // Camper containers should be labeled with the camper's name, and colored according
		    // to the pref level of the assignment.  They should be draggable between chug fields,
		    // but only within the enclosing group (i.e., when changing the aleph assignment for
		    // a camper, it should be possible to move within aleph choices only).  Also, the tooltip
		    // for the camper boxes should show an ordered list of chugim, top to bottom.
		    // "This, I know from nothing!" - N. Lobachevsky.
		    var html = "";
		    var groupId2Name = json["groupId2Name"];
		    var groupId2ChugId2MatchedCampers = json["groupId2ChugId2MatchedCampers"];
		    camperId2Group2PrefList = json["camperId2Group2PrefList"];
		    var chugId2Beta = json["chugId2Beta"];
		    var camperId2Name = json["camperId2Name"];
		    $.each(groupId2ChugId2MatchedCampers,
			   function(groupId, chugId2MatchedCampers) {
			       // Add a holder for each group (aleph, bet, gimel).
			       var groupName = groupId2Name[groupId];
			       html += "
\n";
			       html += "
" + groupName + " assignments
\n";
			       // Within each group, add a holder for campers, and then populate with
			       // campers.
			       $.each(chugId2MatchedCampers,
				      function(chugId, matchedCampers) {
					  // Add a chug holder, and put camper holders inside it.
					  var chugName = chugId2Beta[chugId]["name"];
					  var chugMin = chugId2Beta[chugId]["min_size"];
					  var chugMax = chugId2Beta[chugId]["max_size"];
					  var editChugUrl = editChugBase + chugId;
					  if (chugMax == "0" ||
					      chugMax == "10000") {
					      chugMax = "no limit";
					  }
					  html += "
\n";
					  if (chugName == "Not Assigned Yet") {
					      html += "
" + chugName + "
";
					  } else {
					      html += "
" + "" + chugName + ""
						  + " (min = " + chugMin + ", max = " + chugMax + ")
";
					  }
					  html += "
";
					  $.each(matchedCampers,
						 function(index, camperId) {
						     var camperName = camperId2Name[camperId];
						     var prefListText = "";
						     var prefClass = prefClasses[prefClasses.length - 1];
						     if (camperId in camperId2Group2PrefList) {
							 var group2PrefList = camperId2Group2PrefList[camperId];
							 if (groupId in group2PrefList) {
							     var prefList = group2PrefList[groupId];
							     $.each(prefList, function(index, prefChugId) {
								     var listNum = index + 1;
								     if (prefListText == "") {
									 prefListText += "Preferences:\n";
								     }
								     if (prefChugId in chugId2Beta) {
									 prefListText += listNum + ". " + chugId2Beta[prefChugId]["name"] + "\n";
								     }
								     if (prefChugId == chugId) {
									 if (index < prefClasses.length) {
									     prefClass = prefClasses[index];
									 } else {
									     prefClass = prefClasses[prefClasses.length - 1];
									 }
								     }
								 });
							 }
						     }
						     var titleText = "title=\"<no preferences>\"";
						     if (prefListText) {
							 // If we have a pref list, write it as a tool tip.
							 titleText = "title=\"" + prefListText + "\"";
						     }
						     html += "

" + camperName + "

\n";
						 });
					  html += "

\n";
				      });
			   html += "
\n";
			   });
		    $("#fillmatches").html(html);
                },
                    error: function(xhr, desc, err) {
		    console.log(xhr);
		    console.log("Details: " + desc + "\nError:" + err);
                }
            }).then(function(){
                    if (succeeded) {
			$("ul.gallery li").draggable({
				scroll: false,
				    revert: "invalid", // when not dropped, the item will revert back
				    cursor: "move"
				    });
			$('ul.gallery li').each(function(){
				var $el = $(this);
				$el.draggable({containment:$el.closest('.groupholder')});
			    });
			// Let chug holders be droppable.  When a camper holder is dragged, move from
			// old chug to new, and update the preference color.
			$('.chugholder').each(function(){
				var $el = $(this);
				$el.droppable({accept: "ul.gallery li",
					    activeClass: "ui-state-active",
					    hoverClass: "ui-state-hover",
					    drop: function(event, ui) {
					    var droppedOn = $(this).find(".gallery").addBack(".gallery");
					    var droppedChugId = $(droppedOn).parent().attr("name");
					    var dropped = ui.draggable;
					    //$(dropped).addClass("ui-state-highlight");
					    // Change the color of the dropped item according to the camper's
					    // preference for the dropped-on chug.
					    var camperId = $(dropped).attr("value");
					    var groupId = $(this).parent().attr("name");
					    var prefClass = prefClasses[prefClasses.length - 1];
					    if (camperId in camperId2Group2PrefList) {
						var group2PrefList = camperId2Group2PrefList[camperId];
						if (groupId in group2PrefList) {
						    var prefList = group2PrefList[groupId];
						    $.each(prefList, function(index, prefChugId) {
							    if (prefChugId == droppedChugId) {
								var idx = (index < prefClasses.length) ? index : prefClasses.length - 1;
								prefClass = prefClasses[idx];
								return false; // break
							    }
							});
						}
					    }
					    if (prefClass) {
						$.each(prefClasses, function(index, prefClassToRemove) {
							// Remove old color class.
							$(dropped).removeClass(prefClassToRemove);
						    });
						// Add new color class.
						$(dropped).addClass(prefClass);
					    }
					    $(dropped).detach().css({top:0,left:0}).appendTo(droppedOn);
					}
				    });
			    });
		    } // End if succeeded
		});
}

// Get the current assignment stats for this edah/block.
$(function() {
	var edah = getParameterByName("edah");
	var block = getParameterByName("block");
	doAssignmentAjax("get_current_stats", "Current Stats", "fetch current assignment stats",
			 edah, block);
    });

// Get the name for the current edah and block IDs, and fill them.
$(function() {
	var edahId = getParameterByName('edah');
	var blockId = getParameterByName('block');
        $.ajax({
                url: 'levelingAjax.php',
                    type: 'post',
                    data:{ names_for_id: 1,
		           edah_id: edahId,
			   block_id: blockId },
                    success: function(json) {
                    $( ".edahfill" ).text(function() {
                            if (json.edahName &&
                                json.edahName.length > 0) {
                                return $(this).text().replace("EDAH", json.edahName);
                            }
                        });
		    $( ".blockfill" ).text(function() {
                            if (json.blockName &&
                                json.blockName.length > 0) {
                                return $(this).text().replace("BLOCK", json.blockName);
                            }
                        });
                },
                    error: function(xhr, desc, err) {
		    console.log(xhr);
		    console.log("Details: " + desc + "\nError:" + err);
                }
            })
	    });

// Display current matches when the page loads.
$(function() {
	getAndDisplayCurrentMatches();
    });

// Action for the Report button.
$(function() {
        $("#Report").click(function(event) {
                event.preventDefault();
                // Simulate clicking a link, so this page goes in the browser history.
                var baseUrl = window.location.href;
		baseUrl = baseUrl.replace("levelHome.html", "report.php");
		var edah = getParameterByName("edah");
		var block = getParameterByName("block");
		var reportUrl = baseUrl.split("?")[0];
		var reportUrl = reportUrl + "?report_method=1&block_ids%5B%5D=" + block + "&edah_id=" + edah + "&do_report=1&submit=Display";
                window.location.href = reportUrl;
            })
            });

// Action for the Cancel button.
$(function() {
        $("#Cancel").click(function(event) {
                event.preventDefault();
		// Simulate clicking a link, so this page goes in the browser history.
		var curUrl = window.location.href;
		var homeUrl = curUrl.replace("levelHome.html", "staffHome.php");
		// Remove query string before redir.
		var qpos = homeUrl.indexOf("?");
		if (qpos) {
		    homeUrl = homeUrl.substr(0, qpos);
		}
		window.location.href = homeUrl;
	    })
	    });

// Action for the Reassign button.
$(function() {
	var edah = getParameterByName("edah");
	var block = getParameterByName("block");
        $("#Reassign").click(function(event) {
                event.preventDefault();
		var r = confirm("Reassign campers on page? Please click OK to confirm.");
		if (r != true) {
		    return;
		}
		var ajaxAction = function() {
		    var ra = $.Deferred();
		    doAssignmentAjax("reassign", "Assignment saved!", "reassign",
				     edah, block);
		    ra.resolve();
		    return ra;
		};
		var displayAction = function() {
		    getAndDisplayCurrentMatches();
		};
		ajaxAction().done(displayAction);
            });
    });

// Action for the Save button
// Collect the current assignments and send them to the ajax page to be
// saved in the DB.
$(function() {
	var edah = getParameterByName("edah");
	var block = getParameterByName("block");
        $("#Save").click(function(event) {
                event.preventDefault();
		var r = confirm("Save changes? Please click OK to confirm.");
		if (r != true) {
		    return;
		}
		// Loop through the groups, and then loop through the
		// chugim within each group.
		var assignments = new Object(); // Associative array
                var groupDivs = $(document).find(".groupholder");
                for (var i = 0; i < groupDivs.length; i++) {
                    var groupElement = groupDivs[i];
		    var groupId = groupElement.getAttribute("name");
		    var chugDivs = $(groupElement).find(".chugholder");
		    assignments[groupId] = new Object();// Associative array
                    for (var j = 0; j < chugDivs.length; j++) {
			var chugDiv = chugDivs[j];
			var chugId = chugDiv.getAttribute("name");
			var ulElement = $(chugDiv).find("ul");
			var camperElements = $(ulElement).find("li");
			assignments[groupId][chugId] = [];
			for (var k = 0; k < camperElements.length; k++) {
			    var camperElement = camperElements[k];
			    var camperId = camperElement.getAttribute("value");
			    assignments[groupId][chugId].push(camperId);
			}
		    }
		}
		var values = {};
		values["save_changes"] = 1;
		values["assignments"] = assignments;
		values["edah"] = edah;
		values["block"] = block;
		$.ajax({
			url: 'levelingAjax.php',
			    type: 'post',
			    data: values,
			    success: function(json) {
			    doAssignmentAjax("get_current_stats", "Changes Saved! Stats:", "save your changes",
					     edah, block);
			},
			    error: function(xhr, desc, err) {
			    console.log(xhr);
			    console.log("Details: " + desc + "\nError:" + err);
			}
		    });
	    });
    });
<commit_msg>Require asynchronous ajax methods, and use then() to execute functions in the proper order for display.<commit_after>// On page load, grab nav data, then assignments, and then get and display
// current matches.
$(function() {
        $.when(
               getNav()
               ).then(getAssignments).then(getAndDisplayCurrentMatches);
    });

// Get the current assignment stats for this edah/block.
function getAssignments() {
	var edah = getParameterByName("edah");
	var block = getParameterByName("block");
	doAssignmentAjax("get_current_stats", "Current Stats", "fetch current assignment stats",
			 edah, block);
}

function getNav() {
        $.ajax({
                url: 'ajax.php',
		    type: 'post',
		    data: {get_nav: 1},
		    success: function(txt) {
		    var html = "
" + txt + "
";
		    $("#nav").html(html);
		}
	    });
}

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

function doAssignmentAjax(action, title, errText,
			  edah, block) {
    var values = {};
    values[action] = 1;
    values["edah"] = edah;
    values["block"] = block;
    	$.ajax({
                url: 'levelingAjax.php',
		    async: false,
                    type: 'post',
                    data: values,
                    success: function(data) {
		    if (action == "reassign") {
			// Fade and then reload with new data (for multiple clicks).
			$( "#results:visible" ).removeAttr( "style" ).fadeOut();
		    }
		    $( "#results" ).html(function() {
				    txt = "
" + title + "
";
				    txt += "
";
				    txt += "
Chugim under min: ";
				    txt += data.under_min_list;
				    txt += "
";
				    txt += "
Chugim over max: ";
				    txt += data.over_max_list;
				    txt += "
";
				    txt += "
Assignment Stats:
";
				    txt += data.statstxt;
				    txt += "

";
				    return txt;
			});
		    $( "#results" ).show("slide", 500);
		    $( "#results" ).attr('disabled', false);
		},
		    error: function(xhr, desc, err) {
		    errMsg = "The system was unable to ";
		    errMsg += errText;
		    errMsg += ". If the problem persists, please contact the administrator.  Error: ";
		    errMsg += err + " " + desc;
		    $( "#results" ).text(errMsg);
		    $( "#results" ).show("slide", 250 );
		}
	    });
}

// Get the current match and chug info for this edah/block, and display it by group.
// Also, display chugim with no matches, because the user needs the ability to drag
// to them.
function getAndDisplayCurrentMatches() {
        var curUrl = window.location.href;
        var curUrlBase = curUrl.substr(0, curUrl.lastIndexOf("/"));
	var editChugBase = curUrlBase + "/editChug.php?eid=";
        var edah = getParameterByName("edah");
        var block = getParameterByName("block");
	var succeeded = false;
	var camperId2Group2PrefList;
	var prefClasses = ["li_first_choice", "li_second_choice", "li_third_choice", "li_fourth_choice"];
	$.ajax({
                url: 'levelingAjax.php',
                    type: 'post',
		    async: false,
                    data:{ matches_and_prefs: 1,
			edah_id: edah,
			block_id: block },
                    success: function(json) {
		    succeeded = true;
		    // Display a field for each chug.  The chug fields should be grouped
		    // by group (aleph, bet, gimel).  Each field should contain camper containers,
		    // according to how campers are currently matched.
		    // Camper containers should be labeled with the camper's name, and colored according
		    // to the pref level of the assignment.  They should be draggable between chug fields,
		    // but only within the enclosing group (i.e., when changing the aleph assignment for
		    // a camper, it should be possible to move within aleph choices only).  Also, the tooltip
		    // for the camper boxes should show an ordered list of chugim, top to bottom.
		    // "This, I know from nothing!" - N. Lobachevsky.
		    var html = "";
		    var groupId2Name = json["groupId2Name"];
		    var groupId2ChugId2MatchedCampers = json["groupId2ChugId2MatchedCampers"];
		    camperId2Group2PrefList = json["camperId2Group2PrefList"];
		    var chugId2Beta = json["chugId2Beta"];
		    var camperId2Name = json["camperId2Name"];
		    $.each(groupId2ChugId2MatchedCampers,
			   function(groupId, chugId2MatchedCampers) {
			       // Add a holder for each group (aleph, bet, gimel).
			       var groupName = groupId2Name[groupId];
			       html += "
\n";
			       html += "
" + groupName + " assignments
\n";
			       // Within each group, add a holder for campers, and then populate with
			       // campers.
			       $.each(chugId2MatchedCampers,
				      function(chugId, matchedCampers) {
					  // Add a chug holder, and put camper holders inside it.
					  var chugName = chugId2Beta[chugId]["name"];
					  var chugMin = chugId2Beta[chugId]["min_size"];
					  var chugMax = chugId2Beta[chugId]["max_size"];
					  var editChugUrl = editChugBase + chugId;
					  if (chugMax == "0" ||
					      chugMax == "10000") {
					      chugMax = "no limit";
					  }
					  html += "
\n";
					  if (chugName == "Not Assigned Yet") {
					      html += "
" + chugName + "
";
					  } else {
					      html += "
" + "" + chugName + ""
						  + " (min = " + chugMin + ", max = " + chugMax + ")
";
					  }
					  html += "
";
					  $.each(matchedCampers,
						 function(index, camperId) {
						     var camperName = camperId2Name[camperId];
						     var prefListText = "";
						     var prefClass = prefClasses[prefClasses.length - 1];
						     if (camperId in camperId2Group2PrefList) {
							 var group2PrefList = camperId2Group2PrefList[camperId];
							 if (groupId in group2PrefList) {
							     var prefList = group2PrefList[groupId];
							     $.each(prefList, function(index, prefChugId) {
								     var listNum = index + 1;
								     if (prefListText == "") {
									 prefListText += "Preferences:\n";
								     }
								     if (prefChugId in chugId2Beta) {
									 prefListText += listNum + ". " + chugId2Beta[prefChugId]["name"] + "\n";
								     }
								     if (prefChugId == chugId) {
									 if (index < prefClasses.length) {
									     prefClass = prefClasses[index];
									 } else {
									     prefClass = prefClasses[prefClasses.length - 1];
									 }
								     }
								 });
							 }
						     }
						     var titleText = "title=\"<no preferences>\"";
						     if (prefListText) {
							 // If we have a pref list, write it as a tool tip.
							 titleText = "title=\"" + prefListText + "\"";
						     }
						     html += "

" + camperName + "

\n";
						 });
					  html += "

\n";
				      });
			   html += "
\n";
			   });
		    $("#fillmatches").html(html);
                },
                    error: function(xhr, desc, err) {
		    console.log(xhr);
		    console.log("Details: " + desc + "\nError:" + err);
                }
            }).then(function(){
                    if (succeeded) {
			$("ul.gallery li").draggable({
				scroll: false,
				    revert: "invalid", // when not dropped, the item will revert back
				    cursor: "move"
				    });
			$('ul.gallery li').each(function(){
				var $el = $(this);
				$el.draggable({containment:$el.closest('.groupholder')});
			    });
			// Let chug holders be droppable.  When a camper holder is dragged, move from
			// old chug to new, and update the preference color.
			$('.chugholder').each(function(){
				var $el = $(this);
				$el.droppable({accept: "ul.gallery li",
					    activeClass: "ui-state-active",
					    hoverClass: "ui-state-hover",
					    drop: function(event, ui) {
					    var droppedOn = $(this).find(".gallery").addBack(".gallery");
					    var droppedChugId = $(droppedOn).parent().attr("name");
					    var dropped = ui.draggable;
					    //$(dropped).addClass("ui-state-highlight");
					    // Change the color of the dropped item according to the camper's
					    // preference for the dropped-on chug.
					    var camperId = $(dropped).attr("value");
					    var groupId = $(this).parent().attr("name");
					    var prefClass = prefClasses[prefClasses.length - 1];
					    if (camperId in camperId2Group2PrefList) {
						var group2PrefList = camperId2Group2PrefList[camperId];
						if (groupId in group2PrefList) {
						    var prefList = group2PrefList[groupId];
						    $.each(prefList, function(index, prefChugId) {
							    if (prefChugId == droppedChugId) {
								var idx = (index < prefClasses.length) ? index : prefClasses.length - 1;
								prefClass = prefClasses[idx];
								return false; // break
							    }
							});
						}
					    }
					    if (prefClass) {
						$.each(prefClasses, function(index, prefClassToRemove) {
							// Remove old color class.
							$(dropped).removeClass(prefClassToRemove);
						    });
						// Add new color class.
						$(dropped).addClass(prefClass);
					    }
					    $(dropped).detach().css({top:0,left:0}).appendTo(droppedOn);
					}
				    });
			    });
		    } // End if succeeded
		});
}

// Get the name for the current edah and block IDs, and fill them.
$(function() {
	var edahId = getParameterByName('edah');
	var blockId = getParameterByName('block');
        $.ajax({
                url: 'levelingAjax.php',
                    type: 'post',
		    async: false,
                    data:{ names_for_id: 1,
		           edah_id: edahId,
			   block_id: blockId },
                    success: function(json) {
                    $( ".edahfill" ).text(function() {
                            if (json.edahName &&
                                json.edahName.length > 0) {
                                return $(this).text().replace("EDAH", json.edahName);
                            }
                        });
		    $( ".blockfill" ).text(function() {
                            if (json.blockName &&
                                json.blockName.length > 0) {
                                return $(this).text().replace("BLOCK", json.blockName);
                            }
                        });
                },
                    error: function(xhr, desc, err) {
		    console.log(xhr);
		    console.log("Details: " + desc + "\nError:" + err);
                }
            })
	    });

// Action for the Report button.
$(function() {
        $("#Report").click(function(event) {
                event.preventDefault();
                // Simulate clicking a link, so this page goes in the browser history.
                var baseUrl = window.location.href;
		baseUrl = baseUrl.replace("levelHome.html", "report.php");
		var edah = getParameterByName("edah");
		var block = getParameterByName("block");
		var reportUrl = baseUrl.split("?")[0];
		var reportUrl = reportUrl + "?report_method=1&block_ids%5B%5D=" + block + "&edah_id=" + edah + "&do_report=1&submit=Display";
                window.location.href = reportUrl;
            })
            });

// Action for the Cancel button.
$(function() {
        $("#Cancel").click(function(event) {
                event.preventDefault();
		// Simulate clicking a link, so this page goes in the browser history.
		var curUrl = window.location.href;
		var homeUrl = curUrl.replace("levelHome.html", "staffHome.php");
		// Remove query string before redir.
		var qpos = homeUrl.indexOf("?");
		if (qpos) {
		    homeUrl = homeUrl.substr(0, qpos);
		}
		window.location.href = homeUrl;
	    })
	    });

// Action for the Reassign button.
$(function() {
	var edah = getParameterByName("edah");
	var block = getParameterByName("block");
        $("#Reassign").click(function(event) {
                event.preventDefault();
		var r = confirm("Reassign campers on page? Please click OK to confirm.");
		if (r != true) {
		    return;
		}
		var ajaxAction = function() {
		    var ra = $.Deferred();
		    doAssignmentAjax("reassign", "Assignment saved!", "reassign",
				     edah, block);
		    ra.resolve();
		    return ra;
		};
		var displayAction = function() {
		    getAndDisplayCurrentMatches();
		};
		ajaxAction().then(displayAction);
            });
    });

// Action for the Save button
// Collect the current assignments and send them to the ajax page to be
// saved in the DB.
$(function() {
	var edah = getParameterByName("edah");
	var block = getParameterByName("block");
        $("#Save").click(function(event) {
                event.preventDefault();
		var r = confirm("Save changes? Please click OK to confirm.");
		if (r != true) {
		    return;
		}
		// Loop through the groups, and then loop through the
		// chugim within each group.
		var assignments = new Object(); // Associative array
                var groupDivs = $(document).find(".groupholder");
                for (var i = 0; i < groupDivs.length; i++) {
                    var groupElement = groupDivs[i];
		    var groupId = groupElement.getAttribute("name");
		    var chugDivs = $(groupElement).find(".chugholder");
		    assignments[groupId] = new Object();// Associative array
                    for (var j = 0; j < chugDivs.length; j++) {
			var chugDiv = chugDivs[j];
			var chugId = chugDiv.getAttribute("name");
			var ulElement = $(chugDiv).find("ul");
			var camperElements = $(ulElement).find("li");
			assignments[groupId][chugId] = [];
			for (var k = 0; k < camperElements.length; k++) {
			    var camperElement = camperElements[k];
			    var camperId = camperElement.getAttribute("value");
			    assignments[groupId][chugId].push(camperId);
			}
		    }
		}
		var values = {};
		values["save_changes"] = 1;
		values["assignments"] = assignments;
		values["edah"] = edah;
		values["block"] = block;
		$.ajax({
			url: 'levelingAjax.php',
			    type: 'post',
			    async: false,
			    data: values,
			    success: function(json) {
			    doAssignmentAjax("get_current_stats", "Changes Saved! Stats:", "save your changes",
					     edah, block);
			},
			    error: function(xhr, desc, err) {
			    console.log(xhr);
			    console.log("Details: " + desc + "\nError:" + err);
			}
		    });
	    });
    });
<|endoftext|>


<commit_before>var test = require('tap').test,
    traverse = require('..').traverse,
    createGraph = require('ngraph.graph'),
    // complete graph builder
    createCompleteGraph = require('./graphbuilder');

test('get all links', function(t) {
  var nodesCount = 5;
  var graph = createCompleteGraph(nodesCount);
  var expectedLinksCount = graph.getLinksCount();
  var visitedCount = 0;

  traverse(graph)
      .links()
      .forEach(function(link){
        t.ok(link, 'link should be passed as an argument');
        visitedCount += 1;
      });

  t.equal(visitedCount, expectedLinksCount, 'Number of edges is not correct');
  t.end();
});

test('get all links from node', function(t) {
  var nodesCount = 5;
  var graph = createCompleteGraph(nodesCount);
  // it is a complete graph:
  var expectedLinksCount = nodesCount - 1;
  var visitedCount = 0;

  var startNodeId = 0;
  traverse(graph)
      .links()
      .from(startNodeId)
      .forEach(function(link){
        t.ok(link, 'link should be passed as an argument');
        t.equal(link.fromId, startNodeId, 'from node id is not correct');
        visitedCount += 1;
      });

  t.equal(visitedCount, expectedLinksCount, 'Number of edges is not correct');
  t.end();
});

test('get all links to node', function(t) {
  var nodesCount = 5;
  var graph = createCompleteGraph(nodesCount);
  // it is a complete graph:
  var expectedLinksCount = nodesCount - 1;
  var visitedCount = 0;

  var endNodeId = 0;
  traverse(graph)
      .links()
      .to(endNodeId)
      .forEach(function(link){
        t.ok(link, 'link should be passed as an argument');
        t.equal(link.toId, endNodeId, 'end node id is not correct');
        visitedCount += 1;
      });

  t.equal(visitedCount, expectedLinksCount, 'Number of edges is not correct');
  t.end();
});

test('get links form to', function(t) {
  var graph = createGraph();
  graph.addLink(0, 1); graph.addLink(1, 2);
  traverse(graph)
    .links()
    .from(0)
    .to(2)
    .forEach(function(link) {
      t.fail('Graph does not have such link');
    })
  t.end();
});

test('get filtered links from node', function(t) {
  var graph = createGraph();
  graph.addLink(0, 1, 'Lu');
  graph.addLink(1, 2, 'Lu');
  graph.addLink(0, 2, 'Tako');

  var visitedCount = 0;
  traverse(graph)
      .links()
      .from(0)
      .where(function(link) { return link.data === 'Lu'; })
      .forEach(function(link){
        t.ok(link.data, 'link should have associated data with it');
        t.equal(link.data, 'Lu');
        visitedCount += 1;
      });

  t.equal(visitedCount, 1, 'Only one link should be visited');
  t.end();
});

test('get all links filtered', function(t) {
  var graph = createGraph();
  graph.addLink(0, 1, 'Lu');
  graph.addLink(1, 2, 'Lu');
  graph.addLink(0, 2, 'Tako');

  var visitedCount = 0;
  traverse(graph)
      .links()
      .where(function (link) { return link.data === 'Lu'; })
      .forEach(function (link){
        t.ok(link.data, 'link should have associated data with it');
        t.equal(link.data, 'Lu');
        visitedCount += 1;
      });

  t.equal(visitedCount, 2, 'Two links should be visited');
  t.end();
});

test('get all links to neighbors', function (t) {
  var graph = createGraph();
  // a small graph:
  //    0 -> 1
  //       2   3
  //     4
  graph.addLink(0, 1);
  graph.addLink(1, 2); graph.addLink(1, 3);
  graph.addLink(2, 4);

  t.test('visit custom set of to nodes', function (t) {
    var startNodeId = 0;
    var visitedCount = 0;

    traverse(graph)
      .links()
      .to([2, 3])
      .forEach(function (link) {
        visitedCount += 1;
        t.ok(link.toId === 2 || link.toId === 3, 'Link should go to either 2 or 3');
      });
    t.equal(visitedCount, 2, 'Unexpected number of links visited');
    t.end();
  });

  t.test('visit custom set of from nodes', function (t) {
    var startNodeId = 0;
    var visitedCount = 0;

    traverse(graph)
      .links()
      .from([1, 2])
      .forEach(function (link) {
        visitedCount += 1;
        t.ok(link.fromId === 1 || link.fromId === 2, 'Link should go to either 2 or 3');
      });
    t.equal(visitedCount, 3, 'Unexpected number of links visited');
    t.end();
  });
  t.end();
});
<commit_msg>More tests<commit_after>var test = require('tap').test,
    traverse = require('..').traverse,
    createGraph = require('ngraph.graph'),
    // complete graph builder
    createCompleteGraph = require('./graphbuilder');

test('get all links', function(t) {
  var nodesCount = 5;
  var graph = createCompleteGraph(nodesCount);
  var expectedLinksCount = graph.getLinksCount();
  var visitedCount = 0;

  traverse(graph)
      .links()
      .forEach(function(link){
        t.ok(link, 'link should be passed as an argument');
        visitedCount += 1;
      });

  t.equal(visitedCount, expectedLinksCount, 'Number of edges is not correct');
  t.end();
});

test('get all links from node', function(t) {
  var nodesCount = 5;
  var graph = createCompleteGraph(nodesCount);
  // it is a complete graph:
  var expectedLinksCount = nodesCount - 1;
  var visitedCount = 0;

  var startNodeId = 0;
  traverse(graph)
      .links()
      .from(startNodeId)
      .forEach(function(link){
        t.ok(link, 'link should be passed as an argument');
        t.equal(link.fromId, startNodeId, 'from node id is not correct');
        visitedCount += 1;
      });

  t.equal(visitedCount, expectedLinksCount, 'Number of edges is not correct');
  t.end();
});

test('get all links to node', function(t) {
  var nodesCount = 5;
  var graph = createCompleteGraph(nodesCount);
  // it is a complete graph:
  var expectedLinksCount = nodesCount - 1;
  var visitedCount = 0;

  var endNodeId = 0;
  traverse(graph)
      .links()
      .to(endNodeId)
      .forEach(function(link){
        t.ok(link, 'link should be passed as an argument');
        t.equal(link.toId, endNodeId, 'end node id is not correct');
        visitedCount += 1;
      });

  t.equal(visitedCount, expectedLinksCount, 'Number of edges is not correct');
  t.end();
});

test('get links form to', function(t) {
  var graph = createGraph();
  graph.addLink(0, 1); graph.addLink(1, 2);
  traverse(graph)
    .links()
    .from(0)
    .to(2)
    .forEach(function(link) {
      t.fail('Graph does not have such link');
    })
  t.end();
});

test('get filtered links from node', function(t) {
  var graph = createGraph();
  graph.addLink(0, 1, 'Lu');
  graph.addLink(1, 2, 'Lu');
  graph.addLink(0, 2, 'Tako');

  var visitedCount = 0;
  traverse(graph)
      .links()
      .from(0)
      .where(function(link) { return link.data === 'Lu'; })
      .forEach(function(link){
        t.ok(link.data, 'link should have associated data with it');
        t.equal(link.data, 'Lu');
        visitedCount += 1;
      });

  t.equal(visitedCount, 1, 'Only one link should be visited');
  t.end();
});

test('get all links filtered', function(t) {
  var graph = createGraph();
  graph.addLink(0, 1, 'Lu');
  graph.addLink(1, 2, 'Lu');
  graph.addLink(0, 2, 'Tako');

  var visitedCount = 0;
  traverse(graph)
      .links()
      .where(function (link) { return link.data === 'Lu'; })
      .forEach(function (link){
        t.ok(link.data, 'link should have associated data with it');
        t.equal(link.data, 'Lu');
        visitedCount += 1;
      });

  t.equal(visitedCount, 2, 'Two links should be visited');
  t.end();
});

test('get all links to neighbors', function (t) {
  var graph = createGraph();
  // a small graph:
  //    0 -> 1
  //       2   3
  //     4
  graph.addLink(0, 1);
  graph.addLink(1, 2); graph.addLink(1, 3);
  graph.addLink(2, 4);

  t.test('visit custom set of to nodes', function (t) {
    var startNodeId = 0;
    var visitedCount = 0;

    traverse(graph)
      .links()
      .to([2, 3])
      .forEach(function (link) {
        visitedCount += 1;
        t.ok(link.toId === 2 || link.toId === 3, 'Link should go to either 2 or 3');
      });
    t.equal(visitedCount, 2, 'Unexpected number of links visited');
    t.end();
  });

  t.test('visit custom set of from and to', function(t) {
    var startNodeId = 0;
    var visitedCount = 0;

    traverse(graph)
      .links()
      .from([0, 1])
      .to([2, 4, 1])
      .forEach(function (link) {
        visitedCount += 1;
        var fromIsGood = link.fromId === 0 || link.formId === 1;
        var toIsGood = link.toId === 2 || link.toId === 4 || link.toId === 1;
        t.ok(fromIsGood || toIsGood, 'Link has unexpected start or end');
      });
    // with our configuration only two links are reachable:
    t.equal(visitedCount, 2, 'Unexpected number of links visited');
    t.end();
  })

  t.test('visit custom set of from nodes', function (t) {
    var startNodeId = 0;
    var visitedCount = 0;

    traverse(graph)
      .links()
      .from([1, 2])
      .forEach(function (link) {
        visitedCount += 1;
        t.ok(link.fromId === 1 || link.fromId === 2, 'Link should go to either 2 or 3');
      });
    t.equal(visitedCount, 3, 'Unexpected number of links visited');
    t.end();
  });

  t.test('visit grandchildren', function(t) {
    // graph reminder:
    //    0 -> 1
    //       2   3
    //     4
    var nodes = traverse(graph).nodes();
    var links = traverse(graph).links();
    var children = nodes.neighbors(1);
    var grandChildren = nodes.neighbors(children);
    var totalVisited = 0;
    links.from(1).to(children)
      .forEach(function(link) {
        t.ok(link.toId === 2 || link.toId === 3, 'Unexpected link visited');
        totalVisited++;
      });

    links.from(children).to(grandChildren)
      .forEach(function(link) {
        t.ok(link.toId === 4, 'Unexpected link visited');
        totalVisited++;
      });
    t.equal(totalVisited, 3, 'Only three nodes should be visited in this test')
    t.end();
  });
  t.end();
});
<|endoftext|>


<commit_before>(function(O,W,v){'use strict';function H(a){return function(){var b=arguments[0],d;d="["+(a?a+":":"")+b+"] http://errors.angularjs.org/1.5.0/"+(a?a+"/":"")+b;for(b=1;b<arguments.length;b++){d=d+(1==b?"?":"&")+"p"+(b-1)+"=";var c=encodeURIComponent,e;e=arguments[b];e="function"==typeof e?e.toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof e?"undefined":"string"!=typeof e?JSON.stringify(e):e;d+=c(e)}return Error(d)}}function Ca(a){if(null==a||Za(a))return!1;if(L(a)||F(a)||C&&a instanceof C)return!0;
<commit_msg>#2<commit_after><|endoftext|>


<commit_before>var fs = require('fs');

// Define line type patterns and their identifiers
var linetypes = {
  dbstart : { pattern: /^\s?\/\*\*/ },
  dbanno  : { pattern: /^\s?\*\s?@([\w:-_\(\)]+)(\s+(.*))?/, returns: { name:1, value:3 } },
  dbend   : { pattern: /^\s?\*\/$/ },
  fnsig1  : { pattern: /^\s?function\s+(\w+)\s?/, returns: { name:1 } },
  fnsig2  : { pattern: /^\s?exports\.(\w+)\s?=\s?function/, returns: { name:1 } },
  fnsig3  : { pattern: /^\s?module\.exports\s?=\s?function/, returns: { name:'anonymous' } },
  fnsig4  : { pattern: /exports\[['"](\w+)['"]\]\s*=\s*function/, returns: { name:1 } },
  fnsig5  : { pattern: /^\s*var\s+(\w+)\s*=\s*function/, returns: { name:1 } }
};

function trim(str) {
  return 'string' == typeof str ? str.replace(/^\s+/,'').replace(/\s+$/,'') : str;
}

/**
 * Runs through linetypes, identifying str
 */
function identify(str) {

  // Try all predefined line type patterns
  for(var i in linetypes) {

    // Check for a match
    if(null != (match = str.match( linetypes[i].pattern ))) {

      // Default returns type and regexp match results
      var returns = { id: i, match: match };

      // If specific values are requested, fill those in
      if('undefined' != typeof linetypes[i].returns) {
        for(var r in linetypes[i].returns) {
          returns[r] = 'string' == typeof linetypes[i].returns[r] ?
              linetypes[i].returns[r] : trim(match[linetypes[i].returns[r]]);
        }
      }

      return returns;
    }
  }

  return false;
}

function analyze(data) {

  // Object for holding annotation data
  var annotations = {};

  // Iterate over lines
  var lines = data.split('\n');
  var current = {};
  for(var num in lines) {

    // Get line type
    var type = identify(lines[num]);

    switch(type.id) {
      case 'dbstart':
        // Reset current annotation object
        current = {};
        break;

      case 'dbanno':
        // Store whatever was annotated, bucketing values of duplicate keys
        var annotationValue = undefined == type.value || '' == type.value ? true : type.value;
        if(undefined != current[type.name]) {
          // Create array to hold items
          if('string' == typeof current[type.name])
            current[type.name] = [current[type.name]]
          current[type.name].push(annotationValue);
        } else {
          current[type.name] = annotationValue;
        }
        break;

      case 'fnsig1':
      case 'fnsig2':
      case 'fnsig3':
      case 'fnsig4':
      case 'fnsig5':
        // Store current annotations under function name
        annotations[type.name] = current;
        break;

      default: break;
    }
  }

  return annotations;
}

/**
 * Get an object representation of all annotations in file
 *
 * @param string filename Path to file
 * @param function callback
 *
 */
function get(filename, callback) {

  // Read file
  fs.readFile(filename, 'utf8', function(err, data) {
    if(!err) {
      var annotations = analyze(data);
      callback(null, annotations);
    } else {
      callback(err, null);
    }
  });
};

function getSync(filename) {

  // Read file
  var data = fs.readFileSync(filename, 'utf8');

  // Analyze if possible
  if('string' == typeof data) {
    return analyze(data);
  } else {
    return false;
  }
};

exports.get     = get;
exports.getSync = getSync;<commit_msg>Fixed annotations being carried from one function to another without a docblock start<commit_after>var fs = require('fs');

// Define line type patterns and their identifiers
var linetypes = {
  dbstart : { pattern: /^\s?\/\*\*/ },
  dbanno  : { pattern: /^\s?\*\s?@([\w:-_\(\)]+)(\s+(.*))?/, returns: { name:1, value:3 } },
  dbend   : { pattern: /^\s?\*\/$/ },
  fnsig1  : { pattern: /^\s?function\s+(\w+)\s?/, returns: { name:1 } },
  fnsig2  : { pattern: /^\s?exports\.(\w+)\s?=\s?function/, returns: { name:1 } },
  fnsig3  : { pattern: /^\s?module\.exports\s?=\s?function/, returns: { name:'anonymous' } },
  fnsig4  : { pattern: /exports\[['"](\w+)['"]\]\s*=\s*function/, returns: { name:1 } },
  fnsig5  : { pattern: /^\s*var\s+(\w+)\s*=\s*function/, returns: { name:1 } }
};

function trim(str) {
  return 'string' == typeof str ? str.replace(/^\s+/,'').replace(/\s+$/,'') : str;
}

/**
 * Runs through linetypes, identifying str
 */
function identify(str) {

  // Try all predefined line type patterns
  for(var i in linetypes) {

    // Check for a match
    if(null != (match = str.match( linetypes[i].pattern ))) {

      // Default returns type and regexp match results
      var returns = { id: i, match: match };

      // If specific values are requested, fill those in
      if('undefined' != typeof linetypes[i].returns) {
        for(var r in linetypes[i].returns) {
          returns[r] = 'string' == typeof linetypes[i].returns[r] ?
              linetypes[i].returns[r] : trim(match[linetypes[i].returns[r]]);
        }
      }

      return returns;
    }
  }

  return false;
}

function analyze(data) {

  // Object for holding annotation data
  var annotations = {};

  // Iterate over lines
  var lines = data.split('\n');
  var current = {};
  for(var num in lines) {

    // Get line type
    var type = identify(lines[num]);

    switch(type.id) {
      case 'dbstart':
        // Reset current annotation object
        current = {};
        break;

      case 'dbanno':
        // Store whatever was annotated, bucketing values of duplicate keys
        var annotationValue = undefined == type.value || '' == type.value ? true : type.value;
        if(undefined != current[type.name]) {
          // Create array to hold items
          if('string' == typeof current[type.name])
            current[type.name] = [current[type.name]]
          current[type.name].push(annotationValue);
        } else {
          current[type.name] = annotationValue;
        }
        break;

      case 'fnsig1':
      case 'fnsig2':
      case 'fnsig3':
      case 'fnsig4':
      case 'fnsig5':
        // Store current annotations under function name
        annotations[type.name] = current;
        current = {};
        break;

      default: break;
    }
  }

  return annotations;
}

/**
 * Get an object representation of all annotations in file
 *
 * @param string filename Path to file
 * @param function callback
 *
 */
function get(filename, callback) {

  // Read file
  fs.readFile(filename, 'utf8', function(err, data) {
    if(!err) {
      var annotations = analyze(data);
      callback(null, annotations);
    } else {
      callback(err, null);
    }
  });
};

function getSync(filename) {

  // Read file
  var data = fs.readFileSync(filename, 'utf8');

  // Analyze if possible
  if('string' == typeof data) {
    return analyze(data);
  } else {
    return false;
  }
};

exports.get     = get;
exports.getSync = getSync;<|endoftext|>


<commit_before>var ResourceService = require("services/ResourceService");

Vue.component("invoice-address-select", {

    template: "<address-select template=\"#vue-address-select\" v-on:address-changed=\"addressChanged\" address-type=\"1\" :address-list=\"addressList\" :selected-address-id=\"selectedAddressId\" :show-error='checkoutValidation.invoiceAddress.showError'></address-select>",

    props: [
        "addressList",
        "hasToValidate",
        "selectedAddressId"
    ],

    data: function()
    {
        return {
            checkout: {},
            checkoutValidation: {invoiceAddress: {}}
        };
    },

    /**
     * Initialise the event listener
     */
    created: function()
    {
        ResourceService.bind("checkout", this);

        if (this.hasToValidate)
        {
            ResourceService.bind("checkoutValidation", this);

            this.checkoutValidation.invoiceAddress.validate = this.validate;
        }
    },

    methods:
    {
        /**
         * Update the invoice address
         * @param selectedAddress
         */
        addressChanged: function(selectedAddress)
        {
            this.checkout.billingAddressId = selectedAddress.id;

            ResourceService.getResource("checkout")
                .set(this.checkout)
                .done(function()
                {
                    document.dispatchEvent(new CustomEvent("afterInvoiceAddressChanged", {detail: this.checkout.billingAddressId}));
                }.bind(this));

            if (this.hasToValidate)
            {
                this.validate();
            }
        },

        validate: function()
        {
            this.checkoutValidation.invoiceAddress.showError = this.checkout.billingAddressId <= 0;
        }
    }
});
<commit_msg>checkout_inline_address_input: - create invoiceAddress popup will open, when user opens /checkout without having an address<commit_after>var ResourceService = require("services/ResourceService");

Vue.component("invoice-address-select", {

    template: "<address-select v-ref:invoice-address-select template=\"#vue-address-select\" v-on:address-changed=\"addressChanged\" address-type=\"1\" :address-list=\"addressList\" :selected-address-id=\"selectedAddressId\" :show-error='checkoutValidation.invoiceAddress.showError'></address-select>",

    props: [
        "addressList",
        "hasToValidate",
        "selectedAddressId"
    ],

    data: function()
    {
        return {
            checkout: {},
            checkoutValidation: {invoiceAddress: {}}
        };
    },

    /**
     * Initialise the event listener
     */
    created: function()
    {
        ResourceService.bind("checkout", this);

        if (this.hasToValidate)
        {
            ResourceService.bind("checkoutValidation", this);

            this.checkoutValidation.invoiceAddress.validate = this.validate;
        }
    },

    /**
     * If no address is related to the user, a popup will open to add an address
     */
    ready: function()
    {
        if (this.addressList.length <= 0)
        {
            var invoiceAddressSelect = this.$refs.invoiceAddressSelect;

            invoiceAddressSelect.showAddModal();
        }
    },

    methods:
    {
        /**
         * Update the invoice address
         * @param selectedAddress
         */
        addressChanged: function(selectedAddress)
        {
            this.checkout.billingAddressId = selectedAddress.id;

            ResourceService.getResource("checkout")
                .set(this.checkout)
                .done(function()
                {
                    document.dispatchEvent(new CustomEvent("afterInvoiceAddressChanged", {detail: this.checkout.billingAddressId}));
                }.bind(this));

            if (this.hasToValidate)
            {
                this.validate();
            }
        },

        validate: function()
        {
            this.checkoutValidation.invoiceAddress.showError = this.checkout.billingAddressId <= 0;
        }
    }
});
<|endoftext|>


<commit_before>import Component from '@ember/component';
import EmberObject from '@ember/object';
import { set as emberSet, get as emberGet } from '@ember/object';
import { later as runLater } from '@ember/runloop';
import $ from 'jquery';
import buttonTracker from '../utils/raw_events';
import capabilities from '../utils/capabilities';
import { observer } from '@ember/object';
import { computed } from '@ember/object';

export default Component.extend({
  draw: observer(
    'pending',
    'current_dwell',
    'screen_width',
    'screen_height',
    'event_x',
    'event_y',
    'window_x',
    'window_y',
    'selected',
    'window_width',
    'window_height',
    function() {
      var elem = this.get('element').getElementsByClassName('preview')[0];
      var coords = this.getProperties('screen_width', 'screen_height', 'event_x', 'event_y', 'window_x', 'window_y', 'window_width', 'window_height');

      var now = (new Date()).getTime();
      var ts = this.get('ts');
      this.set('current_dwell', (ts && now - ts <= 2000));
      if(!this.get('current_dwell')) { this.set('pending', false); }

      if(elem && coords && coords.screen_width) {
        var context = elem.getContext('2d');
        var width = elem.width;
        var height = elem.height;
        context.clearRect(0, 0, width, height);
        if(this.get('pending')) {
          context.fillStyle = '#fff7b7';
          context.strokeStyle = '#a59a47';
        } else if(this.get('current_dwell')) {
          context.fillStyle = '#eee';
          context.strokeStyle = '#444';
        } else {
          context.fillStyle = '#fee';
          context.strokeStyle = '#844';
        }
        context.beginPath();
        context.rect(0, 0, width, height);
        context.closePath();
        context.fill();
        context.stroke();

        var ctx_window_width = width * (coords.window_width / coords.screen_width);
        var ctx_window_height = height * (coords.window_height / coords.screen_height);
        var ctx_window_x = width * (coords.window_x / coords.screen_width);
        var ctx_window_y = height * (coords.window_y / coords.screen_height);
        if(this.get('current_dwell')) {
          context.fillStyle = '#fff';
          context.strokeStyle = '#444';
        } else {
          context.fillStyle = '#fff';
          context.strokeStyle = '#844';
        }
        context.beginPath();
        context.rect(ctx_window_x, ctx_window_y, ctx_window_width, ctx_window_height);
        context.closePath();
        context.fill();
        context.stroke();

        if(coords.event_x) {
          var ctx_point_x = width * (coords.event_x / coords.screen_width);
          var ctx_point_y = height * (coords.event_y / coords.screen_height);
          context.fillStyle = '#f00';
          if(this.get('selected')) {
            context.strokeStyle = '#742eff';
            context.fillStyle = '#3cff00';
          }
          context.beginPath();
          context.arc(ctx_point_x, ctx_point_y, 10, 0, 2*Math.PI);
          context.closePath();
          context.fill();
          if(this.get('selected')) {
            context.lineWidth = 4;
            context.stroke();
          }
        }
      }
    }
  ),
  clear_on_change: observer('type', function() {
    this.setProperties({
      ts: (new Date()).getTime(),
      pending: true,
      event_x: null,
      hardware: null
    });
  }),
  hardware_type: computed('hardware', 'source', function() {
    var res = {};
    if(this.get('hardware') && this.get('source') == 'eyegaze') {
      res[this.get('hardware')] = true;
      return res;
    } else {
      return null;
    }
  }),
  eye_tracking: computed('type', function() {
    return this.get('type') == 'eyegaze';
  }),
  update_speed: observer('preferences.device.dwell_arrow_speed', function() {
    if(buttonTracker.gamepadupdate && this.get('preferences.device.dwell_arrow_speed')) {
      buttonTracker.gamepadupdate.speed = this.get('preferences.device.dwell_arrow_speed');
    }
  }),
  didInsertElement: function() {
    var _this = this;

    _this.setProperties({
      screen_width: window.screen.width,
      screen_height: window.screen.height,
      pending: true,
      window_x: window.screenInnerOffsetX || window.screenX,
      window_y: window.screenInnerOffsetY || window.screenY,
      window_width: $(window).width(),
      window_height: $(window).height(),
      event_x: null,
      event_y: null,
      eye_listener: null,
      head_listener: null,
      mouse_listener: null
    });

    var head_pointer = _this.get('preferences.device.dwell_type') == 'head' && _this.get('preferences.device.dwell_head_pointer');
    if(!_this.get('preferences.device.dwell_type') || _this.get('preferences.device.dwell_type') == 'eyegaze' || head_pointer) {
      var eye_listener = function(e) {
        var ratio = window.devicePixelRatio || 1.0;
        e.screenX = ratio * (e.clientX + (window.screenInnerOffsetX || window.screenX));
        e.screenY = ratio * (e.clientY + (window.screenInnerOffsetY || window.screenY));
        _this.setProperties({
          screen_width: window.screen.width,
          screen_height: window.screen.height,
          event_x: e.screenX,
          event_y: e.screenY,
          pending: false,
          hardware: e.eyegaze_hardware,
          window_x: window.screenInnerOffsetX || window.screenX,
          window_y: window.screenInnerOffsetY || window.screenY,
          ts: (new Date()).getTime(),
          window_width: $(window).width(),
          window_height: $(window).height(),
          source: {eyegaze: true}
        });
      };
      capabilities.eye_gaze.listen('noisy');
      this.set('eye_listener', eye_listener);
      $(document).on('gazelinger', eye_listener);
      this.set('eye_gaze', capabilities.eye_gaze);
    }

    if(_this.get('preferences.device.dwell_type') == 'mouse_dwell') {
      var mouse_listener = function(e) {
        _this.setProperties({
          screen_width: window.screen.width,
          screen_height: window.screen.height,
          event_x: e.screenX,
          event_y: e.screenY,
          pending: false,
          window_x: window.screenInnerOffsetX || window.screenX,
          window_y: window.screenInnerOffsetY || window.screenY,
          ts: (new Date()).getTime(),
          window_width: $(window).width(),
          window_height: $(window).height(),
          source: {cursor: true}
        });
      };
      this.set('mouse_listener', mouse_listener);
      this.set('ts', (new Date()).getTime());
      $(document).on('mousemove', mouse_listener);
    }

    if(_this.get('preferences.device.dwell_type') == 'arrow_dwell' || (_this.get('preferences.device.dwell_type') == 'head' && !head_pointer)) {
      if(_this.get('preferences.device.dwell_type') == 'headx') {
        var head_listener = function(e) {
          var event_x = _this.get('event_x') == null ? _this.get('event_x') : (window.screen.width / 2);
          var event_y = _this.get('event_y') == null ? _this.get('event_y') : (window.screen.height / 2);
          var window_x = window.screenInnerOffsetX || window.screenX;
          var window_y = window.screenInnerOffsetY || window.screenY;
          var window_width = $(window).width();
          var window_height = $(window).height();
          _this.setProperties({
            screen_width: window.screen.width,
            screen_height: window.screen.height,
            event_x: Math.min(Math.max(window_x, event_x + e.horizontal), window_x + window_width),
            event_y: Math.min(Math.max(window_y, event_y + e.vertical), window_y + window_height),
            pending: false,
            window_x: window_x,
            window_y: window_y,
            ts: (new Date()).getTime(),
            window_width: window_width,
            window_height: window_height,
            source: {head: true}
          });
        };
        capabilities.head_tracking.listen();
        this.set('head_listener', head_listener);
        $(document).on('headtilt', head_listener);
        this.set('head_tracking', capabilities.head_tracking);
      } else {//if(_this.get('preferences.device.dwell_type') == 'arrow_dwell') {
        var key_listener = function(e) {
          if(_this.get('preferences.device.dwell_selection') == 'button') {
            if(e.keyCode && e.keyCode == _this.get('preferences.device.scanning_select_keycode')) {
              buttonTracker.gamepadupdate('select', e);
            }
          }
        };
        $(document).on('keydown', key_listener);
        _this.set('key_listener', key_listener);
        buttonTracker.gamepadupdate = function(action, e) {
          if(action == 'select') {
            var now = (new Date()).getTime()
            _this.setProperties({
              selected: now
            })
            runLater(function() {
              if(_this.get('selected') == now) {
                _this.set('selected', null);
              }
            }, 800);
          } else if(action == 'move') {
            var event_x = _this.get('event_x') != null ? _this.get('event_x') : (window.screen.width / 2);
            var event_y = _this.get('event_y') != null ? _this.get('event_y') : (window.screen.height / 2);
            var window_x = window.screenInnerOffsetX || window.screenX;
            var window_y = window.screenInnerOffsetY || window.screenY;
            var window_width = $(window).width();
            var window_height = $(window).height();
            var source = {};
            source[e.activation] = true;
            _this.setProperties({
              screen_width: window.screen.width,
              screen_height: window.screen.height,
              event_x: e.clientX, //Math.min(Math.max(window_x, event_x + e.horizontal), window_x + window_width),
              event_y: e.clientY , //Math.min(Math.max(window_y, event_y + e.vertical), window_y + window_height),
              pending: false,
              window_x: window_x,
              window_y: window_y,
              ts: (new Date()).getTime(),
              window_width: window_width,
              window_height: window_height,
              source: source
            });
          }
        };
        if(capabilities.head_tracking.available) {
          capabilities.head_tracking.listen();
        }

        buttonTracker.gamepadupdate.speed = _this.get('preferences.device.dwell_arrow_speed');
        _this.set('gampead_listener', buttonTracker.gamepadupdate);
      }
    }

    if(_this.get('preferences.device.dwell_selection') == 'expression') {
      var expression_listener = function(e) {
        if(e.expression && e.expression == _this.get('preferences.device.select_expression') == e.expression) {
          var now = (new Date()).getTime()
          _this.setProperties({
            selected: now
          })
          runLater(function() {
            if(_this.get('selected') == now) {
              _this.set('selected', null);
            }
          }, 1500);
        }
      };
      $(document).on('facechange', expression_listener);
      this.set('expression_listener', expression_listener)
      if(!this.get('head_tracking')) {
        capabilities.head_tracking.listen();
        this.set('head_tracking', capabilities.head_tracking);
      }
    }
    _this.check_timeout();

  },
  with_status: computed('eye_gaze.statuses', function() {
    return emberGet(capabilities.eye_gaze, 'statuses');
  }),
  check_timeout: function() {
    var _this = this;
    if(this.get('mouse_listener') || this.get('eye_listener') || this.get('head_listener') || this.get('gamepad_listener') || this.get('expression_listener')) {
      var now = (new Date()).getTime();
      var ts = this.get('ts');
      this.set('current_dwell', (ts && now - ts <= 2000));
      if(!this.get('current_dwell')) { this.set('pending', false); }
      runLater(function() { _this.check_timeout(); }, 100);
    }
  },
  willDestroyElement: function() {
    capabilities.eye_gaze.stop_listening();
    if(this.get('mouse_listener')) {
      $(document).off('mousemove', this.get('mouse_listener'));
      this.set('mouse_listener', null);
    }
    if(this.get('eye_listener')) {
      $(document).off('gazelinger', this.get('eye_listener'));
      this.set('eye_listener', null);
    }
    if(this.get('head_listener')) {
      $(document).off('headtilt', this.get('head_listener'));
      this.set('head_listener', null);
    }
    if(this.get('key_listener')) {
      $(document).off('keydown', this.get('key_listener'));
      this.set('key_listener', null);
    }
    if(this.get('gampead_listener')) {
      this.set('gamepad_listener', null);
    }
    if(this.get('keycode_listener')) {
      $(document).off('keypress', this.get('keycode_listener'));
      this.set('keycode_listener', null);
    }
    if(this.get('expression_listener')) {
      $(document).off('facechange', this.get('expression_listener'));
      this.set('expression_listener', null);
    }
  },
  actions: {
    advanced: function() {
      this.set('advanced', true);
    }
  }
});
<commit_msg>tweak<commit_after>import Component from '@ember/component';
import EmberObject from '@ember/object';
import { set as emberSet, get as emberGet } from '@ember/object';
import { later as runLater } from '@ember/runloop';
import $ from 'jquery';
import buttonTracker from '../utils/raw_events';
import capabilities from '../utils/capabilities';
import { observer } from '@ember/object';
import { computed } from '@ember/object';

export default Component.extend({
  draw: observer(
    'pending',
    'current_dwell',
    'screen_width',
    'screen_height',
    'event_x',
    'event_y',
    'window_x',
    'window_y',
    'selected',
    'window_width',
    'window_height',
    function() {
      var elem = this.get('element').getElementsByClassName('preview')[0];
      var coords = this.getProperties('screen_width', 'screen_height', 'event_x', 'event_y', 'window_x', 'window_y', 'window_width', 'window_height');

      var now = (new Date()).getTime();
      var ts = this.get('ts');
      this.set('current_dwell', (ts && now - ts <= 2000));
      if(!this.get('current_dwell')) { this.set('pending', false); }

      if(elem && coords && coords.screen_width) {
        var context = elem.getContext('2d');
        var width = elem.width;
        var height = elem.height;
        context.clearRect(0, 0, width, height);
        if(this.get('pending')) {
          context.fillStyle = '#fff7b7';
          context.strokeStyle = '#a59a47';
        } else if(this.get('current_dwell')) {
          context.fillStyle = '#eee';
          context.strokeStyle = '#444';
        } else {
          context.fillStyle = '#fee';
          context.strokeStyle = '#844';
        }
        context.beginPath();
        context.rect(0, 0, width, height);
        context.closePath();
        context.fill();
        context.stroke();

        var ctx_window_width = width * (coords.window_width / coords.screen_width);
        var ctx_window_height = height * (coords.window_height / coords.screen_height);
        var ctx_window_x = width * (coords.window_x / coords.screen_width);
        var ctx_window_y = height * (coords.window_y / coords.screen_height);
        if(this.get('current_dwell')) {
          context.fillStyle = '#fff';
          context.strokeStyle = '#444';
        } else {
          context.fillStyle = '#fff';
          context.strokeStyle = '#844';
        }
        context.beginPath();
        context.rect(ctx_window_x, ctx_window_y, ctx_window_width, ctx_window_height);
        context.closePath();
        context.fill();
        context.stroke();

        if(coords.event_x) {
          var ctx_point_x = width * (coords.event_x / coords.screen_width);
          var ctx_point_y = height * (coords.event_y / coords.screen_height);
          context.fillStyle = '#f00';
          if(this.get('selected')) {
            context.strokeStyle = '#742eff';
            context.fillStyle = '#3cff00';
          }
          context.beginPath();
          context.arc(ctx_point_x, ctx_point_y, 10, 0, 2*Math.PI);
          context.closePath();
          context.fill();
          if(this.get('selected')) {
            context.lineWidth = 4;
            context.stroke();
          }
        }
      }
    }
  ),
  clear_on_change: observer('type', function() {
    this.setProperties({
      ts: (new Date()).getTime(),
      pending: true,
      event_x: null,
      hardware: null
    });
  }),
  hardware_type: computed('hardware', 'source', function() {
    var res = {};
    if(this.get('hardware') && this.get('source') == 'eyegaze') {
      res[this.get('hardware')] = true;
      return res;
    } else {
      return null;
    }
  }),
  eye_tracking: computed('type', function() {
    return this.get('type') == 'eyegaze';
  }),
  update_speed: observer('preferences.device.dwell_arrow_speed', function() {
    if(buttonTracker.gamepadupdate && this.get('preferences.device.dwell_arrow_speed')) {
      buttonTracker.gamepadupdate.speed = this.get('preferences.device.dwell_arrow_speed');
    }
  }),
  didInsertElement: function() {
    var _this = this;

    _this.setProperties({
      screen_width: window.screen.width,
      screen_height: window.screen.height,
      pending: true,
      window_x: window.screenInnerOffsetX || window.screenX,
      window_y: window.screenInnerOffsetY || window.screenY,
      window_width: $(window).width(),
      window_height: $(window).height(),
      event_x: null,
      event_y: null,
      eye_listener: null,
      head_listener: null,
      mouse_listener: null
    });

    var head_pointer = _this.get('preferences.device.dwell_type') == 'head' && _this.get('preferences.device.dwell_head_pointer');
    if(!_this.get('preferences.device.dwell_type') || _this.get('preferences.device.dwell_type') == 'eyegaze' || head_pointer) {
      var eye_listener = function(e) {
        var ratio = window.devicePixelRatio || 1.0;
        e.screenX = ratio * (e.clientX + (window.screenInnerOffsetX || window.screenX));
        e.screenY = ratio * (e.clientY + (window.screenInnerOffsetY || window.screenY));
        _this.setProperties({
          screen_width: window.screen.width,
          screen_height: window.screen.height,
          event_x: e.screenX,
          event_y: e.screenY,
          pending: false,
          hardware: e.eyegaze_hardware,
          window_x: window.screenInnerOffsetX || window.screenX,
          window_y: window.screenInnerOffsetY || window.screenY,
          ts: (new Date()).getTime(),
          window_width: $(window).width(),
          window_height: $(window).height(),
          source: {eyegaze: true}
        });
      };
      capabilities.eye_gaze.listen('noisy');
      this.set('eye_listener', eye_listener);
      $(document).on('gazelinger', eye_listener);
      this.set('eye_gaze', capabilities.eye_gaze);
    }

    if(_this.get('preferences.device.dwell_type') == 'mouse_dwell') {
      var mouse_listener = function(e) {
        _this.setProperties({
          screen_width: window.screen.width,
          screen_height: window.screen.height,
          event_x: e.screenX,
          event_y: e.screenY,
          pending: false,
          window_x: window.screenInnerOffsetX || window.screenX,
          window_y: window.screenInnerOffsetY || window.screenY,
          ts: (new Date()).getTime(),
          window_width: $(window).width(),
          window_height: $(window).height(),
          source: {cursor: true}
        });
      };
      this.set('mouse_listener', mouse_listener);
      this.set('ts', (new Date()).getTime());
      $(document).on('mousemove', mouse_listener);
    }

    if(_this.get('preferences.device.dwell_type') == 'arrow_dwell' || (_this.get('preferences.device.dwell_type') == 'head' && !head_pointer)) {
      if(false) { //_this.get('preferences.device.dwell_type') == 'head') {
        var head_listener = function(e) {
          var event_x = _this.get('event_x') == null ? _this.get('event_x') : (window.screen.width / 2);
          var event_y = _this.get('event_y') == null ? _this.get('event_y') : (window.screen.height / 2);
          var window_x = window.screenInnerOffsetX || window.screenX;
          var window_y = window.screenInnerOffsetY || window.screenY;
          var window_width = $(window).width();
          var window_height = $(window).height();
          _this.setProperties({
            screen_width: window.screen.width,
            screen_height: window.screen.height,
            event_x: Math.min(Math.max(window_x, event_x + e.horizontal), window_x + window_width),
            event_y: Math.min(Math.max(window_y, event_y + e.vertical), window_y + window_height),
            pending: false,
            window_x: window_x,
            window_y: window_y,
            ts: (new Date()).getTime(),
            window_width: window_width,
            window_height: window_height,
            source: {head: true}
          });
        };
        capabilities.head_tracking.listen();
        this.set('head_listener', head_listener);
        $(document).on('headtilt', head_listener);
        this.set('head_tracking', capabilities.head_tracking);
      } else {//} if(_this.get('preferences.device.dwell_type') == 'arrow_dwell') {
        var key_listener = function(e) {
          if(_this.get('preferences.device.dwell_selection') == 'button') {
            if(e.keyCode && e.keyCode == _this.get('preferences.device.scanning_select_keycode')) {
              buttonTracker.gamepadupdate('select', e);
            }
          }
        };
        $(document).on('keydown', key_listener);
        _this.set('key_listener', key_listener);
        buttonTracker.gamepadupdate = function(action, e) {
          if(action == 'select') {
            var now = (new Date()).getTime()
            _this.setProperties({
              selected: now
            })
            runLater(function() {
              if(_this.get('selected') == now) {
                _this.set('selected', null);
              }
            }, 800);
          } else if(action == 'move') {
            var window_x = window.screenInnerOffsetX || window.screenX;
            var window_y = window.screenInnerOffsetY || window.screenY;
            var window_width = $(window).width();
            var window_height = $(window).height();
            var source = {};
            source[e.activation] = true;
            _this.setProperties({
              screen_width: window.screen.width,
              screen_height: window.screen.height,
              event_x: e.clientX, //Math.min(Math.max(window_x, event_x + e.horizontal), window_x + window_width),
              event_y: e.clientY , //Math.min(Math.max(window_y, event_y + e.vertical), window_y + window_height),
              pending: false,
              window_x: window_x,
              window_y: window_y,
              ts: (new Date()).getTime(),
              window_width: window_width,
              window_height: window_height,
              source: source
            });
          }
        };
        if(capabilities.head_tracking.available) {
          capabilities.head_tracking.listen();
        }

        buttonTracker.gamepadupdate.speed = _this.get('preferences.device.dwell_arrow_speed');
        _this.set('gampead_listener', buttonTracker.gamepadupdate);
      }
    }

    if(_this.get('preferences.device.dwell_selection') == 'expression') {
      var expression_listener = function(e) {
        if(e.expression && e.expression == _this.get('preferences.device.select_expression') == e.expression) {
          var now = (new Date()).getTime()
          _this.setProperties({
            selected: now
          })
          runLater(function() {
            if(_this.get('selected') == now) {
              _this.set('selected', null);
            }
          }, 1500);
        }
      };
      $(document).on('facechange', expression_listener);
      this.set('expression_listener', expression_listener)
      if(!this.get('head_tracking')) {
        capabilities.head_tracking.listen();
        this.set('head_tracking', capabilities.head_tracking);
      }
    }
    _this.check_timeout();

  },
  with_status: computed('eye_gaze.statuses', function() {
    return emberGet(capabilities.eye_gaze, 'statuses');
  }),
  check_timeout: function() {
    var _this = this;
    if(this.get('mouse_listener') || this.get('eye_listener') || this.get('head_listener') || this.get('gamepad_listener') || this.get('expression_listener')) {
      var now = (new Date()).getTime();
      var ts = this.get('ts');
      this.set('current_dwell', (ts && now - ts <= 2000));
      if(!this.get('current_dwell')) { this.set('pending', false); }
      runLater(function() { _this.check_timeout(); }, 100);
    }
  },
  willDestroyElement: function() {
    capabilities.eye_gaze.stop_listening();
    if(this.get('mouse_listener')) {
      $(document).off('mousemove', this.get('mouse_listener'));
      this.set('mouse_listener', null);
    }
    if(this.get('eye_listener')) {
      $(document).off('gazelinger', this.get('eye_listener'));
      this.set('eye_listener', null);
    }
    if(this.get('head_listener')) {
      $(document).off('headtilt', this.get('head_listener'));
      this.set('head_listener', null);
    }
    if(this.get('key_listener')) {
      $(document).off('keydown', this.get('key_listener'));
      this.set('key_listener', null);
    }
    if(this.get('gampead_listener')) {
      this.set('gamepad_listener', null);
    }
    if(this.get('keycode_listener')) {
      $(document).off('keypress', this.get('keycode_listener'));
      this.set('keycode_listener', null);
    }
    if(this.get('expression_listener')) {
      $(document).off('facechange', this.get('expression_listener'));
      this.set('expression_listener', null);
    }
  },
  actions: {
    advanced: function() {
      this.set('advanced', true);
    }
  }
});
<|endoftext|>


<commit_before>angular.module('generateTest').component('generateTest', {
    templateUrl: 'generate-test/generate-test.template.html',

    controller: ['$routeParams', '$firebaseObject', '$firebaseArray', function generateTestController($routeParams, $firebaseObject, $firebaseArray) {
        var self = this;
        self.studentName = $routeParams.name;
        self.classRef = firebase.database().ref().child("root/debug/class");
        n = new Date();
        y = n.getFullYear();
        m = n.getMonth() + 1;
        d = n.getDate();
        document.getElementById("generateDate").innerHTML = "Test Generated On: " + m + "/" + d + "/" + y;

        self.finalQuestions = [];
        self.numQuestionsMap = {}; // maps each category to the target number of questions

        self.questionsRef = self.classRef.child("questions");
        self.questionsObj = $firebaseObject(self.questionsRef);
        // self.categoriesRef = self.classRef.child("categories");
        // self.categoriesObj = $firebaseObject(self.categoriesRef);
        //
        self.studentsRef = self.classRef.child("students").child(self.studentName);
        self.studentsObj = $firebaseObject(self.studentsRef);

        // go through all categories for current student
        self.studentsObj.$loaded(
            function (studentData) {
                // choose questions
                var allKeys = Object.keys(studentData);
                var numCategories = 0;
                var sumGrades = 0;

                // sum up grades, find number of categories
                for (i = 0; i < allKeys.length; i++) {
                    if (allKeys[i].charAt(0) != '$') {
                        var categoryName = allKeys[i];
                        var grade = studentData[categoryName];
                        // console.log("Category Name", categoryName);
                        // console.log("Grade", grade);
                        numCategories++;
                        sumGrades += grade;
                    }
                }

                // calculate number of questions for each category
                for (i = 0; i < allKeys.length; i++) {
                    if (allKeys[i].charAt(0) != '$') {
                        categoryName = allKeys[i];
                        grade = studentData[categoryName];
                        // console.log("Category Name", categoryName);
                        // console.log("Grade", grade);
                        if (grade > 99) {
                            grade = grade - 1;
                        }
                        self.numQuestionsMap[categoryName] = (100 - grade) / ((100 * numCategories) - sumGrades);
                        // round number
                        self.numQuestionsMap[categoryName] = Math.round(self.numQuestionsMap[categoryName] * 10);
                    }
                }

                console.log("MAP", self.numQuestionsMap);

                var studentCategories = Object.keys(self.numQuestionsMap);
                for (i = 0; i < studentCategories.length; i++) {
                    var category = studentCategories[i];
                    var count = self.numQuestionsMap[studentCategories[i]];

                    // console.log("Category", category);
                    self.categoryRef = self.questionsRef.child(category);
                    // console.log("Category2", category);
                    var categoryObj = $firebaseObject(self.categoryRef);
                    console.log("CATEGORY", categoryObj);
                    categoryObj.$loaded(
                        function (categoryData) {
                            var possibleQuestions = Object.keys(categoryData);
                            console.log("COUNT", possibleQuestions);
                            console.log("category", category);
                            for (i = 0; i < possibleQuestions.length; i++) {
                                console.log("PUSH", possibleQuestions[i]);
                                if (possibleQuestions[i].charAt(0) != '$') {
                                    self.finalQuestions.push(possibleQuestions[i]);
                                }
                            }
                        },

                        function (error) {
                            console.error("Error:", error);
                        }
                    );

                }
            },
            function (error) {
                console.error("Error:", error);
            }
        );

    }]
});<commit_msg>OMG IT'S WORKING I CAN"T EVEN<commit_after>angular.module('generateTest').component('generateTest', {
    templateUrl: 'generate-test/generate-test.template.html',

    controller: ['$routeParams', '$firebaseObject', '$firebaseArray', function generateTestController($routeParams, $firebaseObject, $firebaseArray) {
        var self = this;
        self.studentName = $routeParams.name;
        self.classRef = firebase.database().ref().child("root/debug/class");
        n = new Date();
        y = n.getFullYear();
        m = n.getMonth() + 1;
        d = n.getDate();
        document.getElementById("generateDate").innerHTML = "Test Generated On: " + m + "/" + d + "/" + y;

        self.finalQuestions = [];
        self.numQuestionsMap = {}; // maps each category to the target number of questions

        self.questionsRef = self.classRef.child("questions");
        self.questionsObj = $firebaseObject(self.questionsRef);
        // self.categoriesRef = self.classRef.child("categories");
        // self.categoriesObj = $firebaseObject(self.categoriesRef);
        //
        self.studentsRef = self.classRef.child("students").child(self.studentName);
        self.studentsObj = $firebaseObject(self.studentsRef);

        // go through all categories for current student
        self.studentsObj.$loaded(
            function (studentData) {
                // choose questions
                var allKeys = Object.keys(studentData);
                var numCategories = 0;
                var sumGrades = 0;

                // sum up grades, find number of categories
                for (i = 0; i < allKeys.length; i++) {
                    if (allKeys[i].charAt(0) != '$') {
                        var categoryName = allKeys[i];
                        var grade = studentData[categoryName];
                        // console.log("Category Name", categoryName);
                        // console.log("Grade", grade);
                        numCategories++;
                        sumGrades += grade;
                    }
                }

                // calculate number of questions for each category
                for (i = 0; i < allKeys.length; i++) {
                    if (allKeys[i].charAt(0) != '$') {
                        categoryName = allKeys[i];
                        grade = studentData[categoryName];
                        // console.log("Category Name", categoryName);
                        // console.log("Grade", grade);
                        if (grade > 99) {
                            grade = grade - 1;
                        }
                        self.numQuestionsMap[categoryName] = (100 - grade) / ((100 * numCategories) - sumGrades);
                        // round number
                        self.numQuestionsMap[categoryName] = Math.round(self.numQuestionsMap[categoryName] * 10);
                    }
                }

                console.log("MAP", self.numQuestionsMap);

                var studentCategories = Object.keys(self.numQuestionsMap);
                for (i = 0; i < studentCategories.length; i++) {
                    var category = studentCategories[i];
                    var count = self.numQuestionsMap[studentCategories[i]];

                    // console.log("Category", category);
                    self.categoryRef = self.questionsRef.child(category);
                    // console.log("Category2", category);
                    var categoryObj = $firebaseObject(self.categoryRef);
                    // console.log("CATEGORY", categoryObj);
                    categoryObj.$loaded(
                        function (categoryData) {
                            var possibleQuestions = Object.keys(categoryData);
                            // console.log("COUNT", possibleQuestions);
                            // console.log("category", category);
                            var category = categoryData.$id;
                            // console.log("category", category);
                            var count = self.numQuestionsMap[category];
                            // console.log("count", count);
                            for (i = 0; i < possibleQuestions.length && i < count; i++) {
                                // console.log("PUSH", possibleQuestions[i]);
                                if (possibleQuestions[i].charAt(0) != '$') {
                                    self.finalQuestions.push(possibleQuestions[i]);
                                }
                            }
                        },

                        function (error) {
                            console.error("Error:", error);
                        }
                    );

                }
            },
            function (error) {
                console.error("Error:", error);
            }
        );

    }]
});<|endoftext|>


<commit_before>var ffmpeg = require('./ffmpeg')
var through2 = require('through2')
var TokenBucket = require('limiter').TokenBucket
var asciiPixels = require('ascii-pixels')
var ChopStream = require('chop-stream')
var charm = require('charm')

function ThrottleStream (chunksPerSecond) {
  var bucket = new TokenBucket(chunksPerSecond, chunksPerSecond, 'second', null)

  return through2(function (chunk, _, next) {
    bucket.removeTokens(1, function (err) {
      next(err, chunk)
    })
  })
}

function AsciiStream (frameWidth, frameHeight, options) {
  return through2(function (frameData, _, next) {
    var imageData = {
      data: frameData,
      width: frameWidth,
      height: frameHeight,
      format: 'RGB24'
    }

    // convert to ascii art
    var ascii = asciiPixels(imageData, options)

    next(null, ascii)
  })
}

function TerminalStream () {
  var term = charm(process)

  term.removeAllListeners('^C')
  term.on('^C', function () {
    term.cursor(true).end()
    process.exit()
  })

  term.reset()
  term.cursor(false)

  return through2(function (text, _, next) {
    var boldText = '\u001B[1m' + text + '\u001B[22m'
    term.erase('screen').position(0, 0).write(boldText)
    next(null)
  }).on('end', function () {
    term.cursor(true).end()
  })
}

// render video as ascii characters
module.exports = function (video, options) {
  // set the dimensions for the scaled video
  var frameWidth = Math.round(options.width)
  var frameHeight = Math.round(video.height / (video.width / frameWidth))
  var frameBytes = frameWidth * frameHeight * 3 // rgb24

  ffmpeg
    .rawImageStream(video.url, options)
    .pipe(new ChopStream(frameBytes))
    .pipe(new ThrottleStream(options.fps))
    .pipe(new AsciiStream(frameWidth, frameHeight, options))
    .pipe(new TerminalStream())
}
<commit_msg>fix bug: stream not ending<commit_after>var ffmpeg = require('./ffmpeg')
var through2 = require('through2')
var TokenBucket = require('limiter').TokenBucket
var asciiPixels = require('ascii-pixels')
var ChopStream = require('chop-stream')
var charm = require('charm')

function ThrottleStream (chunksPerSecond) {
  var bucket = new TokenBucket(chunksPerSecond, chunksPerSecond, 'second', null)

  return through2(function (chunk, _, next) {
    bucket.removeTokens(1, function (err) {
      next(err, chunk)
    })
  })
}

function AsciiStream (frameWidth, frameHeight, options) {
  return through2(function (frameData, _, next) {
    var imageData = {
      data: frameData,
      width: frameWidth,
      height: frameHeight,
      format: 'RGB24'
    }

    // convert to ascii art
    var ascii = asciiPixels(imageData, options)

    next(null, ascii)
  })
}

function TerminalStream () {
  var term = charm(process)

  term.removeAllListeners('^C')
  term.on('^C', function () {
    term.cursor(true).end()
    process.exit()
  })

  term.reset()
  term.cursor(false)

  return through2(function (text, _, next) {
    var boldText = '\u001B[1m' + text + '\u001B[22m'
    term.erase('screen').position(0, 0).write(boldText)
    next()
  }).on('end', function () {
    term.cursor(true).end()
  })
}

// render video as ascii characters
module.exports = function (video, options) {
  // set the dimensions for the scaled video
  var frameWidth = Math.round(options.width)
  var frameHeight = Math.round(video.height / (video.width / frameWidth))
  var frameBytes = frameWidth * frameHeight * 3 // rgb24

  ffmpeg
    .rawImageStream(video.url, options)
    .pipe(new ChopStream(frameBytes))
    .pipe(new ThrottleStream(options.fps))
    .pipe(new AsciiStream(frameWidth, frameHeight, options))
    .pipe(new TerminalStream())
    .resume() // TODO: makes TerminalStream end (should probably be a writable/output stream instead)
}
<|endoftext|>


<commit_before>var EventEmitter2 = require('eventemitter2').EventEmitter2;
var _ = require('lodash');

var AssetLoader = function(params) {
	EventEmitter2.apply(this, arguments);
	AssetLoader.prototype.init.apply(this, arguments);
};

var proto = AssetLoader.prototype = Object.create(EventEmitter2.prototype, {
	constructor: {
		configurable: true,
		enumerable: true,
		value: AssetLoader,
		writable: true
	}
});

proto.init = function(param) {
	param = param || {};
	this.success = 0;
	this.failure = 0;
	this.queue = [];
	this.resources = {};
	this.baseUrl = param.baseUrl || '/';
};

proto.push = function(fileUrl) {
	var idx = this.queue.indexOf(fileUrl);
	if (idx < 0) {
		this.queue.push(fileUrl);
	}
};

proto.start = function() {
	this.queue.forEach(function(fileUrl, index){
		var url = fileUrl[0] === '/' ? fileUrl : this.baseUrl + fileUrl;
		var xhr = new XMLHttpRequest();
		xhr.open('GET', url, true);
		xhr.responseType = 'blob';
		xhr.onload = this.onload.bind(this, fileUrl, xhr);
		xhr.onerror = this.onerror.bind(this, fileUrl, xhr);
		xhr.send();
	}.bind(this));
};

proto.onerror = function(fileUrl, e) {
	var xhr = e.target;
	this.failure += 1;
};

proto.onload = function(fileUrl, e) {
	var xhr = e.target;
	if (xhr.status === 200) {
		var blob = new Blob([xhr.response], {type: xhr.response.type});
		this.success += 1;
		this.resources[fileUrl] = blob;
	}
};

module.exports = AssetLoader;<commit_msg>404 handler<commit_after>var EventEmitter2 = require('eventemitter2').EventEmitter2;
var _ = require('lodash');

var AssetLoader = function(params) {
	EventEmitter2.apply(this, arguments);
	AssetLoader.prototype.init.apply(this, arguments);
};

var proto = AssetLoader.prototype = Object.create(EventEmitter2.prototype, {
	constructor: {
		configurable: true,
		enumerable: true,
		value: AssetLoader,
		writable: true
	}
});

proto.init = function(param) {
	param = param || {};
	this.success = 0;
	this.failure = 0;
	this.queue = [];
	this.resources = {};
	this.baseUrl = param.baseUrl || '/';
};

proto.push = function(fileUrl) {
	var idx = this.queue.indexOf(fileUrl);
	if (idx < 0) {
		this.queue.push(fileUrl);
	}
};

proto.start = function() {
	this.queue.forEach(function(fileUrl, index){
		var url = fileUrl[0] === '/' ? fileUrl : this.baseUrl + fileUrl;
		var xhr = new XMLHttpRequest();
		xhr.open('GET', url, true);
		xhr.responseType = 'blob';
		xhr.onload = this.onload.bind(this, fileUrl, xhr);
		xhr.onerror = this.onerror.bind(this, fileUrl, xhr);
		xhr.send();
	}.bind(this));
};

proto.onerror = function(fileUrl, e) {
	var xhr = e.target;
	this.failure += 1;
};

proto.onload = function(fileUrl, e) {
	var xhr = e.target;
	if (xhr.status === 200) {
		var blob = new Blob([xhr.response], {type: xhr.response.type});
		this.success += 1;
		this.resources[fileUrl] = blob;
	} else if (xhr.status === 404) {
		this.failure += 1;
	}
};

module.exports = AssetLoader;<|endoftext|>


<commit_before>// This code is largely borrowed from:
// https://github.com/missive/emoji-mart/blob/bbd4fbe/src/utils/emoji-index.js

import data from './emoji_data_light';
import { getData, getSanitizedData, intersect } from './emoji_utils';

let index = {};
let emojisList = {};
let emoticonsList = {};
let previousInclude = [];
let previousExclude = [];

for (let emoji in data.emojis) {
  let emojiData = data.emojis[emoji],
    { short_names, emoticons } = emojiData,
    id = short_names[0];

  for (let emoticon of (emoticons || [])) {
    if (!emoticonsList[emoticon]) {
      emoticonsList[emoticon] = id;
    }
  }

  emojisList[id] = getSanitizedData(id);
}

function search(value, { emojisToShowFilter, maxResults, include, exclude, custom = [] } = {}) {
  maxResults = maxResults || 75;
  include = include || [];
  exclude = exclude || [];

  if (custom.length) {
    for (const emoji of custom) {
      data.emojis[emoji.id] = getData(emoji);
      emojisList[emoji.id] = getSanitizedData(emoji);
    }

    data.categories.push({
      name: 'Custom',
      emojis: custom.map(emoji => emoji.id),
    });
  }

  let results = null;
  let pool = data.emojis;

  if (value.length) {
    if (value === '-' || value === '-1') {
      return [emojisList['-1']];
    }

    let values = value.toLowerCase().split(/[\s|,|\-|_]+/);

    if (values.length > 2) {
      values = [values[0], values[1]];
    }

    if (include.length || exclude.length) {
      pool = {};

      if (previousInclude !== include.sort().join(',') || previousExclude !== exclude.sort().join(',')) {
        previousInclude = include.sort().join(',');
        previousExclude = exclude.sort().join(',');
        index = {};
      }

      for (let category of data.categories) {
        let isIncluded = include && include.length ? include.indexOf(category.name.toLowerCase()) > -1 : true;
        let isExcluded = exclude && exclude.length ? exclude.indexOf(category.name.toLowerCase()) > -1 : false;
        if (!isIncluded || isExcluded) {
          continue;
        }

        for (let emojiId of category.emojis) {
          pool[emojiId] = data.emojis[emojiId];
        }
      }
    } else if (previousInclude.length || previousExclude.length) {
      index = {};
    }

    let allResults = values.map((value) => {
      let aPool = pool;
      let aIndex = index;
      let length = 0;

      for (let char of value.split('')) {
        length++;

        aIndex[char] = aIndex[char] || {};
        aIndex = aIndex[char];

        if (!aIndex.results) {
          let scores = {};

          aIndex.results = [];
          aIndex.pool = {};

          for (let id in aPool) {
            let emoji = aPool[id],
              { search } = emoji,
              sub = value.substr(0, length),
              subIndex = search.indexOf(sub);

            if (subIndex !== -1) {
              let score = subIndex + 1;
              if (sub === id) {
                score = 0;
              }

              aIndex.results.push(emojisList[id]);
              aIndex.pool[id] = emoji;

              scores[id] = score;
            }
          }

          aIndex.results.sort((a, b) => {
            let aScore = scores[a.id],
              bScore = scores[b.id];

            return aScore - bScore;
          });
        }

        aPool = aIndex.pool;
      }

      return aIndex.results;
    }).filter(a => a);

    if (allResults.length > 1) {
      results = intersect(...allResults);
    } else if (allResults.length) {
      results = allResults[0];
    } else {
      results = [];
    }
  }

  if (results) {
    if (emojisToShowFilter) {
      results = results.filter((result) => emojisToShowFilter(data.emojis[result.id].unified));
    }

    if (results && results.length > maxResults) {
      results = results.slice(0, maxResults);
    }
  }

  return results;
}

export { search };
<commit_msg>Make underscore not to work as splitter in searching<commit_after>// This code is largely borrowed from:
// https://github.com/missive/emoji-mart/blob/bbd4fbe/src/utils/emoji-index.js

import data from './emoji_data_light';
import { getData, getSanitizedData, intersect } from './emoji_utils';

let index = {};
let emojisList = {};
let emoticonsList = {};
let previousInclude = [];
let previousExclude = [];

for (let emoji in data.emojis) {
  let emojiData = data.emojis[emoji],
    { short_names, emoticons } = emojiData,
    id = short_names[0];

  for (let emoticon of (emoticons || [])) {
    if (!emoticonsList[emoticon]) {
      emoticonsList[emoticon] = id;
    }
  }

  emojisList[id] = getSanitizedData(id);
}

function search(value, { emojisToShowFilter, maxResults, include, exclude, custom = [] } = {}) {
  maxResults = maxResults || 75;
  include = include || [];
  exclude = exclude || [];

  if (custom.length) {
    for (const emoji of custom) {
      data.emojis[emoji.id] = getData(emoji);
      emojisList[emoji.id] = getSanitizedData(emoji);
    }

    data.categories.push({
      name: 'Custom',
      emojis: custom.map(emoji => emoji.id),
    });
  }

  let results = null;
  let pool = data.emojis;

  if (value.length) {
    if (value === '-' || value === '-1') {
      return [emojisList['-1']];
    }

    let values = value.toLowerCase().split(/[\s|,|\-]+/);

    if (values.length > 2) {
      values = [values[0], values[1]];
    }

    if (include.length || exclude.length) {
      pool = {};

      if (previousInclude !== include.sort().join(',') || previousExclude !== exclude.sort().join(',')) {
        previousInclude = include.sort().join(',');
        previousExclude = exclude.sort().join(',');
        index = {};
      }

      for (let category of data.categories) {
        let isIncluded = include && include.length ? include.indexOf(category.name.toLowerCase()) > -1 : true;
        let isExcluded = exclude && exclude.length ? exclude.indexOf(category.name.toLowerCase()) > -1 : false;
        if (!isIncluded || isExcluded) {
          continue;
        }

        for (let emojiId of category.emojis) {
          pool[emojiId] = data.emojis[emojiId];
        }
      }
    } else if (previousInclude.length || previousExclude.length) {
      index = {};
    }

    let allResults = values.map((value) => {
      let aPool = pool;
      let aIndex = index;
      let length = 0;

      for (let char of value.split('')) {
        length++;

        aIndex[char] = aIndex[char] || {};
        aIndex = aIndex[char];

        if (!aIndex.results) {
          let scores = {};

          aIndex.results = [];
          aIndex.pool = {};

          for (let id in aPool) {
            let emoji = aPool[id],
              { search } = emoji,
              sub = value.substr(0, length),
              subIndex = search.indexOf(sub);

            if (subIndex !== -1) {
              let score = subIndex + 1;
              if (sub === id) {
                score = 0;
              }

              aIndex.results.push(emojisList[id]);
              aIndex.pool[id] = emoji;

              scores[id] = score;
            }
          }

          aIndex.results.sort((a, b) => {
            let aScore = scores[a.id],
              bScore = scores[b.id];

            return aScore - bScore;
          });
        }

        aPool = aIndex.pool;
      }

      return aIndex.results;
    }).filter(a => a);

    if (allResults.length > 1) {
      results = intersect(...allResults);
    } else if (allResults.length) {
      results = allResults[0];
    } else {
      results = [];
    }
  }

  if (results) {
    if (emojisToShowFilter) {
      results = results.filter((result) => emojisToShowFilter(data.emojis[result.id].unified));
    }

    if (results && results.length > maxResults) {
      results = results.slice(0, maxResults);
    }
  }

  return results;
}

export { search };
<|endoftext|>