<commit_before>var express = require('express');
var request = require('request');
var router = express.Router();

var MongoClient = require('mongodb').MongoClient,
	assert = require('assert');

var url = 'mongodb://localhost:27017/test';

router.get('/games/:id', function(req, res) {
	MongoClient.connect(url, function(err, db) {
		var gamesCollection = db.collection("games");
		gamesCollection.find({id: req.params.id}).toArray().then(function(results) {
			res.json(results[0]);
			db.close();
		});
	});
});

router.get("/seasons/:id", function(req, res) {
	MongoClient.connect(url, function(err, db) {
		var gamesCollection = db.collection("games");
		gamesCollection.find({season: req.params.id}, {id: 1, displayName: 1}).toArray().then(function(results) {
			var transformedResults = {}; // transform the data for easier construction of the state on the client
			results.forEach(function(result) {
				transformedResults[result.id] = {
					displayName: result.displayName
				};
			});
			res.json({
				status: "ok",
				games: transformedResults
			})
			db.close();
		});
	});
});

router.get("/", function(req, res) {
	MongoClient.connect(url, function(err, db) {
		var seasonsCollection = db.collection("seasons");
		seasonsCollection.find({}).sort({sortNumber: -1}).toArray().then(function(result){
			res.json({
				"status": "ok",
				seasons: result
			});
			db.close();
		});

	});

});

module.exports = router;<commit_msg>Endpoints to save disputes to the db<commit_after>var express = require('express');
var request = require('request');
var router = express.Router();

var MongoClient = require('mongodb').MongoClient,
	assert = require('assert');

var url = 'mongodb://localhost:27017/test';

router.get('/games/:id', function(req, res) {
	MongoClient.connect(url, function(err, db) {
		var gamesCollection = db.collection("games");
		gamesCollection.find({id: req.params.id}).toArray().then(function(results) {
			res.json(results[0]);
			db.close();
		});
	});
});

router.get("/seasons/:id", function(req, res) {
	MongoClient.connect(url, function(err, db) {
		var gamesCollection = db.collection("games");
		gamesCollection.find({season: req.params.id}, {id: 1, displayName: 1}).toArray().then(function(results) {
			var transformedResults = {}; // transform the data for easier construction of the state on the client
			results.forEach(function(result) {
				transformedResults[result.id] = {
					displayName: result.displayName
				};
			});
			res.json({
				status: "ok",
				games: transformedResults
			})
			db.close();
		});
	});
});

router.get("/", function(req, res) {
	MongoClient.connect(url, function(err, db) {
		var seasonsCollection = db.collection("seasons");
		seasonsCollection.find({}).sort({sortNumber: -1}).toArray().then(function(result){
			res.json({
				"status": "ok",
				seasons: result
			});
			db.close();
		});

	});

});

router.post("/dispute", function(req, res) {

	MongoClient.connect(url, function(err, db) {
		var disputeData = JSON.parse(Object.keys(req.body)[0]); //no idea why it formats it as {JSONBODY: ""} when posting JSON via fetch
		var disputeCollection = db.collection("disputes")
		disputeCollection.insert(disputeData).then(function(err, result) {
			res.json({
				"status": "ok"
			});
			db.close();
		});
	});

});

module.exports = router;<|endoftext|>


<commit_before>function onHover(thisBtn) {
	 var img= $(thisBtn).attr('src');
//    $("#"+img).attr('src', 'image/'+img+'_hover.png');
    $(thisBtn).attr('src', img.replace('.png','_hover.png'));
 }

 function offHover(thisBtn) {
	 var img= $(thisBtn).attr('src');
//    $("#"+img).attr('src', 'image/'+img+'.png');
    $(thisBtn).attr('src', img.replace('_hover.png','.png'));
 }

 function popupItemInfo() {
 openItemInfoPane();
 showItemInfo(this);
}

   // Go to Help docs.
  function openKnetHelpPage() {
   var helpURL = 'https://github.com/Rothamsted/knetmaps.js/wiki/KnetMaps.js';
   window.open(helpURL, '_blank');
  }

  // Reset: Re-position the network graph.
  function resetGraph() {
   $('#cy').cytoscape('get').reset().fit(); // reset the graph's zooming & panning properties.
  }

 // Export the graph as a JSON object in a new Tab and allow users to save it.
  function exportAsJson() {
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`

   var exportJson= cy.json(); // get JSON object for the network graph.

   // Display in a new blank browser tab, e.g, window.open().document.write("text"); // for text data
//   window.open('data:application/json;' + (window.btoa?'base64,'+btoa(JSON.stringify(exportJson)):JSON.stringify(exportJson))); // for JSON data

   // use FileSaver.js to save using file downloader
 //  var kNet_json_Blob= new Blob([JSON.stringify(exportJson)], {type: "text/plain;charset=utf-8"});
 //  saveAs(kNet_json_Blob, "kNetwork.cyjs.json");
   var kNet_json= new File([JSON.stringify(exportJson)], "kNetwork.cyjs.json", {type: "text/plain;charset=utf-8"});
   saveAs(kNet_json);
  }

  // Export the graph as a .png image and allow users to save it.
  function exportAsImage() {
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`

   // Export as .png image
   var png64= cy.png(); // .setAttribute('crossOrigin', 'anonymous');

   // Display the exported image in a new window.
   //window.open(png64, 'Image', 'width=1200px,height=600px,resizable=1'); // Blocked on some browsers

   // use FileSaver.js to save using file downloader; fails (creates corrupted png)
   /*cy_image= new Image();
   cy_image.src= png64;
   var knet_canvas= document.getElementById('cy'); // use canvas
   knet_context= knet_canvas.getContext('2d');
   knet_context.drawImage(cy_image, 0,0); // draw image on canvas
   // convert canvas to Blob & save using FileSaver.js.
   knet_canvas.toBlob(function(blob) {
     saveAs(knet_blob, "kNetwork.png");
     }, "image/png");*/

   // Use IFrame to open png image in a new browser tab
   var cy_width= $('#cy').width();
   var cy_height= $('#cy').height();
   var knet_iframe_style= "border:1px solid black; top:0px; left:0px; bottom:0px; right:0px; width:"+ cy_width +"; height:"+ cy_height +";";
   var knet_iframe = '';
   var pngTab= window.open();
   pngTab.document.open();
   pngTab.document.write(knet_iframe);
   pngTab.document.title="kNetwork_png";
   pngTab.document.close();
  }

  // Remove hidden effect from nodes/ edges, if hidden.
/*  function removeHiddenEffect(ele) {
    var thisElement= ele;
    try {
      if(thisElement.hasClass('HideEle')) {
         thisElement.removeClass('HideEle');
        }
     }
    catch(err) {
          console.log("Error occurred while unhiding concepts/ relations. \n"+"Error Details: "+ err.stack);
         }
  }*/

  // Show all concepts & relations.
  function showAll() {
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`
//   cy.elements('node').show(); // show all nodes using eles.show().
//   cy.elements('edge').show(); // show all edges using eles.show().
   cy.elements().removeClass('HideEle');
   cy.elements().addClass('ShowEle');

   // Relayout the graph.
   rerunLayout();

   // Remove shadows around nodes, if any.
   cy.nodes().forEach(function( ele ) {
       removeNodeBlur(ele);
      });

   // Refresh network legend.
   updateKnetStats();
  }

  // Re-run the entire graph's layout.
  function rerunLayout() {
   //console.log("rerunLayout...");
   // Get the cytoscape instance as a Javascript object from JQuery.
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`
   var selected_elements= cy.$(':visible'); // get only the visible elements.

   // Re-run the graph's layout, but only on the visible elements.
   rerunGraphLayout(selected_elements);

   // Reset the graph/ viewport.
   resetGraph();
  }

  // Re-run the graph's layout, but only on the visible elements.
  function rerunGraphLayout(eles) {
   //  var ld= document.getElementById("layouts_dropdown");
   var ld_selected= /*ld.options[ld.selectedIndex].value*/$('#layouts_dropdown').val();
   //console.log("layouts_dropdown selectedOption: "+ ld_selected)
   if(ld_selected === "circle_layout") {
           setCircleLayout(eles);
          }
   else if(ld_selected === "cose_layout") {
           setCoseLayout(eles);
          }
   else if(ld_selected === "coseBilkent_layout") {
           setCoseBilkentLayout(eles);
          }
   else if(ld_selected === "concentric_layout") {
           setConcentricLayout(eles);
          }
   else if(ld_selected === "ngraph_force_layout") {
           setNgraphForceLayout(eles);
          }
   else if(ld_selected === "euler_layout") {
           setEulerLayout(eles);
          }
   else if(ld_selected === "random_layout") {
           setRandomLayout(eles);
          }
   //console.log("Re-run layout complete...");
  }

  // Update the label font size for all the concepts and relations.
  function changeLabelFontSize(new_size) {
   try {
     var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`
     console.log("changeLabelFontSize>> new_size: "+ new_size);
     cy.style().selector('node').css({ 'font-size': new_size }).update();
     cy.style().selector('edge').css({ 'font-size': new_size }).update();
    }
   catch(err) {
          console.log("Error occurred while altering label font size. \n"+"Error Details: "+ err.stack);
         }
  }

  // Show/ Hide labels for concepts and relations.
  function showHideLabels(val) {
   //console.log("cy.hideLabelsOnViewport= "+ $('#cy').cytoscape('get').hideLabelsOnViewport);
   if(val === "Concepts") {
      displayConceptLabels();
     }
   else if(val === "Relations") {
      displayRelationLabels();
     }
   else if(val === "Both") {
      displayConRelLabels();
     }
   else if(val === "None") {
      hideConRelLabels();
     }
  }

  // Show node labels.
  function displayConceptLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '1'});
//   cy.edges().style({'text-opacity': '0'});
   cy.nodes().removeClass("LabelOff").addClass("LabelOn");
   cy.edges().removeClass("LabelOn").addClass("LabelOff");
  }

  // Show edge labels.
  function displayRelationLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '0'});
//   cy.edges().style({'text-opacity': '1'});
   cy.nodes().removeClass("LabelOn").addClass("LabelOff");
   cy.edges().removeClass("LabelOff").addClass("LabelOn");
  }

  // Show node & edge labels.
  function displayConRelLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '1'});
//   cy.edges().style({'text-opacity': '1'});
   cy.nodes().removeClass("LabelOff").addClass("LabelOn");
   cy.edges().removeClass("LabelOff").addClass("LabelOn");
  }

  // Show node labels.
  function hideConRelLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '0'});
//   cy.edges().style({'text-opacity': '0'});
   cy.nodes().removeClass("LabelOn").addClass("LabelOff");
   cy.edges().removeClass("LabelOn").addClass("LabelOff");
  }
<commit_msg>json fileSaver<commit_after>function onHover(thisBtn) {
	 var img= $(thisBtn).attr('src');
//    $("#"+img).attr('src', 'image/'+img+'_hover.png');
    $(thisBtn).attr('src', img.replace('.png','_hover.png'));
 }

 function offHover(thisBtn) {
	 var img= $(thisBtn).attr('src');
//    $("#"+img).attr('src', 'image/'+img+'.png');
    $(thisBtn).attr('src', img.replace('_hover.png','.png'));
 }

 function popupItemInfo() {
 openItemInfoPane();
 showItemInfo(this);
}

   // Go to Help docs.
  function openKnetHelpPage() {
   var helpURL = 'https://github.com/Rothamsted/knetmaps.js/wiki/KnetMaps.js';
   window.open(helpURL, '_blank');
  }

  // Reset: Re-position the network graph.
  function resetGraph() {
   $('#cy').cytoscape('get').reset().fit(); // reset the graph's zooming & panning properties.
  }

 // Export the graph as a JSON object in a new Tab and allow users to save it.
  function exportAsJson() {
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`

   var exportJson= cy.json(); // get JSON object for the network graph.
   console.log("Save network JSON as: kNetwork.cyjs.json");

   // Display in a new blank browser tab, e.g, window.open().document.write("text"); // for text data
//   window.open('data:application/json;' + (window.btoa?'base64,'+btoa(JSON.stringify(exportJson)):JSON.stringify(exportJson))); // for JSON data

   // use FileSaver.js to save using file downloader
 //  var kNet_json_Blob= new Blob([JSON.stringify(exportJson)], {type: "text/plain;charset=utf-8"});
 //  saveAs(kNet_json_Blob, "kNetwork.cyjs.json");
   var kNet_json= new File([JSON.stringify(exportJson)], "kNetwork.cyjs.json", {type: "text/plain;charset=utf-8"});
   //saveAs(kNet_json);
   saveAs(kNet_json, "kNetwork.cyjs.json");
  }

  // Export the graph as a .png image and allow users to save it.
  function exportAsImage() {
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`

   // Export as .png image
   var png64= cy.png(); // .setAttribute('crossOrigin', 'anonymous');
   console.log("Export network PNG as: kNetwork.png");

   // Display the exported image in a new window.
   //window.open(png64, 'Image', 'width=1200px,height=600px,resizable=1'); // Blocked on some browsers

   // use FileSaver.js to save using file downloader; fails (creates corrupted png)
   /*cy_image= new Image();
   cy_image.src= png64;
   var knet_canvas= document.getElementById('cy'); // use canvas
   knet_context= knet_canvas.getContext('2d');
   knet_context.drawImage(cy_image, 0,0); // draw image on canvas
   // convert canvas to Blob & save using FileSaver.js.
   knet_canvas.toBlob(function(blob) {
     saveAs(knet_blob, "kNetwork.png");
     }, "image/png");*/

   // Use IFrame to open png image in a new browser tab
   var cy_width= $('#cy').width();
   var cy_height= $('#cy').height();
   var knet_iframe_style= "border:1px solid black; top:0px; left:0px; bottom:0px; right:0px; width:"+ cy_width +"; height:"+ cy_height +";";
   var knet_iframe = '';
   var pngTab= window.open();
   pngTab.document.open();
   pngTab.document.write(knet_iframe);
   pngTab.document.title="kNetwork_png";
   pngTab.document.close();
  }

  // Remove hidden effect from nodes/ edges, if hidden.
/*  function removeHiddenEffect(ele) {
    var thisElement= ele;
    try {
      if(thisElement.hasClass('HideEle')) {
         thisElement.removeClass('HideEle');
        }
     }
    catch(err) {
          console.log("Error occurred while unhiding concepts/ relations. \n"+"Error Details: "+ err.stack);
         }
  }*/

  // Show all concepts & relations.
  function showAll() {
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`
//   cy.elements('node').show(); // show all nodes using eles.show().
//   cy.elements('edge').show(); // show all edges using eles.show().
   cy.elements().removeClass('HideEle');
   cy.elements().addClass('ShowEle');

   // Relayout the graph.
   rerunLayout();

   // Remove shadows around nodes, if any.
   cy.nodes().forEach(function( ele ) {
       removeNodeBlur(ele);
      });

   // Refresh network legend.
   updateKnetStats();
  }

  // Re-run the entire graph's layout.
  function rerunLayout() {
   //console.log("rerunLayout...");
   // Get the cytoscape instance as a Javascript object from JQuery.
   var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`
   var selected_elements= cy.$(':visible'); // get only the visible elements.

   // Re-run the graph's layout, but only on the visible elements.
   rerunGraphLayout(selected_elements);

   // Reset the graph/ viewport.
   resetGraph();
  }

  // Re-run the graph's layout, but only on the visible elements.
  function rerunGraphLayout(eles) {
   //  var ld= document.getElementById("layouts_dropdown");
   var ld_selected= /*ld.options[ld.selectedIndex].value*/$('#layouts_dropdown').val();
   //console.log("layouts_dropdown selectedOption: "+ ld_selected)
   if(ld_selected === "circle_layout") {
           setCircleLayout(eles);
          }
   else if(ld_selected === "cose_layout") {
           setCoseLayout(eles);
          }
   else if(ld_selected === "coseBilkent_layout") {
           setCoseBilkentLayout(eles);
          }
   else if(ld_selected === "concentric_layout") {
           setConcentricLayout(eles);
          }
   else if(ld_selected === "ngraph_force_layout") {
           setNgraphForceLayout(eles);
          }
   else if(ld_selected === "euler_layout") {
           setEulerLayout(eles);
          }
   else if(ld_selected === "random_layout") {
           setRandomLayout(eles);
          }
   //console.log("Re-run layout complete...");
  }

  // Update the label font size for all the concepts and relations.
  function changeLabelFontSize(new_size) {
   try {
     var cy= $('#cy').cytoscape('get'); // now we have a global reference to `cy`
     console.log("changeLabelFontSize>> new_size: "+ new_size);
     cy.style().selector('node').css({ 'font-size': new_size }).update();
     cy.style().selector('edge').css({ 'font-size': new_size }).update();
    }
   catch(err) {
          console.log("Error occurred while altering label font size. \n"+"Error Details: "+ err.stack);
         }
  }

  // Show/ Hide labels for concepts and relations.
  function showHideLabels(val) {
   //console.log("cy.hideLabelsOnViewport= "+ $('#cy').cytoscape('get').hideLabelsOnViewport);
   if(val === "Concepts") {
      displayConceptLabels();
     }
   else if(val === "Relations") {
      displayRelationLabels();
     }
   else if(val === "Both") {
      displayConRelLabels();
     }
   else if(val === "None") {
      hideConRelLabels();
     }
  }

  // Show node labels.
  function displayConceptLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '1'});
//   cy.edges().style({'text-opacity': '0'});
   cy.nodes().removeClass("LabelOff").addClass("LabelOn");
   cy.edges().removeClass("LabelOn").addClass("LabelOff");
  }

  // Show edge labels.
  function displayRelationLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '0'});
//   cy.edges().style({'text-opacity': '1'});
   cy.nodes().removeClass("LabelOn").addClass("LabelOff");
   cy.edges().removeClass("LabelOff").addClass("LabelOn");
  }

  // Show node & edge labels.
  function displayConRelLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '1'});
//   cy.edges().style({'text-opacity': '1'});
   cy.nodes().removeClass("LabelOff").addClass("LabelOn");
   cy.edges().removeClass("LabelOff").addClass("LabelOn");
  }

  // Show node labels.
  function hideConRelLabels() {
   var cy= $('#cy').cytoscape('get'); // reference to `cy`
//   cy.nodes().style({'text-opacity': '0'});
//   cy.edges().style({'text-opacity': '0'});
   cy.nodes().removeClass("LabelOn").addClass("LabelOff");
   cy.edges().removeClass("LabelOn").addClass("LabelOff");
  }
<|endoftext|>


<commit_before>/*
 * Ahoy.js
 * Simple, powerful JavaScript analytics
 * https://github.com/ankane/ahoy.js
 * v0.1.0
 * MIT License
 */

/*jslint browser: true, indent: 2, plusplus: true, vars: true */

(function (window) {
  "use strict";

  var ahoy = window.ahoy || window.Ahoy || {};
  var $ = window.jQuery || window.Zepto || window.$;
  var visitId, visitorId, track;
  var visitTtl = 4 * 60; // 4 hours
  var visitorTtl = 2 * 365 * 24 * 60; // 2 years
  var isReady = false;
  var queue = [];
  var canStringify = typeof(JSON) !== "undefined" && typeof(JSON.stringify) !== "undefined";
  var eventQueue = [];
  var page = ahoy.page || window.location.pathname;
  var visitsUrl = ahoy.visitsUrl || "/ahoy/visits"
  var eventsUrl = ahoy.eventsUrl || "/ahoy/events"

  // cookies

  // http://www.quirksmode.org/js/cookies.html
  function setCookie(name, value, ttl) {
    var expires = "";
    var cookieDomain = "";
    if (ttl) {
      var date = new Date();
      date.setTime(date.getTime() + (ttl * 60 * 1000));
      expires = "; expires=" + date.toGMTString();
    }
    if (ahoy.domain) {
      cookieDomain = "; domain=" + ahoy.domain;
    }
    console.log("I'M SETTING COOKIE-- \nname: " + name + "\nval: " + value + "\nttl: " + ttl + "\ncookie domain: " + cookieDomain )
    document.cookie = name + "=" + escape(value) + expires + cookieDomain + "; path=/";
  }

  function getCookie(name) {
    var i, c;
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (i = 0; i < ca.length; i++) {
      c = ca[i];
      while (c.charAt(0) === ' ') {
        c = c.substring(1, c.length);
      }
      if (c.indexOf(nameEQ) === 0) {
        return unescape(c.substring(nameEQ.length, c.length));
      }
    }
    return null;
  }

  function destroyCookie(name) {
    setCookie(name, "", -1);
  }

  function log(message) {
    if (getCookie("ahoy_debug")) {
      window.console.log(message);
    }
  }

  function setReady() {
    var callback;
    while (callback = queue.shift()) {
      callback();
    }
    isReady = true;
  }

  function ready(callback) {
    if (isReady) {
      callback();
    } else {
      queue.push(callback);
    }
  }

  // http://stackoverflow.com/a/2117523/1177228
  function generateId() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
      return v.toString(16);
    });
  }

  function saveEventQueue() {
    // TODO add stringify method for IE 7 and under
    if (canStringify) {
      setCookie("ahoy_events", JSON.stringify(eventQueue), 1);
    }
  }

  function trackEvent(event) {
    ready( function () {
      // ensure JSON is defined
      if (canStringify) {
        $.ajax({
          type: "POST",
          url: eventsUrl,
          data: JSON.stringify([event]),
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          success: function() {
            // remove from queue
            for (var i = 0; i < eventQueue.length; i++) {
              if (eventQueue[i].id == event.id) {
                eventQueue.splice(i, 1);
                break;
              }
            }
            saveEventQueue();
          }
        });
      }
    });
  }

  function eventProperties(e) {
    var $target = $(e.currentTarget);
    return {
      tag: $target.get(0).tagName.toLowerCase(),
      id: $target.attr("id"),
      "class": $target.attr("class"),
      page: page,
      section: $target.closest("*[data-section]").data("section")
    };
  }

  // main

  visitId = getCookie("visit");
  visitorId = getCookie("visitor");
  track = getCookie("ahoy_track");

  if (visitId && visitorId && !track) {
    // TODO keep visit alive?
    log("Active visit");
    setReady();
  } else {
    if (track) {
      destroyCookie("ahoy_track");
    }

    if (!visitId) {
      visitId = generateId();
      setCookie("visit", visitId, visitTtl);
    }

    // make sure cookies are enabled
    if (getCookie("visit")) {
      log("Visit started");

      if (!visitorId) {
        visitorId = generateId();
        setCookie("visitor", visitorId, visitorTtl);
      }

      var data = {
        visit_token: visitId,
        visitor_token: visitorId,
        platform: ahoy.platform || "Web",
        landing_page: window.location.href,
        screen_width: window.screen.width,
        screen_height: window.screen.height
      };

      // referrer
      if (document.referrer.length > 0) {
        data.referrer = document.referrer;
      }

      log(data);

      $.post(visitsUrl, data, setReady, "json");
    } else {
      log("Cookies disabled");
      setReady();
    }
  }

  ahoy.getVisitId = ahoy.getVisitToken = function () {
    return visitId;
  };

  ahoy.getVisitorId = ahoy.getVisitorToken = function () {
    return visitorId;
  };

  ahoy.reset = function () {
    destroyCookie("visit");
    destroyCookie("visitor");
    destroyCookie("ahoy_events");
    destroyCookie("ahoy_track");
    return true;
  };

  ahoy.debug = function (enabled) {
    if (enabled === false) {
      destroyCookie("ahoy_debug");
    } else {
      setCookie("ahoy_debug", "t", 365 * 24 * 60); // 1 year
    }
    return true;
  };

  ahoy.track = function (name, properties) {
    // generate unique id
    var event = {
      id: generateId(),
      name: name,
      properties: properties
    };
    log(event);

    eventQueue.push(event);
    saveEventQueue();

    // wait in case navigating to reduce duplicate events
    setTimeout( function () {
      trackEvent(event);
    }, 1000);
  };

  ahoy.trackView = function(extraProperties) {
    var properties = {
      url: window.location.href,
      title: document.title,
      page: page
    };

    if(typeof(extraProperties) == "object") {
      $.extend(properties, extraProperties);
    }

    ahoy.track("$view", properties);
  };

  ahoy.trackClicks = function () {
    $(document).on("click", "a, button, input[type=submit]", function (e) {
      var $target = $(e.currentTarget);
      var properties = eventProperties(e);
      properties.text = properties.tag == "input" ? $target.val() : $.trim($target.text().replace(/[\s\r\n]+/g, " "));
      properties.href = $target.attr("href");
      ahoy.track("$click", properties);
    });
  };

  ahoy.trackSubmits = function () {
    $(document).on("submit", "form", function (e) {
      var properties = eventProperties(e);
      ahoy.track("$submit", properties);
    });
  };

  ahoy.trackChanges = function () {
    $(document).on("change", "input, textarea, select", function (e) {
      var properties = eventProperties(e);
      ahoy.track("$change", properties);
    });
  };

  ahoy.trackAll = function() {
    ahoy.trackView();
    ahoy.trackClicks();
    ahoy.trackSubmits();
    ahoy.trackChanges();
  };

  // push events from queue
  try {
    eventQueue = JSON.parse(getCookie("ahoy_events") || "[]");
  } catch (e) {
    // do nothing
  }

  for (var i = 0; i < eventQueue.length; i++) {
    trackEvent(eventQueue[i]);
  }

  window.ahoy = ahoy;
}(window));
<commit_msg>add debuger to ahoy<commit_after>/*
 * Ahoy.js
 * Simple, powerful JavaScript analytics
 * https://github.com/ankane/ahoy.js
 * v0.1.0
 * MIT License
 */

/*jslint browser: true, indent: 2, plusplus: true, vars: true */

(function (window) {
  "use strict";

  var ahoy = window.ahoy || window.Ahoy || {};
  var $ = window.jQuery || window.Zepto || window.$;
  var visitId, visitorId, track;
  var visitTtl = 4 * 60; // 4 hours
  var visitorTtl = 2 * 365 * 24 * 60; // 2 years
  var isReady = false;
  var queue = [];
  var canStringify = typeof(JSON) !== "undefined" && typeof(JSON.stringify) !== "undefined";
  var eventQueue = [];
  var page = ahoy.page || window.location.pathname;
  var visitsUrl = ahoy.visitsUrl || "/ahoy/visits"
  var eventsUrl = ahoy.eventsUrl || "/ahoy/events"

  // cookies

  // http://www.quirksmode.org/js/cookies.html
  function setCookie(name, value, ttl) {
    var expires = "";
    var cookieDomain = "";
    if (ttl) {
      var date = new Date();
      date.setTime(date.getTime() + (ttl * 60 * 1000));
      expires = "; expires=" + date.toGMTString();
    }
    if (ahoy.domain) {
      cookieDomain = "; domain=" + ahoy.domain;
    }
    debugger
    console.log("I'M SETTING COOKIE-- \nname: " + name + "\nval: " + value + "\nttl: " + ttl + "\ncookie domain: " + cookieDomain )
    document.cookie = name + "=" + escape(value) + expires + cookieDomain + "; path=/";
  }

  function getCookie(name) {
    var i, c;
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (i = 0; i < ca.length; i++) {
      c = ca[i];
      while (c.charAt(0) === ' ') {
        c = c.substring(1, c.length);
      }
      if (c.indexOf(nameEQ) === 0) {
        return unescape(c.substring(nameEQ.length, c.length));
      }
    }
    return null;
  }

  function destroyCookie(name) {
    setCookie(name, "", -1);
  }

  function log(message) {
    if (getCookie("ahoy_debug")) {
      window.console.log(message);
    }
  }

  function setReady() {
    var callback;
    while (callback = queue.shift()) {
      callback();
    }
    isReady = true;
  }

  function ready(callback) {
    if (isReady) {
      callback();
    } else {
      queue.push(callback);
    }
  }

  // http://stackoverflow.com/a/2117523/1177228
  function generateId() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
      return v.toString(16);
    });
  }

  function saveEventQueue() {
    // TODO add stringify method for IE 7 and under
    if (canStringify) {
      setCookie("ahoy_events", JSON.stringify(eventQueue), 1);
    }
  }

  function trackEvent(event) {
    ready( function () {
      // ensure JSON is defined
      if (canStringify) {
        $.ajax({
          type: "POST",
          url: eventsUrl,
          data: JSON.stringify([event]),
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          success: function() {
            // remove from queue
            for (var i = 0; i < eventQueue.length; i++) {
              if (eventQueue[i].id == event.id) {
                eventQueue.splice(i, 1);
                break;
              }
            }
            saveEventQueue();
          }
        });
      }
    });
  }

  function eventProperties(e) {
    var $target = $(e.currentTarget);
    return {
      tag: $target.get(0).tagName.toLowerCase(),
      id: $target.attr("id"),
      "class": $target.attr("class"),
      page: page,
      section: $target.closest("*[data-section]").data("section")
    };
  }

  // main

  visitId = getCookie("visit");
  visitorId = getCookie("visitor");
  track = getCookie("ahoy_track");

  if (visitId && visitorId && !track) {
    // TODO keep visit alive?
    log("Active visit");
    setReady();
  } else {
    if (track) {
      destroyCookie("ahoy_track");
    }

    if (!visitId) {
      visitId = generateId();
      setCookie("visit", visitId, visitTtl);
    }

    // make sure cookies are enabled
    if (getCookie("visit")) {
      log("Visit started");

      if (!visitorId) {
        visitorId = generateId();
        setCookie("visitor", visitorId, visitorTtl);
      }

      var data = {
        visit_token: visitId,
        visitor_token: visitorId,
        platform: ahoy.platform || "Web",
        landing_page: window.location.href,
        screen_width: window.screen.width,
        screen_height: window.screen.height
      };

      // referrer
      if (document.referrer.length > 0) {
        data.referrer = document.referrer;
      }

      log(data);

      $.post(visitsUrl, data, setReady, "json");
    } else {
      log("Cookies disabled");
      setReady();
    }
  }

  ahoy.getVisitId = ahoy.getVisitToken = function () {
    return visitId;
  };

  ahoy.getVisitorId = ahoy.getVisitorToken = function () {
    return visitorId;
  };

  ahoy.reset = function () {
    destroyCookie("visit");
    destroyCookie("visitor");
    destroyCookie("ahoy_events");
    destroyCookie("ahoy_track");
    return true;
  };

  ahoy.debug = function (enabled) {
    if (enabled === false) {
      destroyCookie("ahoy_debug");
    } else {
      setCookie("ahoy_debug", "t", 365 * 24 * 60); // 1 year
    }
    return true;
  };

  ahoy.track = function (name, properties) {
    // generate unique id
    var event = {
      id: generateId(),
      name: name,
      properties: properties
    };
    log(event);

    eventQueue.push(event);
    saveEventQueue();

    // wait in case navigating to reduce duplicate events
    setTimeout( function () {
      trackEvent(event);
    }, 1000);
  };

  ahoy.trackView = function(extraProperties) {
    var properties = {
      url: window.location.href,
      title: document.title,
      page: page
    };

    if(typeof(extraProperties) == "object") {
      $.extend(properties, extraProperties);
    }

    ahoy.track("$view", properties);
  };

  ahoy.trackClicks = function () {
    $(document).on("click", "a, button, input[type=submit]", function (e) {
      var $target = $(e.currentTarget);
      var properties = eventProperties(e);
      properties.text = properties.tag == "input" ? $target.val() : $.trim($target.text().replace(/[\s\r\n]+/g, " "));
      properties.href = $target.attr("href");
      ahoy.track("$click", properties);
    });
  };

  ahoy.trackSubmits = function () {
    $(document).on("submit", "form", function (e) {
      var properties = eventProperties(e);
      ahoy.track("$submit", properties);
    });
  };

  ahoy.trackChanges = function () {
    $(document).on("change", "input, textarea, select", function (e) {
      var properties = eventProperties(e);
      ahoy.track("$change", properties);
    });
  };

  ahoy.trackAll = function() {
    ahoy.trackView();
    ahoy.trackClicks();
    ahoy.trackSubmits();
    ahoy.trackChanges();
  };

  // push events from queue
  try {
    eventQueue = JSON.parse(getCookie("ahoy_events") || "[]");
  } catch (e) {
    // do nothing
  }

  for (var i = 0; i < eventQueue.length; i++) {
    trackEvent(eventQueue[i]);
  }

  window.ahoy = ahoy;
}(window));
<|endoftext|>


<commit_before>/* HPK Namespace. */
var HPK = {};

/* ===== GotoBox ===== */

/* Creates a new GotoBox object. */
HPK.GotoBox = function(presentation) {
  var that = this;
  this._element = $("<input type='text' id='goto-box'>")
    .keypress(function(event) {
      switch (event.keyCode) {
        case 13: // Enter
          presentation.gotoSlide($(this).val() - 1);
          that.hide();
          break;
        case 27: // ESC
          that.hide();
          break;
      }
      event.stopPropagation();
    });
  $("body").append(this._element);
}

HPK.GotoBox.prototype = {
  /* Shows, clears and focuses the goto box. */
  show: function() {
    this._element.val("").show().focus();
  },

  /* Hides the goto box. */
  hide: function() {
    this._element.hide();
  }
}

/* ===== CurrentSlideCounter ===== */

/* Creates a new CurrentSlideCounter object. */
HPK.CurrentSlideCounter = function() {
  this._element = $("
");
  $("body").append(this._element);
}

HPK.CurrentSlideCounter.prototype = {
  /* Updates the current slide counter. */
  update: function(currentSlideIndex) {
    this._element.text(currentSlideIndex + 1);
  }
}

/* ===== Navigation ===== */

/* Creates a new Navigation object. */
HPK.Navigation = function(presentation) {
  this.visible = false;
  var that = this;
  this._element = $("
")
    .append($("")
      .click(function(event) {
        presentation.gotoPrevSlide();
        event.stopPropagation();
      })
    )
    .append($("")
      .click(function(event) {
        alert("TODO")
      })
    )
    .append($("")
      .click(function(event) {
        presentation.gotoNextSlide();
        event.stopPropagation();
      })
    )
    .mouseover(function() {
      that.clearHideTimer();
    })
    .mouseout(function() {
      that.touch();
    })
    .mousemove(function(event) {
      event.stopPropagation();
    });
  $("body").append(this._element);
  this._hideTimer = null;
}

HPK.Navigation.prototype = {

  /* Clears the current hiding timer. */
  clearHideTimer: function() {
    if (this._hideTimer) {
      clearTimeout(this._hideTimer);
      this._hideTimer = null;
    }
  },

  /* Clears the current hiding timer and creates a new one. */
  touch: function() {
    this.clearHideTimer();
    var that = this;
    this._hideTimer = setTimeout(function() {
      that.hide();
    }, 5000);
  },

  /* Shows the navigation. */
  show: function() {
    this.visible = true;
    this._element.css("opacity", "0").show().fadeTo("normal", 0.8);
    this.touch();
  },

  /* Hides the navigation. */
  hide: function() {
    this.clearHideTimer();
    this._element.fadeOut("normal");
    this.visible = false;
  }
}

/* ===== Presentation ===== */

/* Creates a new Presentation object and injects the presentation mode toggle
   element into the HTML. */
HPK.Presentation = function() {
  /* Opera has its own presentation capabilities, we do not have to help it.
     See http://www.opera.com/browser/tutorials/operashow/. */
  if ($.browser.opera) { return; }

  this._slides = $("div.presentation div.slide");
  this._currentSlideIndex = null;
  this._presenting = false;
  this._screenStyleLinks = $("link[rel=stylesheet][media=screen]");
  this._projectionStyleLinks = $("link[rel=stylesheet][media=projection]");

  this._createRunPresentationLink();

  this.currentSlideCounter = new HPK.CurrentSlideCounter;
  this.gotoBox = new HPK.GotoBox(this);
  this.navigation = new HPK.Navigation();
}

HPK.Presentation.prototype = {
  /* Creates the link that enables user to run the presentation. */
  _createRunPresentationLink: function() {
    var that = this;
    $("body").append($("")
      .text(HPK.localizationStrings["runPresentation"])
      .click(function(event) {
        that.beginPresentation();

        /* The following line makes sure that the $(document.click(...) handler
           we setup in the "beginPresentation" will not catch the event. */
        event.stopPropagation();
      })
    );
  },

  /* Returns current slide as jQuery object. */
  _currentSlide: function() {
    return this._slides.slice(this._currentSlideIndex, this._currentSlideIndex + 1);
  },

  /* Are we presenting now? */
  isPresenting: function() {
    return this._presenting;
  },

  /* Begins the presentation. */
  beginPresentation: function() {
    if (this._presenting) { return; }
    if (this._slides.length == 0) { return; }

    this._slides.slice(1).hide();
    this._currentSlideIndex = 0;
    this.currentSlideCounter.update(this._currentSlideIndex);

    this._screenStyleLinks.attr("media", "projection")
    this._projectionStyleLinks.attr("media", "screen");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.attr("disabled", "disabled");
      this._projectionStyleLinks.removeAttr("disabled");
    }

    var that = this;

    $(document).mousemove(function(event) {
      if (event.pageY >= 0.8 * $(document).height()) {
        if (!that.navigation.visible) {
          that.navigation.show();
        } else {
          that.navigation.touch();
        }
      } else {
        if (that.navigation.visible) {
          that.navigation.hide();
        }
      }
    });

    $(document).click(function(event) {
      switch (event.which) {
        case 1: // Left button
          that.gotoNextSlideOrEndPresentation();
          return false;
        case 3: // Right button
          that.gotoPrevSlideOrEndPresentation();
          return false;
      }
    });

    $(document).keypress(function(event) {
      switch (event.which) {
        case 13:  // Enter
        case 32:  // Space
        case 110: // "n"
          that.gotoNextSlideOrEndPresentation();
          return false;

        case 8:   // Backspace
        case 112: // "p"
          that.gotoPrevSlideOrEndPresentation();
          return false;

        case 103: // "g"
          that.gotoBox.show();
          return false;

        case 0:
          switch (event.keyCode) {
            case 34: // Page Down
            case 39: // Right Arrow
            case 40: // Down Arrow
              that.gotoNextSlideOrEndPresentation();
              return false;

            case 33: // Page Up
            case 37: // Left Arrow
            case 38: // Up Arrow
              that.gotoPrevSlideOrEndPresentation();
              return false;

            case 27: // ESC
              that.endPresentation();
              return false;
          }
      }
    });

    this._presenting = true;
  },

  /* Ends the presentation. */
  endPresentation: function() {
    if (!this._presenting) { return; }

    this._slides.show();
    this._currentSlideIndex = null;
    this.gotoBox.hide();

    this._screenStyleLinks.attr("media", "screen");
    this._projectionStyleLinks.attr("media", "projection");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.removeAttr("disabled");
      this._projectionStyleLinks.attr("disabled", "disabled");
    }

    $(document).unbind("mousemove", this._documentMousemove);
    $(document).unbind("click", this._documentClick);
    $(document).unbind("keypress", this._documentKeypress);

    this._presenting = false;
  },

  /* Are we on the last slide? */
  isOnFirstSlide: function() {
    return this._presenting
      && this._currentSlideIndex == 0;
  },

  /* Are we on the last slide? */
  isOnLastSlide: function() {
    return this._presenting
      && this._currentSlideIndex == this._slides.length - 1;
  },

  /* If presenting, moves to the slide with specified index (if there is any). */
  gotoSlide: function(slideIndex) {
    if (this._presenting && slideIndex >= 0 && slideIndex < this._slides.length) {
      this._currentSlide().hide();
      this._currentSlideIndex = slideIndex;
      this._currentSlide().show();
      this.currentSlideCounter.update(this._currentSlideIndex);
    }
  },

  /* If presenting, moves to the next slide (if there is any). */
  gotoNextSlide: function() {
    this.gotoSlide(this._currentSlideIndex + 1);
  },

  /* If presenting, moves to the previous slide (if there is any). */
  gotoPrevSlide: function() {
    this.gotoSlide(this._currentSlideIndex - 1);
  },

  /* If presenting, moves to the next slide (if there is any) or ends the
     presentation. */
  gotoNextSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnLastSlide()) {
        this.gotoNextSlide();
      } else {
        this.endPresentation();
      }
    }
  },

  /* If presenting, moves to the previous slide (if there is any) or ends the
     presentation. */
  gotoPrevSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnFirstSlide()) {
        this.gotoPrevSlide();
      } else {
        this.endPresentation();
      }
    }
  }
}

/* ===== Let's roll... ===== */

$(document).ready(function() {
  HPK.presentation = new HPK.Presentation();

  if (!$.browser.opera) {
    /* These variables will be closed over by the resize handler bellow, so they
       will behave like static variables from its point of view. */
    var oldWindowWidth = $(window).width();
    var oldWindowHeight = $(window).height();

    $(window).bind("resize", function() {
      var windowWidth = $(window).width();
      var windowHeight = $(window).height();

      /* This is obviously an optimization, but we do it mainly because IE
         triggers the resize handler much more often than it should, which
         results to switching from and to the presentation again in certain
         situations (such as clicking the "Run presentation" link or at the
         end of the presentation). */
      if (windowWidth == oldWindowWidth && windowHeight == oldWindowHeight) {
        return;
      }

      /* In IE, the window height is actually larger than the screen height
         in the fullscreen mode, but it does not count scrollbar width into
         the window width. Firefox has a small bar at the top even in the
         fullscreen mode. As a result, fullscreen mode detection must be a bit
         tolerant. Browser world is a mess... */
      var isFullscreen = screen.width - windowWidth <= 20
        && screen.height - windowHeight <= 10;

      if (!HPK.presentation.isPresenting() && isFullscreen) {
        HPK.presentation.beginPresentation();
      } else if (HPK.presentation.isPresenting() && !isFullscreen) {
        HPK.presentation.endPresentation();
      }

      oldWindowWidth = windowWidth;
      oldWindowHeight = windowHeight;
    });
  }

  var matches = document.location.hash.match(/^#slide-(\d+)$/);
  if (matches) {
    HPK.presentation.beginPresentation();
    HPK.presentation.gotoSlide(parseInt(matches[1]) - 1);
  }
});

<commit_msg>Put Opera detection logic to the right place.<commit_after>/* HPK Namespace. */
var HPK = {};

/* ===== GotoBox ===== */

/* Creates a new GotoBox object. */
HPK.GotoBox = function(presentation) {
  var that = this;
  this._element = $("<input type='text' id='goto-box'>")
    .keypress(function(event) {
      switch (event.keyCode) {
        case 13: // Enter
          presentation.gotoSlide($(this).val() - 1);
          that.hide();
          break;
        case 27: // ESC
          that.hide();
          break;
      }
      event.stopPropagation();
    });
  $("body").append(this._element);
}

HPK.GotoBox.prototype = {
  /* Shows, clears and focuses the goto box. */
  show: function() {
    this._element.val("").show().focus();
  },

  /* Hides the goto box. */
  hide: function() {
    this._element.hide();
  }
}

/* ===== CurrentSlideCounter ===== */

/* Creates a new CurrentSlideCounter object. */
HPK.CurrentSlideCounter = function() {
  this._element = $("
");
  $("body").append(this._element);
}

HPK.CurrentSlideCounter.prototype = {
  /* Updates the current slide counter. */
  update: function(currentSlideIndex) {
    this._element.text(currentSlideIndex + 1);
  }
}

/* ===== Navigation ===== */

/* Creates a new Navigation object. */
HPK.Navigation = function(presentation) {
  this.visible = false;
  var that = this;
  this._element = $("
")
    .append($("")
      .click(function(event) {
        presentation.gotoPrevSlide();
        event.stopPropagation();
      })
    )
    .append($("")
      .click(function(event) {
        alert("TODO")
      })
    )
    .append($("")
      .click(function(event) {
        presentation.gotoNextSlide();
        event.stopPropagation();
      })
    )
    .mouseover(function() {
      that.clearHideTimer();
    })
    .mouseout(function() {
      that.touch();
    })
    .mousemove(function(event) {
      event.stopPropagation();
    });
  $("body").append(this._element);
  this._hideTimer = null;
}

HPK.Navigation.prototype = {

  /* Clears the current hiding timer. */
  clearHideTimer: function() {
    if (this._hideTimer) {
      clearTimeout(this._hideTimer);
      this._hideTimer = null;
    }
  },

  /* Clears the current hiding timer and creates a new one. */
  touch: function() {
    this.clearHideTimer();
    var that = this;
    this._hideTimer = setTimeout(function() {
      that.hide();
    }, 5000);
  },

  /* Shows the navigation. */
  show: function() {
    this.visible = true;
    this._element.css("opacity", "0").show().fadeTo("normal", 0.8);
    this.touch();
  },

  /* Hides the navigation. */
  hide: function() {
    this.clearHideTimer();
    this._element.fadeOut("normal");
    this.visible = false;
  }
}

/* ===== Presentation ===== */

/* Creates a new Presentation object and injects the presentation mode toggle
   element into the HTML. */
HPK.Presentation = function() {
  this._slides = $("div.presentation div.slide");
  this._currentSlideIndex = null;
  this._presenting = false;
  this._screenStyleLinks = $("link[rel=stylesheet][media=screen]");
  this._projectionStyleLinks = $("link[rel=stylesheet][media=projection]");

  this._createRunPresentationLink();

  this.currentSlideCounter = new HPK.CurrentSlideCounter;
  this.gotoBox = new HPK.GotoBox(this);
  this.navigation = new HPK.Navigation();
}

HPK.Presentation.prototype = {
  /* Creates the link that enables user to run the presentation. */
  _createRunPresentationLink: function() {
    var that = this;
    $("body").append($("")
      .text(HPK.localizationStrings["runPresentation"])
      .click(function(event) {
        that.beginPresentation();

        /* The following line makes sure that the $(document.click(...) handler
           we setup in the "beginPresentation" will not catch the event. */
        event.stopPropagation();
      })
    );
  },

  /* Returns current slide as jQuery object. */
  _currentSlide: function() {
    return this._slides.slice(this._currentSlideIndex, this._currentSlideIndex + 1);
  },

  /* Are we presenting now? */
  isPresenting: function() {
    return this._presenting;
  },

  /* Begins the presentation. */
  beginPresentation: function() {
    if (this._presenting) { return; }
    if (this._slides.length == 0) { return; }

    this._slides.slice(1).hide();
    this._currentSlideIndex = 0;
    this.currentSlideCounter.update(this._currentSlideIndex);

    this._screenStyleLinks.attr("media", "projection")
    this._projectionStyleLinks.attr("media", "screen");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.attr("disabled", "disabled");
      this._projectionStyleLinks.removeAttr("disabled");
    }

    var that = this;

    $(document).mousemove(function(event) {
      if (event.pageY >= 0.8 * $(document).height()) {
        if (!that.navigation.visible) {
          that.navigation.show();
        } else {
          that.navigation.touch();
        }
      } else {
        if (that.navigation.visible) {
          that.navigation.hide();
        }
      }
    });

    $(document).click(function(event) {
      switch (event.which) {
        case 1: // Left button
          that.gotoNextSlideOrEndPresentation();
          return false;
        case 3: // Right button
          that.gotoPrevSlideOrEndPresentation();
          return false;
      }
    });

    $(document).keypress(function(event) {
      switch (event.which) {
        case 13:  // Enter
        case 32:  // Space
        case 110: // "n"
          that.gotoNextSlideOrEndPresentation();
          return false;

        case 8:   // Backspace
        case 112: // "p"
          that.gotoPrevSlideOrEndPresentation();
          return false;

        case 103: // "g"
          that.gotoBox.show();
          return false;

        case 0:
          switch (event.keyCode) {
            case 34: // Page Down
            case 39: // Right Arrow
            case 40: // Down Arrow
              that.gotoNextSlideOrEndPresentation();
              return false;

            case 33: // Page Up
            case 37: // Left Arrow
            case 38: // Up Arrow
              that.gotoPrevSlideOrEndPresentation();
              return false;

            case 27: // ESC
              that.endPresentation();
              return false;
          }
      }
    });

    this._presenting = true;
  },

  /* Ends the presentation. */
  endPresentation: function() {
    if (!this._presenting) { return; }

    this._slides.show();
    this._currentSlideIndex = null;
    this.gotoBox.hide();

    this._screenStyleLinks.attr("media", "screen");
    this._projectionStyleLinks.attr("media", "projection");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.removeAttr("disabled");
      this._projectionStyleLinks.attr("disabled", "disabled");
    }

    $(document).unbind("mousemove", this._documentMousemove);
    $(document).unbind("click", this._documentClick);
    $(document).unbind("keypress", this._documentKeypress);

    this._presenting = false;
  },

  /* Are we on the last slide? */
  isOnFirstSlide: function() {
    return this._presenting
      && this._currentSlideIndex == 0;
  },

  /* Are we on the last slide? */
  isOnLastSlide: function() {
    return this._presenting
      && this._currentSlideIndex == this._slides.length - 1;
  },

  /* If presenting, moves to the slide with specified index (if there is any). */
  gotoSlide: function(slideIndex) {
    if (this._presenting && slideIndex >= 0 && slideIndex < this._slides.length) {
      this._currentSlide().hide();
      this._currentSlideIndex = slideIndex;
      this._currentSlide().show();
      this.currentSlideCounter.update(this._currentSlideIndex);
    }
  },

  /* If presenting, moves to the next slide (if there is any). */
  gotoNextSlide: function() {
    this.gotoSlide(this._currentSlideIndex + 1);
  },

  /* If presenting, moves to the previous slide (if there is any). */
  gotoPrevSlide: function() {
    this.gotoSlide(this._currentSlideIndex - 1);
  },

  /* If presenting, moves to the next slide (if there is any) or ends the
     presentation. */
  gotoNextSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnLastSlide()) {
        this.gotoNextSlide();
      } else {
        this.endPresentation();
      }
    }
  },

  /* If presenting, moves to the previous slide (if there is any) or ends the
     presentation. */
  gotoPrevSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnFirstSlide()) {
        this.gotoPrevSlide();
      } else {
        this.endPresentation();
      }
    }
  }
}

/* ===== Let's roll... ===== */

$(document).ready(function() {
  /* Opera has its own presentation capabilities, we do not have to help it.
     See http://www.opera.com/browser/tutorials/operashow/. */
  if ($.browser.opera) { return; }

  HPK.presentation = new HPK.Presentation();

  /* These variables will be closed over by the resize handler bellow, so they
     will behave like static variables from its point of view. */
  var oldWindowWidth = $(window).width();
  var oldWindowHeight = $(window).height();

  $(window).bind("resize", function() {
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    /* This is obviously an optimization, but we do it mainly because IE
       triggers the resize handler much more often than it should, which
       results to switching from and to the presentation again in certain
       situations (such as clicking the "Run presentation" link or at the
       end of the presentation). */
    if (windowWidth == oldWindowWidth && windowHeight == oldWindowHeight) {
      return;
    }

    /* In IE, the window height is actually larger than the screen height
       in the fullscreen mode, but it does not count scrollbar width into
       the window width. Firefox has a small bar at the top even in the
       fullscreen mode. As a result, fullscreen mode detection must be a bit
       tolerant. Browser world is a mess... */
    var isFullscreen = screen.width - windowWidth <= 20
      && screen.height - windowHeight <= 10;

    if (!HPK.presentation.isPresenting() && isFullscreen) {
      HPK.presentation.beginPresentation();
    } else if (HPK.presentation.isPresenting() && !isFullscreen) {
      HPK.presentation.endPresentation();
    }

    oldWindowWidth = windowWidth;
    oldWindowHeight = windowHeight;
  });

  var matches = document.location.hash.match(/^#slide-(\d+)$/);
  if (matches) {
    HPK.presentation.beginPresentation();
    HPK.presentation.gotoSlide(parseInt(matches[1]) - 1);
  }
});

<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/*
 * Dependencies
 *
 * /dev/lib/jquery/plugins/jqmodal.sakai-edited.js
 * /dev/lib/jquery/plugins/jquery.validate.sakai-edited.js (validate)
 */

require(["jquery", "sakai/sakai.api.core"], function($, sakai) {

    /**
     * @name sakai_global.newcreategroup
     *
     * @class newcreategroup
     *
     * @description
     * newcreategroup widget
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.newcreategroup = function(tuid, showSettings, widgetData){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    var $rootel = $("#" + tuid);

    // Containers
    var $newcreategroupContainer = $("#newcreategroup_container", $rootel);
    var $newcreategroupGroupMembersNoneAddedContainer = $("#newcreategroup_group_members_none_added_container", $rootel);
    var $newcreategroupMembersAddedContainer = $("#newcreategroup_group_members_added_container", $rootel);

    // Elements
    var $newcreategroupCreateSimpleGroupButton = $(".newcreategroup_create_simple_group", $rootel);
    var $newcreategroupCancelCreateButton = $("#newcreategroup_cancel_create", $rootel);
    var $newcreategroupGroupTitle = $("#newcreategroup_title", $rootel);
    var $newcreategroupSuggestedURL = $("#newcreategroup_suggested_url", $rootel);
    var $newcreategroupGroupDescription = $("#newcreategroup_description", $rootel);
    var $newcreategroupGroupTags = $("#newcreategroup_tags", $rootel);
    var $newcreategroupSuggestedURLBase = $("#newcreategroup_suggested_url_base", $rootel);
    var $newcreategroupCanBeFoundIn = $("#newcreategroup_can_be_found_in", $rootel);
    var $newcreategroupGroupMembership = $("#newcreategroup_membership", $rootel);
    var $newcreategroupAddPeople = $(".newcreategroup_add_people", $rootel);
    var newcreategroupMembersMessage = "#newcreategroup_members_message";

    // Forms
    var $newcreategroupGroupForm = $("#newcreategroup_group_form", $rootel);

    // Templates
    var newcreategroupMembersSelectedTemplate = "newcreategroup_group_members_selected_template";
    var newcreategroupMembersMessageTemplate = "newcreategroup_members_message_template";

    var selectedUsers = {};
    var currentTemplate = false;
    var creationComplete = {
        "tags": false,
        "permissions": false,
        "members": false,
        "message": false,
        "groupid": false
    };

    var renderShareMessage = function(){
        $(newcreategroupMembersMessage, $rootel).html(sakai.api.Util.TemplateRenderer(newcreategroupMembersMessageTemplate, {
            "user" : sakai.api.User.getDisplayName(sakai.data.me.profile),
            "groupName" : sakai.api.Security.safeOutput($newcreategroupGroupTitle.val() || ""),
            "groupURL": window.location.protocol + "//" + window.location.host + "/~" + sakai.api.Util.makeSafeURL($newcreategroupSuggestedURL.val() || "")
        }));
    };

    /**
     * When a group is created, the creator of the group is added directly to
     * the managers list. This is good during group creation, but creates
     * undesired side-effects when managing permissions later on. This function
     * gets ahead of the issue by removing the creator from the managers
     * list after group creation
     *
     * @param {String} groupid the id of the group to remove the creator
     *                        (current user) from
     */
    var removeCreatorFromManagersOfMainGroup = function(groupid, template, callback) {
        var members = [];
        members.push({
            "userid": sakai.api.User.data.me.user.userid,
            "removeManagerOnly": true
        });
        $.each(template.roles, function(i, role) {
            members.push({
                "userid": sakai.api.User.data.me.user.userid,
                "permission": role.id,
                "removeManagerOnly": true
            });
        });
        sakai.api.Groups.removeUsersFromGroup(groupid, members, sakai.api.User.data.me, function() {
            if ($.isFunction(callback)) {
                callback();
            }
        });
    };

    /**
     * Create a simple group and execute the tagging and membership functions
     */
    var doCreateSimpleGroup = function(){
        var grouptitle = $newcreategroupGroupTitle.val() || "";
        var groupdescription = $newcreategroupGroupDescription.val() || "";
        var groupid = sakai.api.Util.makeSafeURL($newcreategroupSuggestedURL.val(), "-");
        var grouptags = $newcreategroupGroupTags.val().split(",");
        sakai.api.Groups.createGroup(groupid, grouptitle, groupdescription, sakai.data.me, currentTemplate, widgetData.category, function(success, groupData, nameTaken){
            if (success) {
                // Tag group
                var groupProfileURL = "/~" + groupid + "/public/authprofile";
                sakai.api.Util.tagEntity(groupProfileURL, grouptags, [], function(){

                    // Set permissions on group
                    var joinable = $newcreategroupGroupMembership.val();
                    var visible = $newcreategroupCanBeFoundIn.val();
                    var roles = $.parseJSON(groupData["sakai:roles"]);
                    sakai.api.Groups.setPermissions(groupid, joinable, visible, roles, function(){

                        // Set members and managers on group
                        var users = [];
                        $.each(selectedUsers, function(index, item){
                            users.push({
                                "name": item.name,
                                "user": item.userid,
                                "permission": item.permission
                            });
                        });

                        if (users.length > 0) {
                            sakai.api.Groups.addUsersToGroup(groupid, users, sakai.data.me, false, function(){
                                $.each(users, function(index, item){
                                    var subject = sakai.api.i18n.Widgets.getValueForKey("newcreategroup","","USER_HAS_ADDED_YOU_AS_A_ROLE_TO_THE_GROUP_GROUPNAME").replace("${user}", sakai.api.Security.unescapeHTML(sakai.api.User.getDisplayName(sakai.data.me.profile))).replace("<\"Role\">", item.permission).replace("${groupName}", grouptitle);
                                    var body = $(newcreategroupMembersMessage, $rootel).text().replace("<\"Role\">", item.permission).replace("<\"First Name\">", item.name);
                                    sakai.api.Communication.sendMessage(item.user, sakai.data.me, subject, body, "message", false, false, true, "group_invitation",{"groupTitle":grouptitle,"groupId":groupid});
                                    if(users.length - 1 === index){
                                        createGroupDocs(groupid, currentTemplate);
                                    }
                                });
                            });
                        } else {
                            createGroupDocs(groupid, currentTemplate);
                        }
                    });
                });

            } else {
                if(nameTaken){
                    sakai.api.Util.notification.show(sakai.api.i18n.Widgets.getValueForKey("newcreategroup","","GROUP_TAKEN"), sakai.api.i18n.Widgets.getValueForKey("newcreategroup","","THIS_GROUP_HAS_BEEN_TAKEN"));
                }
                $newcreategroupContainer.find("select, input, textarea, button").removeAttr("disabled");
            }
        });
    };

    var createGroupDocs = function(groupid, currentTemplate){
        var templateParameters = {
            "groupid": groupid,
            "refid": sakai.api.Util.generateWidgetId()
        };
        currentTemplate = sakai.api.Util.replaceTemplateParameters(templateParameters, currentTemplate);
        createSakaiDocs(groupid, currentTemplate, function(groupid, currentTemplate){
            fillSakaiDocs(groupid, currentTemplate, function(groupid, currentTemplate){
                setSakaiDocPermissions(groupid, currentTemplate, function(groupid, currentTemplate){
                    addStructureToGroup(groupid, currentTemplate, function(){
                        removeCreatorFromManagersOfMainGroup(groupid, currentTemplate, function() {
                            window.location = "/~" + groupid;
                        });
                    });
                });
            });
        });
    };

    var addStructureToGroup = function(groupid, currentTemplate, callback){
        for (var doc in currentTemplate.structure) {
            var definition = currentTemplate.structure[doc];
            delete definition._docref;
            definition._view = $.toJSON(definition._view);
            definition._edit = $.toJSON(definition._edit);
        }
        $.ajax({
            url: "/~" + groupid + "/docstructure",
            type: "POST",
            data: {
                ":operation": "import",
                ":contentType": "json",
                ":replace": true,
                ":replaceProperties": true,
                "_charset_": "utf-8",
                ":content": $.toJSON({
                    "structure0": $.toJSON(currentTemplate.structure)
                })
            },
            success: function(){
                callback();
            }
        });
    };

    var setSakaiDocPermissions = function(groupid, currentTemplate, callback){
        var filesArray = {};
        for (var doc in currentTemplate.structure){
            var definition = currentTemplate.structure[doc];
            var permission = "private";
            if ($.inArray("anonymous", definition._view) !== -1 && $newcreategroupCanBeFoundIn.val() === "public"){
                permission = "public";
            } else if ($.inArray("everyone", definition._view) !== -1 && ($newcreategroupCanBeFoundIn.val() === "public" || $newcreategroupCanBeFoundIn.val() === "logged-in-only")){
                permission = "everyone";
            }
            filesArray[definition._pid] = {
                "hashpath": definition._pid,
                "permissions": permission
            };
        }
        sakai.api.Content.setFilePermissions(filesArray, function(){
            var batchRequests = [];
            for (var doc in currentTemplate.structure) {
                var definition = currentTemplate.structure[doc];
                for (var i = 0; i < definition._view.length; i++){
                    if (definition._view[i].substring(0, 1) === "-") {
                        batchRequests.push({
                            "url": "/p/" + definition._pid + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": groupid + definition._view[i]
                            }
                        });
                    }
                }
                for (var j = 0; j < definition._edit.length; j++){
                    if (definition._edit[j].substring(0, 1) === "-") {
                        batchRequests.push({
                            "url": "/p/" + definition._pid + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":manager": groupid + definition._edit[j]
                            }
                        });
                    }
                }
            }
            sakai.api.Server.batch(batchRequests, function(success, data) {
                if (success) {
                    callback(groupid, currentTemplate);
                }
            });
        });
    };

    var fillSakaiDocs = function(groupid, currentTemplate, callback){
        var batchRequests = [];
        for (var doc in currentTemplate.structure){
            var definition = currentTemplate.structure[doc];
            var toCreate = currentTemplate.docs[definition._docref];
            delete toCreate.structure0;
            batchRequests.push({
                url: "/p/" + definition._pid + ".resource",
                method: "POST",
                parameters: {
                    ":operation": "import",
                    ":contentType": "json",
                    ":replace": true,
                    ":replaceProperties": true,
                    "_charset_": "utf-8",
                    ":content": $.toJSON(toCreate)
                }
            });
        }
        sakai.api.Server.batch(batchRequests, function(success, data) {
            if (success) {
                callback(groupid, currentTemplate);
            }
        });
    };

    var createSakaiDocs = function(groupid, currentTemplate, callback){
        var batchRequests = [];
        for (var doc in currentTemplate.structure){
            var definition = currentTemplate.structure[doc];
            var permission = "private";
            if ($.inArray("anonymous", definition._view) !== -1 && $newcreategroupCanBeFoundIn.val() === "public"){
                permission = "public";
            } else if ($.inArray("everyone", definition._view) !== -1 && ($newcreategroupCanBeFoundIn.val() === "public" || $newcreategroupCanBeFoundIn.val() === "logged-in-only")){
                permission = "everyone";
            }
            var toCreate = currentTemplate.docs[definition._docref];
            batchRequests.push({
                url: "/system/pool/createfile",
                method:"POST",
                parameters: {
                    "sakai:pooled-content-file-name": definition._title,
                    "sakai:description": "",
                    "sakai:permissions": permission,
                    "sakai:copyright": "creativecommons",
                    "structure0": $.toJSON(toCreate.structure0),
                    "mimeType": "x-sakai/document"
                }
            });
        }
        sakai.api.Server.batch(batchRequests, function(success, data) {
            if (success) {
                var count = 0;
                for (var doc in currentTemplate.structure){
                    var response = $.parseJSON(data.results[count].body);
                    currentTemplate.structure[doc]._pid = response._contentItem.poolId;
                    count++;
                }
                callback(groupid, currentTemplate);
            }
        });
    };

    /**
     * Add binding to the elements and validate the forms on submit
     */
    var addBinding = function(){
        $newcreategroupCreateSimpleGroupButton.bind("click", function(){
            $newcreategroupGroupForm.validate({
                submitHandler: function(form){
                    $newcreategroupContainer.find("select, input, textarea, button").attr("disabled","disabled");
                    doCreateSimpleGroup();
                }
            });
            $newcreategroupGroupForm.submit();
        });

        $newcreategroupGroupTitle.bind("keyup", function(){
            var suggestedURL = sakai.api.Util.makeSafeURL($(this).val(), "-");
            $newcreategroupSuggestedURL.val(suggestedURL);
            renderShareMessage();
        });

        $newcreategroupSuggestedURL.bind("blur", function(){
            var suggestedURL = sakai.api.Util.makeSafeURL($(this).val(), "-");
            $newcreategroupSuggestedURL.val(suggestedURL);
            renderShareMessage();
        });

        $newcreategroupAddPeople.live("click", function(){
            $(window).trigger("init.addpeople.sakai", [tuid]);
        });
    };

    /**
     * Initialize the create group widget
     */
    var doInit = function(){
        currentTemplate = sakai.api.Groups.getTemplate(widgetData.category, widgetData.id);
        $(".newcreategroup_template_name", $rootel).text(currentTemplate.title);
        $newcreategroupSuggestedURLBase.text(window.location.protocol + "//" + window.location.host + "/~");
        if (sakai.config.Permissions.Groups.defaultaccess){
            $("#newcreategroup_can_be_found_in [value=" + sakai.config.Permissions.Groups.defaultaccess + "]", $rootel).attr("selected", "selected");
        }
        $newcreategroupContainer.show();
        addBinding();
    };

    $newcreategroupCancelCreateButton.bind("click", function(){
        $.bbq.pushState({"_r": Math.random()});
    });

    $(window).bind("sakai.addpeople.usersselected", function(ev, initTuid, users){
        if (initTuid === tuid) {
            selectedUsers = $.extend(true, {}, users);
            $newcreategroupMembersAddedContainer.html(sakai.api.Util.TemplateRenderer(newcreategroupMembersSelectedTemplate, {
                "users": selectedUsers,
                "roles": currentTemplate.roles
            }));
            var count = 0;
            for (var item in selectedUsers) {
                count++;
            }
            if (count) {
                renderShareMessage();
                $newcreategroupGroupMembersNoneAddedContainer.hide();
                $newcreategroupMembersAddedContainer.show();
            } else {
                $newcreategroupGroupMembersNoneAddedContainer.show();
                $newcreategroupMembersAddedContainer.hide();
            }
        }
    });

    doInit();

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("newcreategroup");

});
<commit_msg>SAKIII-3689 Server URL should be cut off if it is too long for the Create new world screen<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/*
 * Dependencies
 *
 * /dev/lib/jquery/plugins/jqmodal.sakai-edited.js
 * /dev/lib/jquery/plugins/jquery.validate.sakai-edited.js (validate)
 */

require(["jquery", "sakai/sakai.api.core"], function($, sakai) {

    /**
     * @name sakai_global.newcreategroup
     *
     * @class newcreategroup
     *
     * @description
     * newcreategroup widget
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.newcreategroup = function(tuid, showSettings, widgetData){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    var $rootel = $("#" + tuid);

    // Containers
    var $newcreategroupContainer = $("#newcreategroup_container", $rootel);
    var $newcreategroupGroupMembersNoneAddedContainer = $("#newcreategroup_group_members_none_added_container", $rootel);
    var $newcreategroupMembersAddedContainer = $("#newcreategroup_group_members_added_container", $rootel);

    // Elements
    var $newcreategroupCreateSimpleGroupButton = $(".newcreategroup_create_simple_group", $rootel);
    var $newcreategroupCancelCreateButton = $("#newcreategroup_cancel_create", $rootel);
    var $newcreategroupGroupTitle = $("#newcreategroup_title", $rootel);
    var $newcreategroupSuggestedURL = $("#newcreategroup_suggested_url", $rootel);
    var $newcreategroupGroupDescription = $("#newcreategroup_description", $rootel);
    var $newcreategroupGroupTags = $("#newcreategroup_tags", $rootel);
    var $newcreategroupSuggestedURLBase = $("#newcreategroup_suggested_url_base", $rootel);
    var $newcreategroupCanBeFoundIn = $("#newcreategroup_can_be_found_in", $rootel);
    var $newcreategroupGroupMembership = $("#newcreategroup_membership", $rootel);
    var $newcreategroupAddPeople = $(".newcreategroup_add_people", $rootel);
    var newcreategroupMembersMessage = "#newcreategroup_members_message";

    // Forms
    var $newcreategroupGroupForm = $("#newcreategroup_group_form", $rootel);

    // Templates
    var newcreategroupMembersSelectedTemplate = "newcreategroup_group_members_selected_template";
    var newcreategroupMembersMessageTemplate = "newcreategroup_members_message_template";

    var selectedUsers = {};
    var currentTemplate = false;
    var creationComplete = {
        "tags": false,
        "permissions": false,
        "members": false,
        "message": false,
        "groupid": false
    };

    var renderShareMessage = function(){
        $(newcreategroupMembersMessage, $rootel).html(sakai.api.Util.TemplateRenderer(newcreategroupMembersMessageTemplate, {
            "user" : sakai.api.User.getDisplayName(sakai.data.me.profile),
            "groupName" : sakai.api.Security.safeOutput($newcreategroupGroupTitle.val() || ""),
            "groupURL": window.location.protocol + "//" + window.location.host + "/~" + sakai.api.Util.makeSafeURL($newcreategroupSuggestedURL.val() || "")
        }));
    };

    /**
     * When a group is created, the creator of the group is added directly to
     * the managers list. This is good during group creation, but creates
     * undesired side-effects when managing permissions later on. This function
     * gets ahead of the issue by removing the creator from the managers
     * list after group creation
     *
     * @param {String} groupid the id of the group to remove the creator
     *                        (current user) from
     */
    var removeCreatorFromManagersOfMainGroup = function(groupid, template, callback) {
        var members = [];
        members.push({
            "userid": sakai.api.User.data.me.user.userid,
            "removeManagerOnly": true
        });
        $.each(template.roles, function(i, role) {
            members.push({
                "userid": sakai.api.User.data.me.user.userid,
                "permission": role.id,
                "removeManagerOnly": true
            });
        });
        sakai.api.Groups.removeUsersFromGroup(groupid, members, sakai.api.User.data.me, function() {
            if ($.isFunction(callback)) {
                callback();
            }
        });
    };

    /**
     * Create a simple group and execute the tagging and membership functions
     */
    var doCreateSimpleGroup = function(){
        var grouptitle = $newcreategroupGroupTitle.val() || "";
        var groupdescription = $newcreategroupGroupDescription.val() || "";
        var groupid = sakai.api.Util.makeSafeURL($newcreategroupSuggestedURL.val(), "-");
        var grouptags = $newcreategroupGroupTags.val().split(",");
        sakai.api.Groups.createGroup(groupid, grouptitle, groupdescription, sakai.data.me, currentTemplate, widgetData.category, function(success, groupData, nameTaken){
            if (success) {
                // Tag group
                var groupProfileURL = "/~" + groupid + "/public/authprofile";
                sakai.api.Util.tagEntity(groupProfileURL, grouptags, [], function(){

                    // Set permissions on group
                    var joinable = $newcreategroupGroupMembership.val();
                    var visible = $newcreategroupCanBeFoundIn.val();
                    var roles = $.parseJSON(groupData["sakai:roles"]);
                    sakai.api.Groups.setPermissions(groupid, joinable, visible, roles, function(){

                        // Set members and managers on group
                        var users = [];
                        $.each(selectedUsers, function(index, item){
                            users.push({
                                "name": item.name,
                                "user": item.userid,
                                "permission": item.permission
                            });
                        });

                        if (users.length > 0) {
                            sakai.api.Groups.addUsersToGroup(groupid, users, sakai.data.me, false, function(){
                                $.each(users, function(index, item){
                                    var subject = sakai.api.i18n.Widgets.getValueForKey("newcreategroup","","USER_HAS_ADDED_YOU_AS_A_ROLE_TO_THE_GROUP_GROUPNAME").replace("${user}", sakai.api.Security.unescapeHTML(sakai.api.User.getDisplayName(sakai.data.me.profile))).replace("<\"Role\">", item.permission).replace("${groupName}", grouptitle);
                                    var body = $(newcreategroupMembersMessage, $rootel).text().replace("<\"Role\">", item.permission).replace("<\"First Name\">", item.name);
                                    sakai.api.Communication.sendMessage(item.user, sakai.data.me, subject, body, "message", false, false, true, "group_invitation",{"groupTitle":grouptitle,"groupId":groupid});
                                    if(users.length - 1 === index){
                                        createGroupDocs(groupid, currentTemplate);
                                    }
                                });
                            });
                        } else {
                            createGroupDocs(groupid, currentTemplate);
                        }
                    });
                });

            } else {
                if(nameTaken){
                    sakai.api.Util.notification.show(sakai.api.i18n.Widgets.getValueForKey("newcreategroup","","GROUP_TAKEN"), sakai.api.i18n.Widgets.getValueForKey("newcreategroup","","THIS_GROUP_HAS_BEEN_TAKEN"));
                }
                $newcreategroupContainer.find("select, input, textarea, button").removeAttr("disabled");
            }
        });
    };

    var createGroupDocs = function(groupid, currentTemplate){
        var templateParameters = {
            "groupid": groupid,
            "refid": sakai.api.Util.generateWidgetId()
        };
        currentTemplate = sakai.api.Util.replaceTemplateParameters(templateParameters, currentTemplate);
        createSakaiDocs(groupid, currentTemplate, function(groupid, currentTemplate){
            fillSakaiDocs(groupid, currentTemplate, function(groupid, currentTemplate){
                setSakaiDocPermissions(groupid, currentTemplate, function(groupid, currentTemplate){
                    addStructureToGroup(groupid, currentTemplate, function(){
                        removeCreatorFromManagersOfMainGroup(groupid, currentTemplate, function() {
                            window.location = "/~" + groupid;
                        });
                    });
                });
            });
        });
    };

    var addStructureToGroup = function(groupid, currentTemplate, callback){
        for (var doc in currentTemplate.structure) {
            var definition = currentTemplate.structure[doc];
            delete definition._docref;
            definition._view = $.toJSON(definition._view);
            definition._edit = $.toJSON(definition._edit);
        }
        $.ajax({
            url: "/~" + groupid + "/docstructure",
            type: "POST",
            data: {
                ":operation": "import",
                ":contentType": "json",
                ":replace": true,
                ":replaceProperties": true,
                "_charset_": "utf-8",
                ":content": $.toJSON({
                    "structure0": $.toJSON(currentTemplate.structure)
                })
            },
            success: function(){
                callback();
            }
        });
    };

    var setSakaiDocPermissions = function(groupid, currentTemplate, callback){
        var filesArray = {};
        for (var doc in currentTemplate.structure){
            var definition = currentTemplate.structure[doc];
            var permission = "private";
            if ($.inArray("anonymous", definition._view) !== -1 && $newcreategroupCanBeFoundIn.val() === "public"){
                permission = "public";
            } else if ($.inArray("everyone", definition._view) !== -1 && ($newcreategroupCanBeFoundIn.val() === "public" || $newcreategroupCanBeFoundIn.val() === "logged-in-only")){
                permission = "everyone";
            }
            filesArray[definition._pid] = {
                "hashpath": definition._pid,
                "permissions": permission
            };
        }
        sakai.api.Content.setFilePermissions(filesArray, function(){
            var batchRequests = [];
            for (var doc in currentTemplate.structure) {
                var definition = currentTemplate.structure[doc];
                for (var i = 0; i < definition._view.length; i++){
                    if (definition._view[i].substring(0, 1) === "-") {
                        batchRequests.push({
                            "url": "/p/" + definition._pid + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": groupid + definition._view[i]
                            }
                        });
                    }
                }
                for (var j = 0; j < definition._edit.length; j++){
                    if (definition._edit[j].substring(0, 1) === "-") {
                        batchRequests.push({
                            "url": "/p/" + definition._pid + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":manager": groupid + definition._edit[j]
                            }
                        });
                    }
                }
            }
            sakai.api.Server.batch(batchRequests, function(success, data) {
                if (success) {
                    callback(groupid, currentTemplate);
                }
            });
        });
    };

    var fillSakaiDocs = function(groupid, currentTemplate, callback){
        var batchRequests = [];
        for (var doc in currentTemplate.structure){
            var definition = currentTemplate.structure[doc];
            var toCreate = currentTemplate.docs[definition._docref];
            delete toCreate.structure0;
            batchRequests.push({
                url: "/p/" + definition._pid + ".resource",
                method: "POST",
                parameters: {
                    ":operation": "import",
                    ":contentType": "json",
                    ":replace": true,
                    ":replaceProperties": true,
                    "_charset_": "utf-8",
                    ":content": $.toJSON(toCreate)
                }
            });
        }
        sakai.api.Server.batch(batchRequests, function(success, data) {
            if (success) {
                callback(groupid, currentTemplate);
            }
        });
    };

    var createSakaiDocs = function(groupid, currentTemplate, callback){
        var batchRequests = [];
        for (var doc in currentTemplate.structure){
            var definition = currentTemplate.structure[doc];
            var permission = "private";
            if ($.inArray("anonymous", definition._view) !== -1 && $newcreategroupCanBeFoundIn.val() === "public"){
                permission = "public";
            } else if ($.inArray("everyone", definition._view) !== -1 && ($newcreategroupCanBeFoundIn.val() === "public" || $newcreategroupCanBeFoundIn.val() === "logged-in-only")){
                permission = "everyone";
            }
            var toCreate = currentTemplate.docs[definition._docref];
            batchRequests.push({
                url: "/system/pool/createfile",
                method:"POST",
                parameters: {
                    "sakai:pooled-content-file-name": definition._title,
                    "sakai:description": "",
                    "sakai:permissions": permission,
                    "sakai:copyright": "creativecommons",
                    "structure0": $.toJSON(toCreate.structure0),
                    "mimeType": "x-sakai/document"
                }
            });
        }
        sakai.api.Server.batch(batchRequests, function(success, data) {
            if (success) {
                var count = 0;
                for (var doc in currentTemplate.structure){
                    var response = $.parseJSON(data.results[count].body);
                    currentTemplate.structure[doc]._pid = response._contentItem.poolId;
                    count++;
                }
                callback(groupid, currentTemplate);
            }
        });
    };

    /**
     * Add binding to the elements and validate the forms on submit
     */
    var addBinding = function(){
        $newcreategroupCreateSimpleGroupButton.bind("click", function(){
            $newcreategroupGroupForm.validate({
                submitHandler: function(form){
                    $newcreategroupContainer.find("select, input, textarea, button").attr("disabled","disabled");
                    doCreateSimpleGroup();
                }
            });
            $newcreategroupGroupForm.submit();
        });

        $newcreategroupGroupTitle.bind("keyup", function(){
            var suggestedURL = sakai.api.Util.makeSafeURL($(this).val(), "-");
            $newcreategroupSuggestedURL.val(suggestedURL);
            renderShareMessage();
        });

        $newcreategroupSuggestedURL.bind("blur", function(){
            var suggestedURL = sakai.api.Util.makeSafeURL($(this).val(), "-");
            $newcreategroupSuggestedURL.val(suggestedURL);
            renderShareMessage();
        });

        $newcreategroupAddPeople.live("click", function(){
            $(window).trigger("init.addpeople.sakai", [tuid]);
        });
    };

    /**
     * Initialize the create group widget
     */
    var doInit = function(){
        currentTemplate = sakai.api.Groups.getTemplate(widgetData.category, widgetData.id);
        $(".newcreategroup_template_name", $rootel).text(currentTemplate.title);
        $newcreategroupSuggestedURLBase.text(sakai.api.Util.applyThreeDots(window.location.protocol + "//" + window.location.host + "/~", 105, null, null, true));
        if (sakai.config.Permissions.Groups.defaultaccess){
            $("#newcreategroup_can_be_found_in [value=" + sakai.config.Permissions.Groups.defaultaccess + "]", $rootel).attr("selected", "selected");
        }
        $newcreategroupContainer.show();
        addBinding();
    };

    $newcreategroupCancelCreateButton.bind("click", function(){
        $.bbq.pushState({"_r": Math.random()});
    });

    $(window).bind("sakai.addpeople.usersselected", function(ev, initTuid, users){
        if (initTuid === tuid) {
            selectedUsers = $.extend(true, {}, users);
            $newcreategroupMembersAddedContainer.html(sakai.api.Util.TemplateRenderer(newcreategroupMembersSelectedTemplate, {
                "users": selectedUsers,
                "roles": currentTemplate.roles
            }));
            var count = 0;
            for (var item in selectedUsers) {
                count++;
            }
            if (count) {
                renderShareMessage();
                $newcreategroupGroupMembersNoneAddedContainer.hide();
                $newcreategroupMembersAddedContainer.show();
            } else {
                $newcreategroupGroupMembersNoneAddedContainer.show();
                $newcreategroupMembersAddedContainer.hide();
            }
        }
    });

    doInit();

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("newcreategroup");

});
<|endoftext|>