<commit_before>if (typeof SH === 'undefined' || !SH) {
  var SH = {};
}

(function($) {
  SH.map = function () {
    var map,
        infoWindow = new google.maps.InfoWindow(),
        geocoder = new google.maps.Geocoder(),
        youMarkerCollection = new Array(),
        needMarkerCollection = new Array(),
        userLocation,
        _self;

    var markerShadow = new google.maps.MarkerImage('/img/marker_shadow.png',
      new google.maps.Size(51.0, 37.0),
      new google.maps.Point(16, 16),
      new google.maps.Point(0, 22));

    _self = {
      create: function (options) {
        var settings = {
              mapId: 'map',
              zoom: 14,
              center: new google.maps.LatLng(39.95240, -75.16362),
              mapTypeId: google.maps.MapTypeId.ROADMAP
            };

        if (options) {
          $.extend(settings, options);
        }
        map = new google.maps.Map(document.getElementById(settings.mapId), settings);
      },

      getShelters: function (userLocation) {

        var lat = parseFloat(userLocation.lat());
        var lng = parseFloat(userLocation.lng());

        $.ajax({
        url: '_map?lat=' + lat + '&long=' + lng,
        context: document.body,
        success: function(){
           console.log('got it!');
          }
        });

      },

      addShelters: function (shelters) {
        var i,
            lat,
            lng,
            latlng,
            sheltersLength = shelters.shelters.length;

        _self.removeMarkers(needMarkerCollection);

        for (i=0; i<sheltersLength; i++) {
          lat = shelters.shelters[i].lat;
          lng = shelters.shelters[i].lng;
          latlng = new google.maps.LatLng(lat, lng);

          _self.createMarker(latlng, shelters.shelters[i].desc, {icon: '/img/shelter.png', shadow: markerShadow});
        }
      },

      createMarker: function (latlng, description, options) {
        var settings = {
              position: latlng,
              map: map,
          };

        if (options) {
          $.extend(settings, options);
        }

        var marker = new google.maps.Marker(settings);

        needMarkerCollection.push(marker);

        google.maps.event.addListener(marker, 'click', function() {
          infoWindow.close();
          infoWindow.setContent(description);
          infoWindow.open(map,marker);
        });

        if (description === 'Your Location') { //TODO: this is fragile.
          google.maps.event.addListener(marker, 'dragend', function () {
            //recalc distance to needs when marker is dragged
          });

           _self.removeMarkers(youMarkerCollection)
          youMarkerCollection.push(marker);
        }
      },

      orientUser: function () {
        //var userLocation = null;

        // Try W3C Geolocation
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(function(position) {
            userLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
            _self.create({ center: userLocation });
            _self.getShelters(userLocation);
            _self.addShelters(shelters);
            _self.createMarker(userLocation, 'Your Location', {
              animation: google.maps.Animation.DROP,
              draggable: true,
              icon: '/img/you.png',
              shadow: markerShadow
            });
          }, function() {
            _self.create();
          });
        }

        return userLocation;
      },

      updateMapCenter: function (latLongObj) {
        map.setCenter(latLongObj);
      },

      geocode: function (addr, description) {
        var lat,
            lng,
            latlng;

        geocoder.geocode({
          'address': addr,
        }, function (results, status) {
          if (status === google.maps.GeocoderStatus.OK) {
            _self.createMarker(results[0].geometry.location, 'Your Location',  {
              animation: google.maps.Animation.DROP,
              draggable: true,
              icon: '/img/you.png',
              shadow: markerShadow
            });
          }
        });
      },

      removeMarkers: function(markerArray) {
        if (markerArray) {
          for (i in markerArray) {
            markerArray[i].setMap(null);
          }
          markerArray.length = 0;
        }
      }

    };

    return _self;
  };
})(jQuery);
<commit_msg>Shelters from cloudmine being plotted on map<commit_after>if (typeof SH === 'undefined' || !SH) {
  var SH = {};
}

(function($) {
  SH.map = function () {
    var map,
        infoWindow = new google.maps.InfoWindow(),
        geocoder = new google.maps.Geocoder(),
        youMarkerCollection = new Array(),
        needMarkerCollection = new Array(),
        userLocation,
        _self;

    var markerShadow = new google.maps.MarkerImage('/img/marker_shadow.png',
      new google.maps.Size(51.0, 37.0),
      new google.maps.Point(16, 16),
      new google.maps.Point(0, 22));

    _self = {
      create: function (options) {
        var settings = {
              mapId: 'map',
              zoom: 14,
              center: new google.maps.LatLng(39.95240, -75.16362),
              mapTypeId: google.maps.MapTypeId.ROADMAP
            };

        if (options) {
          $.extend(settings, options);
        }
        map = new google.maps.Map(document.getElementById(settings.mapId), settings);
      },

      getShelters: function (userLocation) {

        var lat = parseFloat(userLocation.lat());
        var lng = parseFloat(userLocation.lng());

        $.ajax({
        url: '_map?lat=' + lat + '&long=' + lng,
        context: document.body,
        success: function(data){
           _self.addShelters(data);
          }
        });

      },

      addShelters: function (shelters) {
        var i,
            lat,
            lng,
            latlng,
            sheltersLength = shelters.result.length;

        _self.removeMarkers(needMarkerCollection);

        for (i=0; i<sheltersLength; i++) {
          lat = shelters.result[i].Latitude;
          lng = shelters.result[i].Longitude;
          latlng = new google.maps.LatLng(lat, lng);

          _self.createMarker(latlng, shelters.result[i].Name, {icon: '/img/shelter.png', shadow: markerShadow});
        }
      },

      createMarker: function (latlng, description, options) {
        var settings = {
              position: latlng,
              map: map,
          };

        if (options) {
          $.extend(settings, options);
        }

        var marker = new google.maps.Marker(settings);

        google.maps.event.addListener(marker, 'click', function() {
          infoWindow.close();
          infoWindow.setContent(description);
          infoWindow.open(map,marker);
        });

        if (description === 'Your Location') { //TODO: this is fragile.
          google.maps.event.addListener(marker, 'dragend', function () {
            //recalc distance to needs when marker is dragged
          });

           _self.removeMarkers(youMarkerCollection)
          youMarkerCollection.push(marker);
        } else {
          needMarkerCollection.push(marker);
        }
      },

      orientUser: function () {
        //var userLocation = null;

        // Try W3C Geolocation
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(function(position) {
            userLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
            _self.create({ center: userLocation });
            _self.getShelters(userLocation);
            _self.createMarker(userLocation, 'Your Location', {
              animation: google.maps.Animation.DROP,
              draggable: true,
              icon: '/img/you.png',
              shadow: markerShadow
            });
          }, function() {
            _self.create();
          });
        }

        return userLocation;
      },

      updateMapCenter: function (latLongObj) {
        map.setCenter(latLongObj);
      },

      geocode: function (addr, description) {
        var lat,
            lng,
            latlng;

        geocoder.geocode({
          'address': addr,
        }, function (results, status) {
          if (status === google.maps.GeocoderStatus.OK) {
            _self.createMarker(results[0].geometry.location, 'Your Location',  {
              animation: google.maps.Animation.DROP,
              draggable: true,
              icon: '/img/you.png',
              shadow: markerShadow
            });
          }
        });
      },

      removeMarkers: function(markerArray) {
        if (markerArray) {
          for (i in markerArray) {
            markerArray[i].setMap(null);
          }
          markerArray.length = 0;
        }
      }

    };

    return _self;
  };
})(jQuery);
<|endoftext|>


<commit_before>import environment from '../common/helpers/environment';

// Temporary hack to use GIDS on localhost directly
// (instead of vets-api)
function getAPIUrl(useLocalGidsURL) {
  const localGidsApiURL = 'https://dev-api.vets.gov/v0/gi'; // 'http://localhost:5000/v0';
  const it = useLocalGidsURL ? localGidsApiURL : `${environment.API_URL}/v0/gi`;
  return it;
}

module.exports = {
  // Base URL to be used in API requests.
  api: {
    url: getAPIUrl(true),
    settings: {
      headers: {
        'Content-Type': 'application/json',
        // 'X-Key-Inflection': 'camel',
      }
    }
  }
};
<commit_msg>Remove temporary local GIDS API override (#5105)<commit_after>import environment from '../common/helpers/environment';

module.exports = {
  // Base URL to be used in API requests.
  api: {
    url: `${environment.API_URL}/v0/gi`,
    settings: {
      headers: {
        'Content-Type': 'application/json',
        // 'X-Key-Inflection': 'camel',
      }
    }
  }
};
<|endoftext|>


<commit_before>"use strict";
///
/// socket events
///

var Socket = Socket || {};

var target = window.location.protocol + '//' + window.location.hostname + ':8080';
Socket.socket = io.connect(target);

Socket.socket.on('topology-change', function (data) {
	Sonos.grouping = {};
	var stateTime = new Date().valueOf();
	var shouldRenderVolumes = false;
	data.forEach(function (player) {
		player.stateTime = stateTime;
		Sonos.players[player.uuid] = player;
		if (!Sonos.grouping[player.coordinator]) Sonos.grouping[player.coordinator] = [];
		Sonos.grouping[player.coordinator].push(player.uuid);
	});

	console.log("topology-change", Sonos.grouping, Sonos.players);

	// If the selected group dissappeared, select a new one.
	if (!Sonos.grouping[Sonos.currentState.selectedZone]) {
		// just get first zone available
		for (var uuid in Sonos.grouping) {
			Sonos.currentState.selectedZone = uuid;
			break;
		}
		// we need queue as well!
		Socket.socket.emit('queue', {uuid:Sonos.currentState.selectedZone});
		shouldRenderVolumes = true;
	}

	if (Socket.topologyChanged instanceof Function) Socket.topologyChanged(shouldRenderVolumes);
});

Socket.socket.on('transport-state', function (player) {
	player.stateTime = new Date().valueOf();
	Sonos.players[player.uuid] = player;

	if (Socket.transportStateChanged instanceof Function) Socket.transportStateChanged(player);

});

Socket.socket.on('group-volume', function (data) {

	Sonos.players[data.uuid].groupState.volume = data.groupState.volume;

	if (Socket.groupVolumeChanged instanceof Function) Socket.groupVolumeChanged(data);
});

Socket.socket.on('group-mute', function (data) {
	Sonos.players[data.uuid].groupState = data.state;
	if (Socket.groupMuteChanged instanceof Function) Socket.groupMuteChanged(data);
});

Socket.socket.on('mute', function (data) {
	var player = Sonos.players[data.uuid];
	player.state.mute = data.state.mute;
	if (Socket.muteChanged instanceof Function) Socket.muteChanged(data);
});

Socket.socket.on('favorites', function (data) {
	if (Socket.favoritesChanged instanceof Function) Socket.favoritesChanged(data);
});

Socket.socket.on('queue', function (data) {
	if (Socket.queueChanged instanceof Function) Socket.queueChanged(data);
});

Socket.socket.on('search-result', function (data) {
	if (Socket.searchResultReceived instanceof Function) Socket.searchResultReceived(data);
})
<commit_msg>port via browser url<commit_after>"use strict";
///
/// socket events
///

var Socket = Socket || {};

var target = window.location.protocol + '//' + window.location.hostname +
(window.location.port != '' ? ':' + window.location.port : '');
Socket.socket = io.connect(target);

Socket.socket.on('topology-change', function (data) {
	Sonos.grouping = {};
	var stateTime = new Date().valueOf();
	var shouldRenderVolumes = false;
	data.forEach(function (player) {
		player.stateTime = stateTime;
		Sonos.players[player.uuid] = player;
		if (!Sonos.grouping[player.coordinator]) Sonos.grouping[player.coordinator] = [];
		Sonos.grouping[player.coordinator].push(player.uuid);
	});

	console.log("topology-change", Sonos.grouping, Sonos.players);

	// If the selected group dissappeared, select a new one.
	if (!Sonos.grouping[Sonos.currentState.selectedZone]) {
		// just get first zone available
		for (var uuid in Sonos.grouping) {
			Sonos.currentState.selectedZone = uuid;
			break;
		}
		// we need queue as well!
		Socket.socket.emit('queue', {uuid:Sonos.currentState.selectedZone});
		shouldRenderVolumes = true;
	}

	if (Socket.topologyChanged instanceof Function) Socket.topologyChanged(shouldRenderVolumes);
});

Socket.socket.on('transport-state', function (player) {
	player.stateTime = new Date().valueOf();
	Sonos.players[player.uuid] = player;

	if (Socket.transportStateChanged instanceof Function) Socket.transportStateChanged(player);

});

Socket.socket.on('group-volume', function (data) {

	Sonos.players[data.uuid].groupState.volume = data.groupState.volume;

	if (Socket.groupVolumeChanged instanceof Function) Socket.groupVolumeChanged(data);
});

Socket.socket.on('group-mute', function (data) {
	Sonos.players[data.uuid].groupState = data.state;
	if (Socket.groupMuteChanged instanceof Function) Socket.groupMuteChanged(data);
});

Socket.socket.on('mute', function (data) {
	var player = Sonos.players[data.uuid];
	player.state.mute = data.state.mute;
	if (Socket.muteChanged instanceof Function) Socket.muteChanged(data);
});

Socket.socket.on('favorites', function (data) {
	if (Socket.favoritesChanged instanceof Function) Socket.favoritesChanged(data);
});

Socket.socket.on('queue', function (data) {
	if (Socket.queueChanged instanceof Function) Socket.queueChanged(data);
});

Socket.socket.on('search-result', function (data) {
	if (Socket.searchResultReceived instanceof Function) Socket.searchResultReceived(data);
})
<|endoftext|>


<commit_before>function highlight(evt){
    var tag = $(evt.target).prop("name");
    $("div#source-text").unhighlight();

    // highlight a beginning tag (two cases)
    $("div#source-text").highlight("<"+tag +">");
    $("div#source-text").highlight("<"+tag +" ");

    // highlight an ending tag
    $("div#source-text").highlight("</"+tag+">");

    $("#tag-info").empty();
    $("#tag-info").html(""+tag+" tag is highlighted");
}

$(function() {

    function displayTagCount(data){
        $("#tag-count-header").show();
        $("#tag-count-loading").hide();

        // iterate through the object of tags and counts
        $.each( data, function( key, value ) {
          $("#tag-count").append( ""+key +""+ ": " + value+" time(s)
" );
        });
    }

    function displaySourceText(data){
        $("#source-text-header").show();
        $("#source-text-loading").hide();
        $("#source-text").html(data);
        $("#submit-btn").removeAttr("disabled");

        // show TOP buttom (at bottom of source text)
        $("#top-btn").show();
    }

    function executeSearch(){

        var url = {
            "source": $("#source").val()
        };

        // AJAX calls - fill in tag counts and source text of URL
        $.get("/count-tags.json", url, displayTagCount);
        $.get("/source-text.json", url, displaySourceText);

        // get rid of previous content
        $("#tag-count").empty();
        $("#source-text").empty();
        $("#tag-info").empty();

        // loading wheels in each section
        $("#tag-count-loading").show();
        $("#source-text-loading").show();

        // show the div tag that has all tag count / source text info
        $("#tag").show();

        // scroll
        window.location = "#tag";

    }

    function checkAnswer(data){

        // URL
        var source = $("#source").val();

        // if the URL is valid
        if(data === "True"){

            // the user is searching for http://textsource.herokuapp.com
            if(source.indexOf("http://textsource.herokuapp.com") != -1){
                $('#myModal').modal('show');

                // enable search again
                $("#submit-btn").removeAttr("disabled");

            }

            // if the site's URL has not been entered
            else{
                alert("source is "+ source);
                executeSearch();
            }

        }

        // if the URL is not valid
        else{

            // checks to see if there is an http in the address and there isn't
            // capture both upper and lower case
            if (source.indexOf("http") == -1 || source.indexOf("HTTP") == -1){
                $("#warning").show();
                $("#warning").html(" This is not a valid URL
Try adding 'http://' or 'https://' to the beginning");
            }

            // has http in addresss
            else{
                $("#warning").show();
                $("#warning").html(" This is not a valid URL");
            }

            // enable search again
            $("#submit-btn").removeAttr("disabled");

            // hide div with tag count and source text
            $("#tag").hide();
        }

    }

    function checkUrl(evt){
        evt.preventDefault();

        // disable button
        $("#submit-btn").prop("disabled", "true");

        // hide/clear the warning text
        $("#warning").hide().empty();

        var url = {
            "source": $("#source").val()
        };

        $.get("/check-url.json", url, checkAnswer);
    }

    // event listener for URL submission
    $("#input-form").on("submit", checkUrl);

    // hide warning box (even if empty, has opaque borders that show)
    $("#warning").hide();

});
<commit_msg>took out the JS 'on ready' to test<commit_after>function highlight(evt){
    var tag = $(evt.target).prop("name");
    $("div#source-text").unhighlight();

    // highlight a beginning tag (two cases)
    $("div#source-text").highlight("<"+tag +">");
    $("div#source-text").highlight("<"+tag +" ");

    // highlight an ending tag
    $("div#source-text").highlight("</"+tag+">");

    $("#tag-info").empty();
    $("#tag-info").html(""+tag+" tag is highlighted");
}

// $(function() {

    function displayTagCount(data){
        $("#tag-count-header").show();
        $("#tag-count-loading").hide();

        // iterate through the object of tags and counts
        $.each( data, function( key, value ) {
          $("#tag-count").append( ""+key +""+ ": " + value+" time(s)
" );
        });
    }

    function displaySourceText(data){
        $("#source-text-header").show();
        $("#source-text-loading").hide();
        $("#source-text").html(data);
        $("#submit-btn").removeAttr("disabled");

        // show TOP buttom (at bottom of source text)
        $("#top-btn").show();
    }

    function executeSearch(){

        var url = {
            "source": $("#source").val()
        };

        // AJAX calls - fill in tag counts and source text of URL
        $.get("/count-tags.json", url, displayTagCount);
        $.get("/source-text.json", url, displaySourceText);

        // get rid of previous content
        $("#tag-count").empty();
        $("#source-text").empty();
        $("#tag-info").empty();

        // loading wheels in each section
        $("#tag-count-loading").show();
        $("#source-text-loading").show();

        // show the div tag that has all tag count / source text info
        $("#tag").show();

        // scroll
        window.location = "#tag";

    }

    function checkAnswer(data){

        // URL
        var source = $("#source").val();

        // if the URL is valid
        if(data === "True"){

            // the user is searching for http://textsource.herokuapp.com
            if(source.indexOf("http://textsource.herokuapp.com") != -1){
                $('#myModal').modal('show');

                // enable search again
                $("#submit-btn").removeAttr("disabled");

            }

            // if the site's URL has not been entered
            else{
                alert("source is "+ source);
                executeSearch();
            }

        }

        // if the URL is not valid
        else{

            // checks to see if there is an http in the address and there isn't
            // capture both upper and lower case
            if (source.indexOf("http") == -1 || source.indexOf("HTTP") == -1){
                $("#warning").show();
                $("#warning").html(" This is not a valid URL
Try adding 'http://' or 'https://' to the beginning");
            }

            // has http in addresss
            else{
                $("#warning").show();
                $("#warning").html(" This is not a valid URL");
            }

            // enable search again
            $("#submit-btn").removeAttr("disabled");

            // hide div with tag count and source text
            $("#tag").hide();
        }

    }

    function checkUrl(evt){
        evt.preventDefault();

        // disable button
        $("#submit-btn").prop("disabled", "true");

        // hide/clear the warning text
        $("#warning").hide().empty();

        var url = {
            "source": $("#source").val()
        };

        $.get("/check-url.json", url, checkAnswer);
    }

    // event listener for URL submission
    $("#input-form").on("submit", checkUrl);

    // hide warning box (even if empty, has opaque borders that show)
    $("#warning").hide();

// });
<|endoftext|>


<commit_before>var side = 100
var cos = Math.cos
var sin = Math.sin
var pi = Math.PI
function degToRad(a) { return a*pi/180 }

var thinrhomb = function() {
    this.theta = degToRad(36)
    this.alpha = degToRad(144)
    this.color = "#0000FF"

    this.points = [
        [0,0],
        [ side*cos(this.theta/2), side*sin(this.theta/2) ],
        [ 2*side*cos(this.theta/2), 0],
        [ side*cos(this.theta/2), -side*sin(this.theta/2) ]
    ]
    this.drawFun = function(canvas) {
        pointsStr = ""
        for(var i=0; i<this.points.length; i++){
            pointsStr += this.points[i].toString() + " "
        }
        return canvas.append("polygon")
            .attr("points", pointsStr)
            .attr({ fill: this.color })
    }
    this.drawable = this.drawFun( d3.select("svg") )
}

// universal prototype for rhombs
var rhomb = function() {}
rhomb.prototype = {
    points : function() { return [
        [0,0],
        [ side*cos(this.theta/2), side*sin(this.theta/2) ],
        [ 2*side*cos(this.theta/2), 0],
        [ side*cos(this.theta/2), -side*sin(this.theta/2) ]
    ] },
    drawFun : function(canvas) {
        pointsStr = ""
        for(var i=0; i<this.points.length; i++){
            pointsStr += this.points[i].toString() + " "
        }
        this.drawable = canvas.append("polygon")
            .attr("points", pointsStr)
            .attr({ fill: this.color })
        return this.drawable
    },
    drawable : null, // nothing until we're drawn
    center : function () {
        obj = this.drawable.node()
        bbox = $(obj)[0].getBBox()
        x = bbox.x + bbox.width/2
        y = bbox.y + bbox.height/2
        return [x,y]
    },
    rotate : function(ang) {
        center = this.center()
        this.drawable.attr("transform", "rotate("+ang+" "+center[0]+" "+center[1]+")")
    }
}

var thickrhomb = function() {
    this.theta = degToRad(72)
    this.alpha = degToRad(108)
    this.points = this.points()

    this.color = "#FF0000"
}
thickrhomb.prototype = rhomb.prototype

var thinrhomb = function() {
    this.theta = degToRad(36)
    this.alpha = degToRad(144)
    this.points = this.points()

    this.color = "#0000FF"
}
thinrhomb.prototype = rhomb.prototype

<commit_msg>position and orientation fixins<commit_after>var side = 100
var cos = Math.cos
var sin = Math.sin
var pi = Math.PI
function degToRad(a) { return a*pi/180 }

var thinrhomb = function() {
    this.theta = degToRad(36)
    this.alpha = degToRad(144)
    this.color = "#0000FF"

    this.points = [
        [0,0],
        [ side*cos(this.theta/2), side*sin(this.theta/2) ],
        [ 2*side*cos(this.theta/2), 0],
        [ side*cos(this.theta/2), -side*sin(this.theta/2) ]
    ]
    this.drawFun = function(canvas) {
        pointsStr = ""
        for(var i=0; i<this.points.length; i++){
            pointsStr += this.points[i].toString() + " "
        }
        return canvas.append("polygon")
            .attr("points", pointsStr)
            .attr({ fill: this.color })
    }
    this.drawable = this.drawFun( d3.select("svg") )
}

// universal prototype for rhombs
var rhomb = function() {}
rhomb.prototype = {
    points : function() { return [
        [0,0],
        [ side*cos(this.theta/2), side*sin(this.theta/2) ],
        [ 2*side*cos(this.theta/2), 0],
        [ side*cos(this.theta/2), -side*sin(this.theta/2) ]
    ] },
    drawFun : function(canvas) {
        pointsStr = ""
        for(var i=0; i<this.points.length; i++){
            pointsStr += this.points[i].toString() + " "
        }
        this.drawable = canvas.append("polygon")
            .attr("points", pointsStr)
            .attr({ fill: this.color })
        this.update() // we wanna be in the right place/orientation
        return this.drawable
    },
    drawable : null, // nothing until we're drawn
    bbox : function () {
        obj = this.drawable.node()
        bbox = $(obj)[0].getBBox()
        return bbox
    },
    update : function() {
        bbox = this.bbox()
        center = [ bbox.x + bbox.width/2, bbox.y + bbox.height/2 ]
        ang = this.rotation
        this.drawable.attr("transform",
                // order matters!
                "translate("+this.position.toString()+") " +
                "rotate("+ang+" "+center[0]+" "+center[1]+") "
                )
    },
    translate: function(offset) {
        this.position[0] += offset[0]
        this.position[1] += offset[1]
        this.update()
    },
    setTranslation: function(pos) {
        this.position = pos
        this.update()
    },
    setRotation: function(ang) {
        this.rotation = ang
        this.update()
    },
    rotate : function(ang) {
        this.rotation += ang
        this.update()
    },
    position: [0,0],
    rotation: 0
}

var thickrhomb = function() {
    this.theta = degToRad(72)
    this.alpha = degToRad(108)
    this.points = this.points()
    this.position = [0,50]

    this.color = "#FF0000"
}
thickrhomb.prototype = rhomb.prototype

var thinrhomb = function() {
    this.theta = degToRad(36)
    this.alpha = degToRad(144)
    this.points = this.points()
    this.position = [0,50]

    this.color = "#0000FF"
}
thinrhomb.prototype = rhomb.prototype

thin = new thinrhomb(); thin.drawFun( d3.select("svg") )
thick = new thickrhomb(); thick.drawFun( d3.select("svg") )
<|endoftext|>


<commit_before>import Content from './components/Content';
import Handles from './components/handles/index';
import Overlay from './components/Overlay';

import {hasValue} from './utils/Object';
import {cell, isElement} from './utils/Dom';
import {MODES, STATES} from './constants';

let scope = Object.seal({
    $$parent : null,
    $$state : STATES.OFFLINE,
    meta : {
        dimensions : {
            x : 0,
            x2 : 0,
            y : 0,
            y2 : 0,
            w : 0,
            h : 0,
        },
        ratio : {
            w : 1,
            h : 1,
        },
    },
    elements : {
        content : null,
        overlay : null,
        handles : null
    },
    options : {
        update_cb : () => {},
        create_cb : () => {},
        destroy_cb : () => {},
        min_crop_width : 32,
        min_crop_height : 32,
        max_width : 500,
        max_height : 500,
        fixed_size : false,
        mode : MODES.SQUARE,
    },
});

function render () {
    if (scope.$$state !== STATES.LOADING) return;

    const img = scope.elements.content.$$source;

    //  Calculate width and height based on max-width and max-height
    let {naturalWidth : w, naturalHeight : h} = img;

    if (w > scope.options.max_width) {
        h = ~~(scope.options.max_width * h / w);
        w = scope.options.max_width;
    }

    if (h > scope.options.max_height) {
        w = ~~(scope.options.max_height * w / h);
        h = scope.options.max_height;
    }

    //  Set ratio to use in processing afterwards ( this is based on original image size )
    scope.meta.ratio = {
        w : Math.round((img.naturalWidth / w) * 100) / 100,
        h : Math.round((img.naturalHeight / h) * 100) / 100,
    };

    //  Set width/height
    img.width = w;
    img.height = h;

    scope.$$state = STATES.READY;

    //  Initialize dimensions
    scope.meta.dimensions.x2 = scope.meta.dimensions.w = w;
    scope.meta.dimensions.y2 = scope.meta.dimensions.h = h;

    update();
}

function update (evt) {
    if (scope.$$state !== STATES.READY) return;
    if (evt) evt.stopPropagation();

    const {dimensions : dim} = scope.meta;

    //  boundary collision checks
    if (dim.x < 0) dim.x = 0;
    if (dim.y < 0) dim.y = 0;
    if (dim.x2 > dim.w) dim.x2 = dim.w;
    if (dim.y2 > dim.h) dim.y2 = dim.h;

    //  Patch updates
    scope.elements.overlay.update(dim, scope.options);
    scope.elements.handles.update(dim, scope.options);
}

export default class ImageCropper {
    constructor (selector, href, opts = {}) {
        if (!href || !selector) return;

        //  Parse options
        Object.keys(opts || {}).forEach((key) => scope.options[key] = opts[key]);

        //  Set parent
        const el = document.querySelector(selector);

        if (!isElement(el)) throw new TypeError('Does the parent exist?');

        scope.$$parent = el;
        scope.$$parent.classList.add('imgc');

        //  Create a Content instance
        scope.$$parent.addEventListener('DOMNodeRemovedFromDocument', this.destroy);
        scope.$$parent.addEventListener('source:fetched', render, true);
        scope.$$parent.addEventListener('source:dimensions', update, true);

        //  Create Wrapper elements
        scope.elements.content = new Content(scope);
        scope.elements.overlay = new Overlay(scope);
        scope.elements.handles = new Handles(scope);

        this.setImage(href);
    }

    setImage (href) {
        scope.$$state = STATES.LOADING;
        scope.elements.content.source(href);
    }

    destroy () {
        scope.$$state = STATES.OFFLINE;

        if (isElement(scope.$$parent)) {
            while (scope.$$parent.firstChild) {
                scope.$$parent.removeChild(scope.$$parent.firstChild);
            }

            //  Clean parent
            scope.$$parent.classList.remove('imgc');
        }
    }

    crop (mime_type = 'image/jpeg', quality = 1) {
        mime_type = hasValue(['image/jpeg', 'image/png'], mime_type)
            ? 'image/jpeg'
            : mime_type;

        quality = (quality < 0 || quality > 1)
            ? 1
            : quality;

        const {x, y, x2, y2} = scope.meta.dimensions;
        const {w : rw, h : rh} = scope.meta.ratio;
        const w = x2 - x;   //  width
        const h = y2 - y;   //  height

        const canvas = cell('canvas', null, {
            width : w,
            height : h
        });

        canvas.getContext('2d').drawImage(document.querySelector('img'), rw * x, rh * y, rw * w, rh * h, 0, 0, w, h);

        return canvas.toDataURL(mime_type, quality);
    }
}
<commit_msg>re-add callbacks<commit_after>import Content from './components/Content';
import Handles from './components/handles/index';
import Overlay from './components/Overlay';

import {hasValue} from './utils/Object';
import {cell, isElement} from './utils/Dom';
import {MODES, STATES} from './constants';

let scope = Object.seal({
    $$parent : null,
    $$state : STATES.OFFLINE,
    meta : {
        dimensions : {
            x : 0,
            x2 : 0,
            y : 0,
            y2 : 0,
            w : 0,
            h : 0,
        },
        ratio : {
            w : 1,
            h : 1,
        },
    },
    elements : {
        content : null,
        overlay : null,
        handles : null
    },
    options : {
        update_cb : () => {},
        create_cb : () => {},
        destroy_cb : () => {},
        min_crop_width : 32,
        min_crop_height : 32,
        max_width : 500,
        max_height : 500,
        fixed_size : false,
        mode : MODES.SQUARE,
    },
});

function render () {
    if (scope.$$state !== STATES.LOADING) return;

    const img = scope.elements.content.$$source;

    //  Calculate width and height based on max-width and max-height
    let {naturalWidth : w, naturalHeight : h} = img;

    if (w > scope.options.max_width) {
        h = ~~(scope.options.max_width * h / w);
        w = scope.options.max_width;
    }

    if (h > scope.options.max_height) {
        w = ~~(scope.options.max_height * w / h);
        h = scope.options.max_height;
    }

    //  Set ratio to use in processing afterwards ( this is based on original image size )
    scope.meta.ratio = {
        w : Math.round((img.naturalWidth / w) * 100) / 100,
        h : Math.round((img.naturalHeight / h) * 100) / 100,
    };

    //  Set width/height
    img.width = w;
    img.height = h;

    scope.$$state = STATES.READY;

    //  Initialize dimensions
    scope.meta.dimensions.x2 = scope.meta.dimensions.w = w;
    scope.meta.dimensions.y2 = scope.meta.dimensions.h = h;

    update();

    scope.options.create_cb({w, h});
}

function update (evt) {
    if (scope.$$state !== STATES.READY) return;
    if (evt) evt.stopPropagation();

    const {dimensions : dim} = scope.meta;

    //  boundary collision checks
    if (dim.x < 0) dim.x = 0;
    if (dim.y < 0) dim.y = 0;
    if (dim.x2 > dim.w) dim.x2 = dim.w;
    if (dim.y2 > dim.h) dim.y2 = dim.h;

    //  Patch updates
    scope.elements.overlay.update(dim, scope.options);
    scope.elements.handles.update(dim, scope.options);

    scope.options.update_cb(dim);
}

export default class ImageCropper {
    constructor (selector, href, opts = {}) {
        if (!href || !selector) return;

        //  Parse options
        Object.keys(opts || {}).forEach((key) => scope.options[key] = opts[key]);

        //  Set parent
        const el = document.querySelector(selector);

        if (!isElement(el)) throw new TypeError('Does the parent exist?');

        scope.$$parent = el;
        scope.$$parent.classList.add('imgc');

        //  Create a Content instance
        scope.$$parent.addEventListener('DOMNodeRemovedFromDocument', this.destroy);
        scope.$$parent.addEventListener('source:fetched', render, true);
        scope.$$parent.addEventListener('source:dimensions', update, true);

        //  Create Wrapper elements
        scope.elements.content = new Content(scope);
        scope.elements.overlay = new Overlay(scope);
        scope.elements.handles = new Handles(scope);

        this.setImage(href);
    }

    setImage (href) {
        scope.$$state = STATES.LOADING;
        scope.elements.content.source(href);
    }

    destroy () {
        scope.$$state = STATES.OFFLINE;

        if (isElement(scope.$$parent)) {
            while (scope.$$parent.firstChild) {
                scope.$$parent.removeChild(scope.$$parent.firstChild);
            }

            //  Clean parent
            scope.$$parent.classList.remove('imgc');
        }

        scope.options.destroy_cb();
    }

    crop (mime_type = 'image/jpeg', quality = 1) {
        mime_type = hasValue(['image/jpeg', 'image/png'], mime_type)
            ? 'image/jpeg'
            : mime_type;

        quality = (quality < 0 || quality > 1)
            ? 1
            : quality;

        const {x, y, x2, y2} = scope.meta.dimensions;
        const {w : rw, h : rh} = scope.meta.ratio;
        const w = x2 - x;   //  width
        const h = y2 - y;   //  height

        const canvas = cell('canvas', null, {
            width : w,
            height : h
        });

        canvas.getContext('2d').drawImage(document.querySelector('img'), rw * x, rh * y, rw * w, rh * h, 0, 0, w, h);

        return canvas.toDataURL(mime_type, quality);
    }
}
<|endoftext|>


<commit_before>const electron = require( 'electron' );
const path = require( 'path' );
const url = require( 'url' );
const config = require( './config.js' );
const cache = require( './cache.js' );

// global reference to the main window
var win = null;

/**
 * Register a custom file protocol handler that will open files from the given directory
 * @param {*} protocol
 * @param {*} directory
 */
function registerCacheProtocol( protocol, directory ) {
    electron.protocol.registerFileProtocol( protocol, ( request, callback ) => {
        // build full path (replace backslashes by forward slashes)
        callback( { path: path.normalize( path.join( directory, url.parse( request.url ).pathname ) ) } );
    } );
}

/**
 * Open and configure the main window of the application
 */
function activateWindow() {

    if ( win !== null ) {
        return;
    }

    registerCacheProtocol( config.cache.url.protocol, config.cache.directory );

    win = new electron.BrowserWindow( {
        width: 1120,
        height: 680,
        webPreferences: {
            experimentalFeatures: true,
            nodeIntegration: true,
            webSecurity: false // required to open local images in browser
        }
    } );

    // inject headers before a request is made (call the handler in the webapp to do the dirty work)
    electron.session.defaultSession.webRequest.onBeforeSendHeaders( ['http*://*'], ( details, callback ) => {
        ( new Promise( (resolve, reject ) => {
            // prevent from injecting javascript into the webpage while the webcontent is not yet ready
            // => required for loading initial page over http protocol (e.g. local hosted test page)
            if( win && win.webContents && !win.webContents.isLoading() ) {
                resolve();
            } else {
                throw new Error( 'Cannot inject javascript while web-app is not yet ready!' );
            }
        } ) )
        .then( () => {
            // inject javascript: looks stupid, but is a working solution to call a function
            // directly within the render process (without dealing with ipcRenderer)
            let payload = Buffer.from( JSON.stringify( details ) ).toString( 'base64' );
            return win.webContents.executeJavaScript( `Engine.Request.onBeforeSendHeadersHandler('${payload}');` );
        } )
        .then( result => {
            callback( {
                cancel: false,
                requestHeaders: result.requestHeaders
            } );
        } )
        .catch( error => {
            callback( {
                cancel: false,
                requestHeaders: details.requestHeaders
            } );
        } );
    } );

    win.setMenu( null );

    let load = () => {
        win.loadURL( config.cache.url.href );
        if( config.app.developer ) {
            win.webContents.openDevTools();
        }
    };

    cache.update( config.app.url.href, config.cache.directory )
    .then( version => {
        load();
        electron.dialog.showMessageBox( win, {
            type: 'info',
            message: 'HakuNeko has been updated\nrev.' + version,
            buttons: ['OK']
        }, ( button, checkbox ) => {} );
    } )
    .catch( error => {
        load();
        if( error ) {
            console.error( error );
        }
    } );

    win.on( 'closed', () => {
        // close all existing windows
        electron.BrowserWindow.getAllWindows().forEach( window => window.close() );
        win = null;
    } );
}

/**
 * Quit aplication, except for OSX
 */
function closeWindow () {
    electron.app.quit();
}

/************************
 *** MAIN ENTRY POINT ***
 ************************/

// Disabling GPU acceleration to possibly prevent chromiums 'blank screen' bug
// it seems the --disable-gpu flag did not solve problems for windows user (blank screen)
// => no need to disable gpu if it still not solves the problem ...
//electron.app.disableHardwareAcceleration();

// add HakuNeko's application directory to the environment variable path (make ffmpeg available on windows)
process.env.PATH += ( process.platform === 'win32' ? ';' : ':' ) + path.dirname( process.execPath );

// register new protocol handler as standard handler to host files locally without web server
// => required to enable access to chromium specific features such as local store, indexedDB, ...
electron.protocol.registerStandardSchemes( [config.cache.url.protocol] );

// update userdata path (e.g. for portable version)
electron.app.setPath( 'userData', config.app.userdata );

// connect events
//electron.app.addEventListener(;
electron.app.on( 'ready', activateWindow );
electron.app.on( 'activate', activateWindow );
electron.app.on( 'window-all-closed', closeWindow );<commit_msg>dump electron info when hakuneko is started<commit_after>const electron = require( 'electron' );
const path = require( 'path' );
const url = require( 'url' );
const config = require( './config.js' );
const cache = require( './cache.js' );

// global reference to the main window
var win = null;

/**
 *
 */
function info() {
    let separator = '------------------------';
    console.log();
    console.log( separator );
    console.log( 'Framework Version Info' );
    console.log( separator );
    console.log( 'Electron :', process.versions.electron );
    console.log( 'Chrome   :', process.versions.chrome );
    console.log( 'Node     :', process.versions.node );
    console.log( separator );
    console.log();
}

/**
 * Register a custom file protocol handler that will open files from the given directory
 * @param {*} protocol
 * @param {*} directory
 */
function registerCacheProtocol( protocol, directory ) {
    electron.protocol.registerFileProtocol( protocol, ( request, callback ) => {
        // build full path (replace backslashes by forward slashes)
        callback( { path: path.normalize( path.join( directory, url.parse( request.url ).pathname ) ) } );
    } );
}

/**
 * Open and configure the main window of the application
 */
function activateWindow() {

    if ( win !== null ) {
        return;
    }

    registerCacheProtocol( config.cache.url.protocol, config.cache.directory );

    win = new electron.BrowserWindow( {
        width: 1120,
        height: 680,
        webPreferences: {
            experimentalFeatures: true,
            nodeIntegration: true,
            webSecurity: false // required to open local images in browser
        }
    } );

    // inject headers before a request is made (call the handler in the webapp to do the dirty work)
    electron.session.defaultSession.webRequest.onBeforeSendHeaders( ['http*://*'], ( details, callback ) => {
        ( new Promise( (resolve, reject ) => {
            // prevent from injecting javascript into the webpage while the webcontent is not yet ready
            // => required for loading initial page over http protocol (e.g. local hosted test page)
            if( win && win.webContents && !win.webContents.isLoading() ) {
                resolve();
            } else {
                throw new Error( 'Cannot inject javascript while web-app is not yet ready!' );
            }
        } ) )
        .then( () => {
            // inject javascript: looks stupid, but is a working solution to call a function
            // directly within the render process (without dealing with ipcRenderer)
            let payload = Buffer.from( JSON.stringify( details ) ).toString( 'base64' );
            return win.webContents.executeJavaScript( `Engine.Request.onBeforeSendHeadersHandler('${payload}');` );
        } )
        .then( result => {
            callback( {
                cancel: false,
                requestHeaders: result.requestHeaders
            } );
        } )
        .catch( error => {
            callback( {
                cancel: false,
                requestHeaders: details.requestHeaders
            } );
        } );
    } );

    win.setMenu( null );

    let load = () => {
        win.loadURL( config.cache.url.href );
        if( config.app.developer ) {
            win.webContents.openDevTools();
        }
    };

    cache.update( config.app.url.href, config.cache.directory )
    .then( version => {
        load();
        electron.dialog.showMessageBox( win, {
            type: 'info',
            message: 'HakuNeko has been updated\nrev.' + version,
            buttons: ['OK']
        }, ( button, checkbox ) => {} );
    } )
    .catch( error => {
        load();
        if( error ) {
            console.error( error );
        }
    } );

    win.on( 'closed', () => {
        // close all existing windows
        electron.BrowserWindow.getAllWindows().forEach( window => window.close() );
        win = null;
    } );
}

/**
 * Quit aplication, except for OSX
 */
function closeWindow () {
    electron.app.quit();
}

/************************
 *** MAIN ENTRY POINT ***
 ************************/

info();

// Disabling GPU acceleration to possibly prevent chromiums 'blank screen' bug
// it seems the --disable-gpu flag did not solve problems for windows user (blank screen)
// => no need to disable gpu if it still not solves the problem ...
//electron.app.disableHardwareAcceleration();

// add HakuNeko's application directory to the environment variable path (make ffmpeg available on windows)
process.env.PATH += ( process.platform === 'win32' ? ';' : ':' ) + path.dirname( process.execPath );

// register new protocol handler as standard handler to host files locally without web server
// => required to enable access to chromium specific features such as local store, indexedDB, ...
electron.protocol.registerStandardSchemes( [config.cache.url.protocol] );

// update userdata path (e.g. for portable version)
electron.app.setPath( 'userData', config.app.userdata );

// connect events
//electron.app.addEventListener(;
electron.app.on( 'ready', activateWindow );
electron.app.on( 'activate', activateWindow );
electron.app.on( 'window-all-closed', closeWindow );<|endoftext|>


<commit_before>var prompt = require("prompt")
var LoadPackage = require("../app/utils/package_loader")

var Setup = require("../app/actions/profile_setup")
var Create = require("../app/actions/profile_create")

function setup(){
  var options = [
    { name: 'public_dev_key', description: 'Developer Key: ( Your Developer Key provided by the 3VOT Admin )' }
  ];

  prompt.start();
  prompt.get( options, function (err, result) {
    LoadPackage(result)
    .then(Setup)
    .then( function(){ "ok" } )
    .fail( function(err){console.error(err); } );
  });
}

function create(){
  prompt.start();
  prompt.get( [
    { name: 'name', description: 'Name: ( The Official Name of your profile)' } ,
    { name: 'user_name', description: 'username: ( The username, that appears in the url )' },
    { name: 'email', description: 'email: ( Your Email, required in order to administer your profile )' }],
    function (err, result) {
      Create(result)
      .then( function(profile){ console.log("Profile Created Succesfully".green); console.log( ( "Save your developer key: " + profile.security.public_dev_key ).bold) } )
      .fail( function(err){ console.log("Error creating Profile".red.bold); console.error(err.red); } )
  });
}

module.exports = {
  setup: setup,
  create: create
}<commit_msg>fix profile:setup<commit_after>var prompt = require("prompt")
var LoadPackage = require("../app/utils/package_loader")

var Setup = require("../app/actions/profile_setup")
var Create = require("../app/actions/profile_create")

function setup(){
  var options = [
    { name: 'public_dev_key', description: 'Developer Key: ( Your Developer Key provided by the 3VOT Admin )' }
  ];

  prompt.start();
  prompt.get( options, function (err, result) {
    .then(result)
    .then( function(){ "ok" } )
    .fail( function(err){console.error(err); } );
  });
}

function create(){
  prompt.start();
  prompt.get( [
    { name: 'name', description: 'Name: ( The Official Name of your profile)' } ,
    { name: 'user_name', description: 'username: ( The username, that appears in the url )' },
    { name: 'email', description: 'email: ( Your Email, required in order to administer your profile )' }],
    function (err, result) {
      Create(result)
      .then( function(profile){ console.log("Profile Created Succesfully".green); console.log( ( "Save your developer key: " + profile.security.public_dev_key ).bold) } )
      .fail( function(err){ console.log("Error creating Profile".red.bold); console.error(err.red); } )
  });
}

module.exports = {
  setup: setup,
  create: create
}<|endoftext|>


<commit_before>#!/usr/bin/env node

var program = require('commander'),
    cli = require('./lib/cli'),
    colors = require('colors'),
    coercion = require('./lib/coercion'),
    _ = require('underscore');

program
  .version(require('./package').version)
  .usage('<command> <name> [options]');

program.name = 'tinder';

program
  .command('new <name> <template>')
  .alias('mk')
  .description('Initialize new project <name> based on <template>')
  .option('-u, --user <username>', 'Github username')
  .option('-p, --pass', 'Github password')
  .option('-d, --description <description>', 'Description of the project')
  .option('-v, --vars <json>', 'Additional variables for template interpolation', coercion.obj, {})
  .option('-i, --interpolate <value>', 'Underscore interpolate pattern', _.templateSettings.interpolate.source)
  .option('-e, --evaluate <pattern>', 'Underscore evaluate pattern', _.templateSettings.evaluate.source)
  .option('-E, --escape <pattern>', 'Underscore escape pattern', _.templateSettings.escape.source)
  .option('-c, --no-clean', 'Do not rm -rf on a faiure')
  .option('-P, --private', 'Create a private github repo')
  .option('-w, --no-wiki', 'Do not create a github wiki')
  .option('-I, --no-issues', 'Do not create a github issues page')
  .action(cli.create);

program
  .command('* <name> <template>')
  .usage('tinder <name> <template>')
  .description('Shortcut for "new"')
  .option('-u, --user <username>', 'Github username')
  .option('-p, --pass', 'Github password')
  .option('-d, --description <description>', 'Description of the project')
  .option('-v, --vars <json>', 'Additional variables for template interpolation', coercion.obj, {})
  .option('-i, --interpolate <value>', 'Underscore interpolate pattern', _.templateSettings.interpolate.source)
  .option('-e, --evaluate <pattern>', 'Underscore evaluate pattern', _.templateSettings.evaluate.source)
  .option('-E, --escape <pattern>', 'Underscore escape pattern', _.templateSettings.escape.source)
  .option('-c, --no-clean', 'Do not rm -rf on a faiure')
  .option('-P, --private', 'Create a private github repo')
  .option('-w, --no-wiki', 'Do not create a github wiki')
  .option('-I, --no-issues', 'Do not create a github issues page')
  .action(cli.create);

program.parse(process.argv);
<commit_msg>Add config command<commit_after>#!/usr/bin/env node

var program = require('commander'),
    cli = require('./lib/cli'),
    colors = require('colors'),
    coercion = require('./lib/coercion'),
    _ = require('underscore');

program
  .version(require('./package').version)
  .usage('<command> <name> [options]');

program.name = 'tinder';

program
  .command('new <name> <template>')
  .alias('mk')
  .description('Initialize new project <name> based on <template>')
  .option('-u, --user <username>', 'Github username')
  .option('-p, --pass', 'Github password')
  .option('-d, --description <description>', 'Description of the project')
  .option('-v, --vars <json>', 'Additional variables for template interpolation', coercion.obj, {})
  .option('-i, --interpolate <value>', 'Underscore interpolate pattern', _.templateSettings.interpolate.source)
  .option('-e, --evaluate <pattern>', 'Underscore evaluate pattern', _.templateSettings.evaluate.source)
  .option('-E, --escape <pattern>', 'Underscore escape pattern', _.templateSettings.escape.source)
  .option('-c, --no-clean', 'Do not rm -rf on a faiure')
  .option('-P, --private', 'Create a private github repo')
  .option('-w, --no-wiki', 'Do not create a github wiki')
  .option('-I, --no-issues', 'Do not create a github issues page')
  .action(cli.create);

program
  .command('config')
  .description('Store options for later re-use')
  .action(cli.register);

//program
  //.command('* <name> <template>')
  //.usage('tinder <name> <template>')
  //.description('Shortcut for "new"')
  //.option('-u, --user <username>', 'Github username')
  //.option('-p, --pass', 'Github password')
  //.option('-d, --description <description>', 'Description of the project')
  //.option('-v, --vars <json>', 'Additional variables for template interpolation', coercion.obj, {})
  //.option('-i, --interpolate <value>', 'Underscore interpolate pattern', _.templateSettings.interpolate.source)
  //.option('-e, --evaluate <pattern>', 'Underscore evaluate pattern', _.templateSettings.evaluate.source)
  //.option('-E, --escape <pattern>', 'Underscore escape pattern', _.templateSettings.escape.source)
  //.option('-c, --no-clean', 'Do not rm -rf on a faiure')
  //.option('-P, --private', 'Create a private github repo')
  //.option('-w, --no-wiki', 'Do not create a github wiki')
  //.option('-I, --no-issues', 'Do not create a github issues page')
  //.action(cli.create);

program.parse(process.argv);
<|endoftext|>


<commit_before>/*
 * JavaScript tracker for Snowplow: out_queue.js
 *
 * Significant portions copyright 2010 Anthon Pang. Remainder copyright
 * 2012-2014 Snowplow Analytics Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of Anthon Pang nor Snowplow Analytics Ltd nor the
 *   names of their contributors may be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

;(function() {

	var
		json2 = require('JSON'),
		lodash = require('./lib_managed/lodash'),
		localStorageAccessible = require('./lib/detectors').localStorageAccessible,
		object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support

	/**
	 * Object handling sending events to a collector.
	 * Instantiated once per tracker instance.
	 *
	 * @param string functionName The Snowplow function name (used to generate the localStorage key)
	 * @param string namespace The tracker instance's namespace (used to generate the localStorage key)
	 * @param object mutSnowplowState Gives the pageUnloadGuard a reference to the outbound queue
	 *                                so it can unload the page when all queues are empty
	 * @param boolean useLocalStorage Whether to use localStorage at all
	 * @param boolean usePost Whether to send events by POST or GET
	 * @param int bufferSize How many events to batch in localStorage before sending them all.
	 *                       Only applies when sending POST requests and when localStorage is available.
	 * @return object OutQueueManager instance
	 */
	object.OutQueueManager = function (functionName, namespace, mutSnowplowState, useLocalStorage, usePost, bufferSize) {
		var	queueName,
			executingQueue = false,
			configCollectorUrl,
			outQueue;

		// Fall back to GET for browsers which don't support CORS XMLHttpRequests (e.g. IE <= 9)
		usePost = usePost && window.XMLHttpRequest && ('withCredentials' in new XMLHttpRequest());

		var path = usePost ? '/com.snowplowanalytics.snowplow/tp2' : '/i';

		bufferSize = (localStorageAccessible() && useLocalStorage && usePost && bufferSize) || 1;

		// Different queue names for GET and POST since they are stored differently
		queueName = ['snowplowOutQueue', functionName, namespace, usePost ? 'post' : 'get'].join('_');

		if (localStorageAccessible() && useLocalStorage) {
			// Catch any JSON parse errors that might be thrown
			try {
				outQueue = json2.parse(localStorage.getItem(queueName));
			}
			catch(e) {}
		}

		// Initialize to and empty array if we didn't get anything out of localStorage
		if (!lodash.isArray(outQueue)) {
			outQueue = [];
		}

		// Used by pageUnloadGuard
		mutSnowplowState.outQueues.push(outQueue);

		if (usePost) {
			mutSnowplowState.bufferFlushers.push(executeQueue);
		}

		/*
		 * Convert a dictionary to a querystring
		 * The context field is the last in the querystring
		 */
		function getQuerystring(request) {
			var querystring = '?',
				lowPriorityKeys = {'co': true, 'cx': true},
				firstPair = true;

			for (var key in request) {
				if (request.hasOwnProperty(key) && !(lowPriorityKeys.hasOwnProperty(key))) {
					if (!firstPair) {
						querystring += '&';
					} else {
						firstPair = false;
					}
					querystring += encodeURIComponent(key) + '=' + encodeURIComponent(request[key]);
				}
			}

			for (var contextKey in lowPriorityKeys) {
				if (request.hasOwnProperty(contextKey)  && lowPriorityKeys.hasOwnProperty(contextKey)) {
					querystring += '&' + contextKey + '=' + encodeURIComponent(request[contextKey]);
				}
			}

			return querystring;
		}

		/*
		 * Convert numeric fields to strings to match payload_data schema
		 */
		function getBody(request) {
			return lodash.mapValues(request, function (v) {
				return v.toString();
			});
		}

		/*
		 * Queue an image beacon for submission to the collector.
		 * If we're not processing the queue, we'll start.
		 */
		function enqueueRequest (request, url) {

			outQueue.push(usePost ? getBody(request) : getQuerystring(request));
			configCollectorUrl = url + path;
			if (localStorageAccessible() && useLocalStorage) {
				localStorage.setItem(queueName, json2.stringify(outQueue));
			}

			if (!executingQueue && outQueue.length >= bufferSize) {
				executeQueue();
			}
		}

		/*
		 * Run through the queue of image beacons, sending them one at a time.
		 * Stops processing when we run out of queued requests, or we get an error.
		 */
		function executeQueue () {

			// Failsafe in case there is some way for a bad value like "null" to end up in the outQueue
			while (outQueue.length && typeof outQueue[0] !== 'string' && typeof outQueue[0] !== 'object') {
				outQueue.shift();
			}

			if (outQueue.length < 1) {
				executingQueue = false;
				return;
			}

			// Let's check that we have a Url to ping
			if (!lodash.isString(configCollectorUrl)) {
				throw "No Snowplow collector configured, cannot track";
			}

			executingQueue = true;

			var nextRequest = outQueue[0];

			if (usePost) {

				var xhr = new XMLHttpRequest();
				xhr.open('POST', configCollectorUrl, true);
				xhr.withCredentials = true;

				// Time out POST requests after 5 seconds
				var xhrTimeout = setTimeout(function () {
					xhr.abort();
					executingQueue = false;
				}, 5000);

				// Keep track of number of events to delete from queue
				var eventCount = outQueue.length;

				xhr.onreadystatechange = function () {
					if (xhr.readyState === 4 && xhr.status === 200) {
						for (var deleteCount = 0; deleteCount < eventCount; deleteCount++) {
							outQueue.shift();
						}
						if (localStorageAccessible() && useLocalStorage) {
							localStorage.setItem(queueName, json2.stringify(outQueue));
						}
						clearTimeout(xhrTimeout);
						executeQueue();
					} else if (xhr.readyState === 4 && xhr.status === 404) {
						executingQueue = false;
					}
				};

				xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				var batchRequest = {
					schema: 'iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-2',
					data: outQueue
				};
				if (outQueue.length > 0) {
					xhr.send(json2.stringify(batchRequest));
				}

			} else {

				var image = new Image(1, 1);

				image.onload = function () {
					outQueue.shift();
					if (localStorageAccessible() && useLocalStorage) {
						localStorage.setItem(queueName, json2.stringify(outQueue));
					}
					executeQueue();
				};

				image.onerror = function () {
					executingQueue = false;
				};

				image.src = configCollectorUrl + nextRequest;
			}

		}

		return {
			enqueueRequest: enqueueRequest,
			executeQueue: executeQueue
		};
	};

}());
<commit_msg>Counted any 4xx or 5xx collector response to a POST request as failed (fixes #344)<commit_after>/*
 * JavaScript tracker for Snowplow: out_queue.js
 *
 * Significant portions copyright 2010 Anthon Pang. Remainder copyright
 * 2012-2014 Snowplow Analytics Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of Anthon Pang nor Snowplow Analytics Ltd nor the
 *   names of their contributors may be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

;(function() {

	var
		json2 = require('JSON'),
		lodash = require('./lib_managed/lodash'),
		localStorageAccessible = require('./lib/detectors').localStorageAccessible,
		object = typeof exports !== 'undefined' ? exports : this; // For eventual node.js environment support

	/**
	 * Object handling sending events to a collector.
	 * Instantiated once per tracker instance.
	 *
	 * @param string functionName The Snowplow function name (used to generate the localStorage key)
	 * @param string namespace The tracker instance's namespace (used to generate the localStorage key)
	 * @param object mutSnowplowState Gives the pageUnloadGuard a reference to the outbound queue
	 *                                so it can unload the page when all queues are empty
	 * @param boolean useLocalStorage Whether to use localStorage at all
	 * @param boolean usePost Whether to send events by POST or GET
	 * @param int bufferSize How many events to batch in localStorage before sending them all.
	 *                       Only applies when sending POST requests and when localStorage is available.
	 * @return object OutQueueManager instance
	 */
	object.OutQueueManager = function (functionName, namespace, mutSnowplowState, useLocalStorage, usePost, bufferSize) {
		var	queueName,
			executingQueue = false,
			configCollectorUrl,
			outQueue;

		// Fall back to GET for browsers which don't support CORS XMLHttpRequests (e.g. IE <= 9)
		usePost = usePost && window.XMLHttpRequest && ('withCredentials' in new XMLHttpRequest());

		var path = usePost ? '/com.snowplowanalytics.snowplow/tp2' : '/i';

		bufferSize = (localStorageAccessible() && useLocalStorage && usePost && bufferSize) || 1;

		// Different queue names for GET and POST since they are stored differently
		queueName = ['snowplowOutQueue', functionName, namespace, usePost ? 'post' : 'get'].join('_');

		if (localStorageAccessible() && useLocalStorage) {
			// Catch any JSON parse errors that might be thrown
			try {
				outQueue = json2.parse(localStorage.getItem(queueName));
			}
			catch(e) {}
		}

		// Initialize to and empty array if we didn't get anything out of localStorage
		if (!lodash.isArray(outQueue)) {
			outQueue = [];
		}

		// Used by pageUnloadGuard
		mutSnowplowState.outQueues.push(outQueue);

		if (usePost) {
			mutSnowplowState.bufferFlushers.push(executeQueue);
		}

		/*
		 * Convert a dictionary to a querystring
		 * The context field is the last in the querystring
		 */
		function getQuerystring(request) {
			var querystring = '?',
				lowPriorityKeys = {'co': true, 'cx': true},
				firstPair = true;

			for (var key in request) {
				if (request.hasOwnProperty(key) && !(lowPriorityKeys.hasOwnProperty(key))) {
					if (!firstPair) {
						querystring += '&';
					} else {
						firstPair = false;
					}
					querystring += encodeURIComponent(key) + '=' + encodeURIComponent(request[key]);
				}
			}

			for (var contextKey in lowPriorityKeys) {
				if (request.hasOwnProperty(contextKey)  && lowPriorityKeys.hasOwnProperty(contextKey)) {
					querystring += '&' + contextKey + '=' + encodeURIComponent(request[contextKey]);
				}
			}

			return querystring;
		}

		/*
		 * Convert numeric fields to strings to match payload_data schema
		 */
		function getBody(request) {
			return lodash.mapValues(request, function (v) {
				return v.toString();
			});
		}

		/*
		 * Queue an image beacon for submission to the collector.
		 * If we're not processing the queue, we'll start.
		 */
		function enqueueRequest (request, url) {

			outQueue.push(usePost ? getBody(request) : getQuerystring(request));
			configCollectorUrl = url + path;
			if (localStorageAccessible() && useLocalStorage) {
				localStorage.setItem(queueName, json2.stringify(outQueue));
			}

			if (!executingQueue && outQueue.length >= bufferSize) {
				executeQueue();
			}
		}

		/*
		 * Run through the queue of image beacons, sending them one at a time.
		 * Stops processing when we run out of queued requests, or we get an error.
		 */
		function executeQueue () {

			// Failsafe in case there is some way for a bad value like "null" to end up in the outQueue
			while (outQueue.length && typeof outQueue[0] !== 'string' && typeof outQueue[0] !== 'object') {
				outQueue.shift();
			}

			if (outQueue.length < 1) {
				executingQueue = false;
				return;
			}

			// Let's check that we have a Url to ping
			if (!lodash.isString(configCollectorUrl)) {
				throw "No Snowplow collector configured, cannot track";
			}

			executingQueue = true;

			var nextRequest = outQueue[0];

			if (usePost) {

				var xhr = new XMLHttpRequest();
				xhr.open('POST', configCollectorUrl, true);
				xhr.withCredentials = true;

				// Time out POST requests after 5 seconds
				var xhrTimeout = setTimeout(function () {
					xhr.abort();
					executingQueue = false;
				}, 5000);

				// Keep track of number of events to delete from queue
				var eventCount = outQueue.length;

				xhr.onreadystatechange = function () {
					if (xhr.readyState === 4 && xhr.status === 200) {
						for (var deleteCount = 0; deleteCount < eventCount; deleteCount++) {
							outQueue.shift();
						}
						if (localStorageAccessible() && useLocalStorage) {
							localStorage.setItem(queueName, json2.stringify(outQueue));
						}
						clearTimeout(xhrTimeout);
						executeQueue();
					} else if (xhr.readyState === 4 && xhr.status >= 400) {
						executingQueue = false;
					}
				};

				xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				var batchRequest = {
					schema: 'iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-2',
					data: outQueue
				};
				if (outQueue.length > 0) {
					xhr.send(json2.stringify(batchRequest));
				}

			} else {

				var image = new Image(1, 1);

				image.onload = function () {
					outQueue.shift();
					if (localStorageAccessible() && useLocalStorage) {
						localStorage.setItem(queueName, json2.stringify(outQueue));
					}
					executeQueue();
				};

				image.onerror = function () {
					executingQueue = false;
				};

				image.src = configCollectorUrl + nextRequest;
			}

		}

		return {
			enqueueRequest: enqueueRequest,
			executeQueue: executeQueue
		};
	};

}());
<|endoftext|>


<commit_before>// Post requests

var json_parser = function () {
	this.parsed = [];
	this.time_stamp = {
		start_time: Date.now(),
		end_time: 0
	}
	var frame_init = 0;
	var index = 0;
	this.post_partial = async function (exp_id, game, data) {
		var frame_last = game.time;
		var partial = JSON.stringify(game.gameStates.slice(frame_init, frame_last));
		frame_init = frame_last;

		var steps = game.steps
		var last_state = game.gameStates.length;
		var win = game.gameStates[last_state-1].win;
		var score = game.gameStates[last_state-1].score;
		$.ajax({
			type: 'PUT',
			url: "/experiment/"+exp_id,
			data: {timeStamp: JSON.stringify(this.time_stamp),
			 	   gameStates: partial,
			 	   // score: score,
			 	   // win: win,
			 	   // steps: steps,
			 	   data: data},
			success: function (status) {
				if (!status.success) {
					console.log('could not put experiment');
				}
			},
		})
	}
}

var next_experiment = function (exp_id, game, parser, data, callback) {
	if (exp_id == '0') {
		callback();
		return;
	}
	$.ajax({
		type: 'POST',
		url: '/experiment/'+exp_id+'/next',
		success: function (status) {
			if (status.success) {
				callback();
			}
		}
	})
	// post_experiment(exp_id, game, parser, data, 'next', callback);
}

var retry_experiment = function (exp_id, game, parser, data, callback) {
	if (exp_id == '0') {
		callback();
		return;
	}
	$.ajax({
		type: 'POST',
		url: '/experiment/'+exp_id+'/retry',
		success: function (status) {
			if (status.success) {
				callback();
			}
		}
	})
	// post_experiment(exp_id, game, parser, data, 'retry', callback);
}

/**
 * @fileoverview
 * Draw lines, polygons, circles, etc on the screen.
 * Render text in a certain font to the screen.
 */

var gamejs = require('gamejs');;
var vgdl_parser = VGDLParser(gamejs);
var game = vgdl_parser.playGame(vgdl_game.game, vgdl_game.level, color_scheme);
// var on_game_end = function () {
// }
// game.paused = false;
// gamejs.ready(game.run(on_game_end));
// console.log('game started');

var interval;
var parser;

var retry_game = function () {
	window.location.reload();
}

var continue_game = function () {
	next_experiment(exp_id, game, parser, data, function () {
		window.location.href = `/experiment/${exp_id}`
	});
}

var page_refresh = function () {
	game.paused = true;
	if (game.win === null) {
		retry_experiment(exp_id, game, parser, data, function () {
			console.log('game refreshed');
		})
	}
}

$(document).on('click', '#forfeit', function () {
	next_experiment(exp_id, game, parser, data, function () {
		location.reload();
	})
})

$(document).on('click', '#continue', continue_game);

$(document).on('click', '#return', function () {
	window.location.href = '/admin';
})
$(document).on('click', '#retry', retry_game);

$(document).on('click', '#pause', function () {
	game.paused = !game.paused;
})
$(window).bind('beforeunload', page_refresh);

$(document).ready(function () {

	var cont_button = $('<button id="continue">Continue</button>');
	var return_button = $('<button id="return">Return</button>');

	var forfeit_div = $('

')
	var forfeit_text = $('
If you want to forfeit the entire level and try a new one, press "Forfeit".
');
	var forfeit_button = $('<button id="forfeit">Forfeit</button>');

	var retry_container = $('

');
	var retry_text = $('
If you get stuck, you can press "Retry" to reset this level.
')
	var retry_button = $('<button id="retry">Retry</button>')
	retry_container.append(retry_text)
	retry_container.append(retry_button)

	forfeit_div.append(forfeit_text);
	forfeit_div.append(forfeit_button);

	var end_game_delay = 1000;
	var retry_delay = 30000;
	var forfeit_delay = 60000*2;
	var ended = false;

	var on_game_end = function () {
		parser.post_partial(exp_id, game, data);
		clearInterval(interval);
		game.paused = true;
		ended = true
		$('#retry-div').remove()
		var show_status = function () {
			var status_text = '';
			if (game.win) {
				var container = $('

');
				if (exp_id != '0') {
					var button = cont_button;
				} else {
					var button = return_button;
				}
			}
			else {
				var container = retry_container;
				var button = retry_button;
			}

			container.append(button);
			$('body').append(container)
			$('#forfeit-div').remove();
			$('#retry-text').remove();
		}

		if (game.win) {
			$('#title').text('Game Won!')
			show_status()

		} else {
			$('#title').text('Game Lost!')
			window.setTimeout(show_status, end_game_delay);
		}
	}

	var begin_game = function () {
		parser = new json_parser();
		interval = window.setInterval(function(){
		  parser.post_partial(exp_id, game, data)
		}, 2500);

		$('#start-div').remove();
		game.paused = false;
		window.setTimeout(function () {
			if (!ended)
				$('body').append(retry_container)
		}, retry_delay);
		window.setTimeout(function () {
			if (!ended)
				$('#retry-div').append(forfeit_div);
		}, forfeit_delay);
	}

	$('#gjs-canvas').focus();
	$('#start').click(begin_game)

	// start_modal.style.display = 'none';
	// game.paused = true;
	gamejs.ready(game.run(on_game_end));

	begin_game();

});

// // gamejs.ready will call your main function
// // once all components and resources are ready.
// gamejs.ready(main);
<commit_msg>blocker added<commit_after>// Post requests

var json_parser = function () {
	this.parsed = [];
	this.time_stamp = {
		start_time: Date.now(),
		end_time: 0
	}
	var frame_init = 0;
	var index = 0;
	this.post_partial = async function (exp_id, game, data) {
		var frame_last = game.time;
		var partial = JSON.stringify(game.gameStates.slice(frame_init, frame_last));
		frame_init = frame_last;

		var steps = game.steps
		var last_state = game.gameStates.length;
		var win = game.gameStates[last_state-1].win;
		var score = game.gameStates[last_state-1].score;
		$.ajax({
			type: 'PUT',
			url: "/experiment/"+exp_id,
			data: {timeStamp: JSON.stringify(this.time_stamp),
			 	   gameStates: partial,
			 	   // score: score,
			 	   // win: win,
			 	   // steps: steps,
			 	   data: data},
			success: function (status) {
				if (!status.success) {
					console.log('could not put experiment');
				}
			},
		})
	}
}

var next_experiment = function (exp_id, game, parser, data, callback) {
	$('body').addClass('loading')
	if (exp_id == '0') {
		callback();
		return;
	}
	$.ajax({
		type: 'POST',
		url: '/experiment/'+exp_id+'/next',
		data: data,
		success: function (status) {
			if (status.success) {
				callback();
			}
		}
	})
	// post_experiment(exp_id, game, parser, data, 'next', callback);
}

var retry_experiment = function (exp_id, game, parser, data, callback) {
	$('body').addClass('loading')
	if (exp_id == '0') {
		callback();
		return;
	}
	$.ajax({
		type: 'POST',
		url: '/experiment/'+exp_id+'/retry',
		success: function (status) {
			if (status.success) {
				callback();
			}
		}
	})
	// post_experiment(exp_id, game, parser, data, 'retry', callback);
}

/**
 * @fileoverview
 * Draw lines, polygons, circles, etc on the screen.
 * Render text in a certain font to the screen.
 */

var gamejs = require('gamejs');;
var vgdl_parser = VGDLParser(gamejs);
var game = vgdl_parser.playGame(vgdl_game.game, vgdl_game.level, color_scheme);
// var on_game_end = function () {
// }
// game.paused = false;
// gamejs.ready(game.run(on_game_end));
// console.log('game started');

var interval;
var parser;

var retry_game = function () {
	window.location.reload();
}

var continue_game = function () {
	next_experiment(exp_id, game, parser, data, function () {
		window.location.href = `/experiment/${exp_id}`
	});
}

var page_refresh = function () {
	game.paused = true;
	if (game.win === null) {
		retry_experiment(exp_id, game, parser, data, function () {
			console.log('game refreshed');
		})
	}
}

$(document).on('click', '#forfeit', function () {
	next_experiment(exp_id, game, parser, data, function () {
		location.reload();
	})
})

$(document).on('click', '#continue', continue_game);

$(document).on('click', '#return', function () {
	window.location.href = '/admin';
})
$(document).on('click', '#retry', retry_game);

$(document).on('click', '#pause', function () {
	game.paused = !game.paused;
})
$(window).bind('beforeunload', page_refresh);

$(document).ready(function () {

	var cont_button = $('<button id="continue">Continue</button>');
	var return_button = $('<button id="return">Return</button>');

	var forfeit_div = $('

')
	var forfeit_text = $('
If you want to forfeit the entire level and try a new one, press "Forfeit".
');
	var forfeit_button = $('<button id="forfeit">Forfeit</button>');

	var retry_container = $('

');
	var retry_text = $('
If you get stuck, you can press "Retry" to reset this level.
')
	var retry_button = $('<button id="retry">Retry</button>')
	retry_container.append(retry_text)
	retry_container.append(retry_button)

	forfeit_div.append(forfeit_text);
	forfeit_div.append(forfeit_button);

	var end_game_delay = 1000;
	var retry_delay = 30000;
	var forfeit_delay = 60000*2;
	var ended = false;

	var on_game_end = function () {
		parser.post_partial(exp_id, game, data);
		clearInterval(interval);
		game.paused = true;
		ended = true
		$('#retry-div').remove()
		var show_status = function () {
			var status_text = '';
			if (game.win) {
				var container = $('

');
				if (exp_id != '0') {
					var button = cont_button;
				} else {
					var button = return_button;
				}
			}
			else {
				var container = retry_container;
				var button = retry_button;
			}

			container.append(button);
			$('body').append(container)
			$('#forfeit-div').remove();
			$('#retry-text').remove();
		}

		if (game.win) {
			$('#title').text('Game Won!')
			show_status()

		} else {
			$('#title').text('Game Lost!')
			window.setTimeout(show_status, end_game_delay);
		}
	}

	var begin_game = function () {
		parser = new json_parser();
		interval = window.setInterval(function(){
		  parser.post_partial(exp_id, game, data)
		}, 2500);

		$('#start-div').remove();
		game.paused = false;
		window.setTimeout(function () {
			if (!ended)
				$('body').append(retry_container)
		}, retry_delay);
		window.setTimeout(function () {
			if (!ended)
				$('#retry-div').append(forfeit_div);
		}, forfeit_delay);
	}

	$('#gjs-canvas').focus();
	$('#start').click(begin_game)

	// start_modal.style.display = 'none';
	// game.paused = true;
	gamejs.ready(game.run(on_game_end));

	begin_game();

});

// // gamejs.ready will call your main function
// // once all components and resources are ready.
// gamejs.ready(main);
<|endoftext|>


<commit_before>
//init spinner
var opts = {
    lines: 13, // The number of lines to draw
    length: 28, // The length of each line
    width: 14, // The line thickness
    radius: 42, // The radius of the inner circle
    scale: 1, // Scales overall size of the spinner
    corners: 1, // Corner roundness (0..1)
    color: '#000', // #rgb or #rrggbb or array of colors
    opacity: 0.25, // Opacity of the lines
    rotate: 0, // The rotation offset
    direction: 1, // 1: clockwise, -1: counterclockwise
    speed: 1, // Rounds per second
    trail: 60, // Afterglow percentage
    fps: 20, // Frames per second when using setTimeout() as a fallback for CSS
    zIndex: 2e9, // The z-index (defaults to 2000000000)
    className: 'spinner', // The CSS class to assign to the spinner
    top: '50%', // Top position relative to parent
    left: '50%', // Left position relative to parent
    shadow: false, // Whether to render a shadow
    hwaccel: true, // Whether to use hardware acceleration
    position: 'absolute' // Element positioning
};
var spinner;

/**
 *
 */
function initConfig() {
  "use strict";

  loadConfig('#congregation');
  var val = $('#congregation').val();
  $('#congregationSpan1').html(val);
  $('#congregationSpan2').html(val);
  loadConfig('#cal1');
  loadConfig('#cal2');
  loadConfig('#cal3');
  loadConfig('#cal4');

  $('#congregation').keyup( function() {
      var val = $(this).val();
      $('#congregationSpan1').html(val);
      $('#congregationSpan2').html(val);

      localStorage.setItem('#congregation', val);
  });

  $('#cal1').keyup( function() {
      localStorage.setItem('#cal1', $(this).val());
  });

  $('#cal2').keyup( function() {
      localStorage.setItem('#cal2', $(this).val());
  });

  $('#cal3').keyup( function() {
      localStorage.setItem('#cal3', $(this).val());
  });

  $('#cal4').keyup( function() {
      localStorage.setItem('#cal4', $(this).val());
  });

    $('#calendar').fullCalendar({
          timeFormat: 'H:mm',
          height: 'auto',
          header: {
              left:   'title',
              center: '',
              right:  'prev,next'
          },
          eventRender: function(event, el) {
              el.find('.fc-content').attr("contenteditable", "true");
              el.find('.fc-content').attr("onclick", "$(this).focus();");
              el.find('.fc-time').attr("contenteditable", "true");
              el.find('.fc-time').attr("onclick", "$(this).focus();");
              el.find('.fc-title').attr("contenteditable", "true");
              el.find('.fc-title').attr("onclick", "$(this).focus();");
          }
      });
}

/**
 *
 */
function loadConfig( fieldId ) {
  $(fieldId)[0].value = localStorage.getItem(fieldId);
}

/**
 *
 */
function storeConfig( fieldId ) {
  var inputField = $(fieldId);
  console.log(inputField);
  localStorage.setItem(fieldId, inputField[0].value);
}

/**
 *
 */
function loadCalendar() {
  "use strict";
  console.log("start loading Calendar(s) ...");

  var calDiv = $('#calendar');
  spinner = new Spinner(opts).spin();
  calDiv.append(spinner.el);
  calDiv.fullCalendar( 'removeEvents' );

  var icalURL = $('#cal1').val();

  if($('#cal1').val() !== "") {
    try{
      new ical_parser("http://cors-anywhere.herokuapp.com/" +$('#cal1').val(),
            renderEvents,
             loadFailed);
    } catch (e) {
        console.log("Exception: " + e);
        spinner.stop();
    }
  }
        if($('#cal2').val() !== "") {
                new ical_parser(
                    "http://cors-anywhere.herokuapp.com/" +$('#cal2').val(),
                    renderEvents,
                    loadFailed);

        }
        if($('#cal3').val() !== "") {
            try{
                new ical_parser("http://cors-anywhere.herokuapp.com/" +$('#cal3').val(),renderEvents);
            } catch (e) {
                console.log("Exception: " + e);
                spinner.stop();
            }
        }
        if($('#cal4').val() !== "") {
            try{
                new ical_parser("http://cors-anywhere.herokuapp.com/" +$('#cal4').val(),renderEvents);
            } catch (e) {
                console.log("Exception: " + e);
                spinner.stop();
            }
        }

}

/**
 * Render the calendar events.
 */
function renderEvents(cal){
  console.log("cal: " + cal);
  var calDiv = $('#calendar');
  spinner.spin();
  var icalEvents = cal.getEvents();
  var events = [];
  icalEvents.forEach(function (icalEv) {
      //console.log("event: title="+ icalEv.SUMMARY + ", start=" + icalEv.DTSTART + ", end=" + icalEv.DTEND );
      events.push({
          id: icalEv.UID,
          title: icalEv.SUMMARY + ' \n' + icalEv.LOCATION + ' ',
          start: icalEv.DTSTART, // will be parsed
          end: icalEv.DTEND
      });
  });
  calDiv.fullCalendar( 'renderEvents', events, true );

  spinner.stop();
  console.log("done loading Calendar ...");
}

/**
 * Failed loading iCal data.
 */
function loadFailed(e) {
    console.log("Load of Calendar failed. Exception: " + e);
    spinner.stop();
}

/**
 * HTML to Microsoft Word Export
 */
function export2Word(element) {

  if (!window.Blob) {
    alert('Ihr Browser ist leider veraltet und unterstützt diese Funktion nicht.');
    return;
  }

  convertImagesToBase64(element);

  var cssRules = {
    'propertyGroups' : {
        'block' : ['margin', 'padding', 'float'],
        'inline' : ['color'],
        'headings' : ['font-size', 'font-family',],
        'tables': ['width'],
        'images': ['width', 'height', 'margin', 'padding', 'float', 'display']
    },
    'elementGroups' : {
        'block' : ['DIV', 'P', 'H1', 'H2'],
        'inline' : ['SPAN'],
        'headings' : ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
        'tables' : ['TABLE', 'TR', 'TH', 'TD'],
        'images': ['img']
    }
  };
  //$(element).inlineStyler( cssRules );
  $(element).inlineStyler();
  var html, link, url;

  var css = '';
  var head = '<!DOCTYPE html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">' + css + '';

   html = element.innerHTML;

   $(html).contents().each(function() {
    if(this.nodeType === Node.COMMENT_NODE) {
        $(this).remove();
    }
   });
   var doc = head + '' + html +  '';

  console.info("HTML: " + doc);
    var converted = htmlDocx.asBlob(doc, {
        orientation: 'portrait',
        margins: { top: 720, bottom: 720, left: 720, right: 720}
    });

    saveAs(converted, 'Termine.docx');
/*
   url = URL.createObjectURL(converted);
   link = document.createElement('A');
   link.href = url;
   // Set default file name.
   // Word will append file extension - do not add an extension here.
   link.download = 'Termine';
   document.body.appendChild(link);
   if (navigator.msSaveOrOpenBlob ) {
     navigator.msSaveOrOpenBlob( blob, 'Termine.docx'); // IE10-11
   } else {
     link.click();  // other browsers
   }
   document.body.removeChild(link);
   */
 }

/**
 * Convert refered Image to inline.
 */
function convertImagesToBase64 (element) {

  var regularImages = $(element).find('img');
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  [].forEach.call(regularImages, function (imgElement) {
	// preparing canvas for drawing
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	canvas.width = imgElement.naturalWidth;
	canvas.height = imgElement.naturalHeight;
	ctx.drawImage(imgElement, 0, 0);
	// by default toDataURL() produces png image, but you can also export to jpeg
	// checkout function's documentation for more details
	var dataURL = canvas.toDataURL();
	imgElement.setAttribute('src', dataURL);
  });
  canvas.remove();

  return element;
}
<commit_msg>refactored for better input handling<commit_after>
//init spinner
var opts = {
    lines: 13, // The number of lines to draw
    length: 28, // The length of each line
    width: 14, // The line thickness
    radius: 42, // The radius of the inner circle
    scale: 1, // Scales overall size of the spinner
    corners: 1, // Corner roundness (0..1)
    color: '#000', // #rgb or #rrggbb or array of colors
    opacity: 0.25, // Opacity of the lines
    rotate: 0, // The rotation offset
    direction: 1, // 1: clockwise, -1: counterclockwise
    speed: 1, // Rounds per second
    trail: 60, // Afterglow percentage
    fps: 20, // Frames per second when using setTimeout() as a fallback for CSS
    zIndex: 2e9, // The z-index (defaults to 2000000000)
    className: 'spinner', // The CSS class to assign to the spinner
    top: '50%', // Top position relative to parent
    left: '50%', // Left position relative to parent
    shadow: false, // Whether to render a shadow
    hwaccel: true, // Whether to use hardware acceleration
    position: 'absolute' // Element positioning
};
var spinner = new Spinner(opts).spin();

/**
 *
 */
function initConfig() {
  "use strict";

  loadConfig('#congregation');
  var val = $('#congregation').val();
  $('#congregationSpan1').html(val);
  $('#congregationSpan2').html(val);
  loadConfig('#cal1');
  loadConfig('#cal2');
  loadConfig('#cal3');
  loadConfig('#cal4');

  $('#congregation').keyup( function() {
      var val = $(this).val();
      $('#congregationSpan1').html(val);
      $('#congregationSpan2').html(val);

      localStorage.setItem('#congregation', val);
  });

  $('#cal1').keyup( function() {
      localStorage.setItem('#cal1', $(this).val());
  });

  $('#cal2').keyup( function() {
      localStorage.setItem('#cal2', $(this).val());
  });

  $('#cal3').keyup( function() {
      localStorage.setItem('#cal3', $(this).val());
  });

  $('#cal4').keyup( function() {
      localStorage.setItem('#cal4', $(this).val());
  });

    $('#calendar').fullCalendar({
          timeFormat: 'H:mm',
          height: 'auto',
          header: {
              left:   'title',
              center: '',
              right:  'prev,next'
          },
          eventRender: function(event, el) {
              el.find('.fc-content').attr("contenteditable", "true");
              el.find('.fc-content').attr("onclick", "$(this).focus();");
              el.find('.fc-time').attr("contenteditable", "true");
              el.find('.fc-time').attr("onclick", "$(this).focus();");
              el.find('.fc-title').attr("contenteditable", "true");
              el.find('.fc-title').attr("onclick", "$(this).focus();");
          }
      });
}

/**
 *
 */
function loadConfig( fieldId ) {
  $(fieldId)[0].value = localStorage.getItem(fieldId);
}

/**
 *
 */
function storeConfig( fieldId ) {
  var inputField = $(fieldId);
  console.log(inputField);
  localStorage.setItem(fieldId, inputField[0].value);
}

/**
 *
 */
function loadCalendar() {
  "use strict";
  console.log("start loading Calendar(s) ...");

  var calDiv = $('#calendar');

  calDiv.append(spinner.el);
  calDiv.fullCalendar( 'removeEvents' );

  loadCalendar($('#cal1').val());
  loadCalendar($('#cal2').val());
  loadCalendar($('#cal3').val());
  loadCalendar($('#cal4').val());

  spinner.stop();
}

function loadCalendar(icalUrl) {
  console.info("Loading: " + icalUrl);
  if (typeof calUrl != 'undefined') {
    new ical_parser("http://cors-anywhere.herokuapp.com/" +icalUrl,
            renderEvents,
             loadFailed);
  }
}
/**
 * Render the calendar events.
 */
function renderEvents(cal){
  console.log("cal: " + cal);
  var calDiv = $('#calendar');
  spinner.spin();
  var icalEvents = cal.getEvents();
  var events = [];
  icalEvents.forEach(function (icalEv) {
      //console.log("event: title="+ icalEv.SUMMARY + ", start=" + icalEv.DTSTART + ", end=" + icalEv.DTEND );
      events.push({
          id: icalEv.UID,
          title: icalEv.SUMMARY + ' \n' + icalEv.LOCATION + ' ',
          start: icalEv.DTSTART, // will be parsed
          end: icalEv.DTEND
      });
  });
  calDiv.fullCalendar( 'renderEvents', events, true );

  spinner.stop();
  console.log("done loading Calendar ...");
}

/**
 * Failed loading iCal data.
 */
function loadFailed(e) {
    console.log("Load of Calendar failed. Exception: " + e);
    spinner.stop();
}

/**
 * HTML to Microsoft Word Export
 */
function export2Word(element) {

  if (!window.Blob) {
    alert('Ihr Browser ist leider veraltet und unterstützt diese Funktion nicht.');
    return;
  }

  convertImagesToBase64(element);

  var cssRules = {
    'propertyGroups' : {
        'block' : ['margin', 'padding', 'float'],
        'inline' : ['color'],
        'headings' : ['font-size', 'font-family',],
        'tables': ['width'],
        'images': ['width', 'height', 'margin', 'padding', 'float', 'display']
    },
    'elementGroups' : {
        'block' : ['DIV', 'P', 'H1', 'H2'],
        'inline' : ['SPAN'],
        'headings' : ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
        'tables' : ['TABLE', 'TR', 'TH', 'TD'],
        'images': ['img']
    }
  };
  //$(element).inlineStyler( cssRules );
  $(element).inlineStyler();
  var html, link, url;

  var css = '';
  var head = '<!DOCTYPE html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">' + css + '';

   html = element.innerHTML;

   $(html).contents().each(function() {
    if(this.nodeType === Node.COMMENT_NODE) {
        $(this).remove();
    }
   });
   var doc = head + '' + html +  '';

  console.info("HTML: " + doc);
    var converted = htmlDocx.asBlob(doc, {
        orientation: 'portrait',
        margins: { top: 720, bottom: 720, left: 720, right: 720}
    });

    saveAs(converted, 'Termine.docx');
/*
   url = URL.createObjectURL(converted);
   link = document.createElement('A');
   link.href = url;
   // Set default file name.
   // Word will append file extension - do not add an extension here.
   link.download = 'Termine';
   document.body.appendChild(link);
   if (navigator.msSaveOrOpenBlob ) {
     navigator.msSaveOrOpenBlob( blob, 'Termine.docx'); // IE10-11
   } else {
     link.click();  // other browsers
   }
   document.body.removeChild(link);
   */
 }

/**
 * Convert refered Image to inline.
 */
function convertImagesToBase64 (element) {

  var regularImages = $(element).find('img');
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  [].forEach.call(regularImages, function (imgElement) {
	// preparing canvas for drawing
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	canvas.width = imgElement.naturalWidth;
	canvas.height = imgElement.naturalHeight;
	ctx.drawImage(imgElement, 0, 0);
	// by default toDataURL() produces png image, but you can also export to jpeg
	// checkout function's documentation for more details
	var dataURL = canvas.toDataURL();
	imgElement.setAttribute('src', dataURL);
  });
  canvas.remove();

  return element;
}
<|endoftext|>