<commit_before>var myApp = angular.module('myApp', ['ngMap']);

myApp.controller('viewcontroller', function($scope, dataClient, $interval, $window, $document, helper, $timeout) {

  var places = [],
    renderarray = [],
    categoryarray = [],
    streamedCheckin = [],
    searchedCheckinarray = [],
    draggedCheckin = [],
    infowindowarray = [],
    citysearched,
    index = 0,
    current_date = new Date().getTime() / 1000,
    geocoder = new google.maps.Geocoder(), //variable for geocoding
    infowindow = new google.maps.InfoWindow(); //variable for map info

  $scope.activeContainer = '';

  $scope.init = function() {
    $scope.$on('mapInitialized', function(event, map) {
      $scope.mapobj = map;
      $scope.mapobj.setZoom(3);
      $scope.mapobj.setOptions({
        minZoom: 2,
        maxZoom: 15
      });
      $scope.mapobj.setCenter({
        lat: 0,
        lng: 0
      });
    });
    $scope.categoriesbox = false;
    $scope.checkinfrequency = "Count";
    $scope.freqtext = "";
    $scope.freqclass = "";
    $scope.inputcontainerHeight = {
      'height': "5rem"
    };
    $('[data-toggle="popover"]').popover({
      placement: 'right',
      html: true
    });
    $('[data-toggle="popover"]').mouseover(function() {
      $(this).popover('show');
    });
    $('[data-toggle="popover"]').mouseleave(function() {
      $(this).popover('hide');
    });
    $timeout(function() {
      $('div[title="Zoom in"]').closest('.gmnoprint').closest('.gmnoprint').addClass('zoomSet');
    }, 3000);
  };

  $scope.opencheckin = function(event, details) {
    $window.open('https://' + details, '_blank');
  };

  $scope.changeCategory = function(sub) {
    //sub.value = (sub.value==true ? false : true);
    $timeout(function() {
      $scope.showcategory(sub.name);
    }, 300);
  }

  $scope.showwindow = function(e, data, visible) {
    for (var i = 0; i < infowindowarray.length; i++) {
      if (infowindowarray[i][1] == data[1] && infowindowarray[i][2] == data[2]) {
        visible = false;
      }
    }
    if (visible) {
      infowindow = new google.maps.InfoWindow();
      infowindow.setContent('

' + '' + '	' + '' + '  ' + data[8] + ' says ' + '' + data[0] + '
 Place ' + data[7] + '

Visit this checkin

' + '
');
      var center = helper.getCenter($scope.mapobj.getZoom(), data);
      infowindow.setPosition(center);
      infowindow.setZIndex(2);
      infowindow.open($scope.mapobj);
      var current_date = new Date().getTime() / 1000;
      infowindowarray[index] = [infowindow, data[1], data[2], current_date];
      index++;
    }
  };

  $scope.searchquery = function() {
    try {
      //searchtext variable referred to the text in the search box
      if ($scope.searchtext != null && $scope.searchtext.replace(/\s/g, '').length) { //to check if search text is null
        $scope.activeContainer = 'active';
        var suggestClient = dataClient.getSuggestions($scope.searchtext);
        suggestClient.on('data', function(resp) {
          //$apply_solve
          $timeout(function() {
            $scope.row = true;
            $scope.categoriesbox = false;
            $scope.suggestions = resp.suggest.mysuggester[0].options;
          }, 0);
        }).on('error', function(err) {
          console.trace(err.message);
        });
      } else {
        $scope.suggestions = null;
        $scope.categoriesbox = false;
        $scope.row = false;
        $scope.activeContainer = '';
      }
    } catch (e) {
      console.log('error in try' + e);
    }
  };

  $scope.changesearchtext = function(text) {
    $scope.searchtext = text;
    $scope.row = false;
  }

  $scope.getData = function() {
    var searchClient = dataClient.getSearchCheckin(angular.lowercase($scope.searchtext));
    searchClient.on('data', function(res) {
      console.log(res);
      searchedCheckinarray = [];
      categoryarray = [];
      places = [];
      citysearched = angular.lowercase($scope.searchtext);
      $scope.row = false; //to hide suggestions
      searchProcess(res); //to fetch the data and to mark it on map
    }).on('error', function(err) {
      console.log("caught a stream error", err);
    });
  };

  function searchProcess(response) {
    if ($scope.searchtext != null && $scope.searchtext.replace(/\s/g, '').length) {
      $scope.categoriesbox = true;
      if (response.hits) {
        var hit_length = response.hits.hits.length;
        var current_date = new Date().getTime() / 1000;
        for (var i = 0; i < hit_length; i++) {
          var current_hit = response.hits.hits[i];
          if (current_hit._source.category && current_hit._source.latitude && current_hit._source.longitude && current_hit._source.category) {
            categoryarray[current_hit._source.category] = true;
            var default_arr = helper.getMapArray(current_hit._source);
            var specific_arr = [
              'src/assets/img/red_marker.png',
              current_date
            ];
            var arr = default_arr.concat(specific_arr);
            searchedCheckinarray.push(arr);
          }
        }
      }
      //GeoCoding to search the city
      geocoder.geocode({
        "address": $scope.searchtext
      }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
          var location = results[0].geometry.location,
            latitude = location.lat(),
            longitude = location.lng();
          $scope.mapobj.setCenter({
            lat: latitude,
            lng: longitude
          });
          $scope.mapobj.setZoom(11);
          $scope.$apply();
        }
      });
      renderarray = [];
      places.push.apply(places, searchedCheckinarray);
      renderarray.push.apply(renderarray, searchedCheckinarray);
      if (draggedCheckin !== null)
        renderarray.push.apply(renderarray, draggedCheckin);
      if (streamedCheckin != null)
        renderarray.push.apply(renderarray, streamedCheckin);
      $scope.places = renderarray;
      $scope.subjects = createJson(categoryarray, Object.keys(categoryarray));
      $scope.$digest();
      $scope.$apply();
      console.log($scope.places);
    }
  }

  var realtimeClient = dataClient.getliveData();
  realtimeClient.on('data', function(res) {
    streamProcess(res); //to fetch the data and to mark it on map
  }).on('error', function(err) {
    console.log("caught a stream error", err);
  });

  function streamProcess(response) {
    if (response._source.latitude != null && response._source.longitude != null) {
      var default_arr = helper.getMapArray(response._source);
      var specific_arr = [
        'src/assets/img/green_marker.png',
        response._source.city,
        current_date
      ];
      var arr = default_arr.concat(specific_arr);

      streamedCheckin.push(arr);
      renderarray.push(arr);
      $scope.places = renderarray;

      $scope.streamStatus = helper.getStatus(streamedCheckin.length);
      $scope.checkinfrequency = $scope.streamStatus.checkinfrequency;
      $scope.color = $scope.streamStatus.color;
      $scope.freqtext = $scope.streamStatus.freqtext;
      $scope.freqclass = $scope.streamStatus.freqclass;

      $scope.$apply();
    }
  }

  $scope.draggedmap = function() {
    draggedCheckin = [];
    if ($scope.mapobj.getZoom() >= 5) {
      var dragClient = dataClient.getDragData($scope.mapobj.getCenter().lat(), $scope.mapobj.getCenter().lng());
      dragClient.on('data', function(res) {
        dragProcess(res); //to fetch the data and to mark it on map
      }).on('error', function(err) {
        console.log("caught a stream error", err);
      });
    } else if ($scope.mapobj.getZoom() === 4) {
      draggedCheckin = [];
      renderarray = [];
      if (places != null)
        renderarray.push.apply(renderarray, places);
      if (streamedCheckin !== null)
        renderarray.push.apply(renderarray, streamedCheckin);
      $scope.places = renderarray;
    }
  }

  function dragProcess(response) {
    if (response.hits) {
      for (var i = 0; i < response.hits.hits.length; i++) {
        if (response.hits.hits[i]._source) {
          if (response.hits.hits[i]._source.latitude && response.hits.hits[i]._source.longitude) {
            if (citysearched == response.hits.hits[i]._source.city)
              continue;
            var default_arr = helper.getMapArray(response.hits.hits[i]._source);
            var specific_arr = [
              'src/assets/img/yellow_marker.png'
            ];
            var arr = default_arr.concat(specific_arr);
            draggedCheckin.push(arr);
          }
        }
      }
    }
    if (draggedCheckin.length != 0) {
      renderarray = [];
      if (places != null)
        renderarray.push.apply(renderarray, places);
      renderarray.push.apply(renderarray, draggedCheckin);
      if (streamedCheckin != null)
        renderarray.push.apply(renderarray, streamedCheckin);
      $scope.places = renderarray;
      $scope.$digest();
      $scope.$apply();
    }
  }

  $scope.showcategory = function(data) {
    places = [];
    if (categoryarray[data] == true)
      categoryarray[data] = false;
    else
      categoryarray[data] = true;
    for (var i = 0; i < searchedCheckinarray.length; i++) {
      if (categoryarray[searchedCheckinarray[i][4]] == true) {
        var arr = [];
        for (var j = 0; j < 10; j++) {
          arr[j] = searchedCheckinarray[i][j];
        }
        places.push(arr);
      }
    }
    renderarray = [];
    if (places != null) renderarray.push.apply(renderarray, places);
    if (draggedCheckin != null) renderarray.push.apply(renderarray, draggedCheckin);
    if (streamedCheckin != null) renderarray.push.apply(renderarray, streamedCheckin);
    $scope.places = renderarray;
  };

  function createJson(key, array) {
    var json = [];
    for (var i = 0; i < array.length; i++) {
      var object = {
        name: array[i],
        value: true
      };
      json.push(object);
    }
    return json;
  }

  var removecheckin = function() {
    var nowTime = new Date().getTime() / 1000;
    if (streamedCheckin.length != 0) {
      if (citysearched == streamedCheckin[0][10]) {
        streamedCheckin[0][9] = 'src/assets/img/red_marker.png';
        searchedCheckinarray.push(streamedCheckin[0]);
        categoryarray[streamedCheckin[0][4]] = true;
        $scope.subjects = createJson(categoryarray, Object.keys(categoryarray));
      }
      for (var i = places.length + draggedCheckin.length, j = 0; i < places.length + streamedCheckin.length + draggedCheckin.length; i++, j++) {
        if (nowTime - renderarray[i][11] < 5)
          break;
        if (nowTime - renderarray[i][11] >= 5) {
          renderarray.splice(i, 1);
          streamedCheckin.splice(j, 1);
        }
      }
      $scope.places = renderarray;
    }

    $scope.streamStatus = helper.getStatus(streamedCheckin.length);
    $scope.checkinfrequency = $scope.streamStatus.checkinfrequency;
    $scope.color = $scope.streamStatus.color;
    $scope.freqtext = $scope.streamStatus.freqtext;
    $scope.freqclass = $scope.streamStatus.freqclass;
    //No need $apply_solve
    // $scope.$digest();
    // $scope.$apply();
  }

  function closewindow() {
    var nowTime = new Date().getTime() / 1000;
    for (var i = 0; i < infowindowarray.length; i++) {
      if (nowTime - infowindowarray[i][3] < 3)
        break;
      if (nowTime - infowindowarray[i][3] >= 3) {
        var popup = infowindowarray[i][0]
        popup.close();
        index--;
        infowindowarray.splice(i, 1);
      }
    }
  }

  $interval(removecheckin, 5000);
  $interval(closewindow, 3000);

});
<commit_msg>Update index.js<commit_after>var myApp = angular.module('myApp', ['ngMap']);

myApp.controller('viewcontroller', function($scope, dataClient, $interval, $window, $document, helper, $timeout) {

  var places = [],
    renderarray = [],
    categoryarray = [],
    streamedCheckin = [],
    searchedCheckinarray = [],
    draggedCheckin = [],
    infowindowarray = [],
    citysearched,
    index = 0,
    current_date = new Date().getTime() / 1000,
    geocoder = new google.maps.Geocoder(), //variable for geocoding
    infowindow = new google.maps.InfoWindow(); //variable for map info

  $scope.activeContainer = '';

  $scope.init = function() {
    $scope.$on('mapInitialized', function(event, map) {
      $scope.mapobj = map;
      $scope.mapobj.setZoom(3);
      $scope.mapobj.setOptions({
        minZoom: 2,
        maxZoom: 15
      });
      $scope.mapobj.setCenter({
        lat: 0,
        lng: 0
      });
    });
    $scope.categoriesbox = false;
    $scope.checkinfrequency = "Count";
    $scope.freqtext = "";
    $scope.freqclass = "";
    $scope.inputcontainerHeight = {
      'height': "5rem"
    };
    $('[data-toggle="popover"]').popover({
      placement: 'right',
      html: true
    });
    $('[data-toggle="popover"]').mouseover(function() {
      $(this).popover('show');
    });
    $('[data-toggle="popover"]').mouseleave(function() {
      $(this).popover('hide');
    });
    $timeout(function() {
      $('div[title="Zoom in"]').closest('.gmnoprint').closest('.gmnoprint').addClass('zoomSet');
    }, 3000);
  };

  $scope.opencheckin = function(event, details) {
    $window.open('https://' + details, '_blank');
  };

  $scope.changeCategory = function(sub) {
    //sub.value = (sub.value==true ? false : true);
    $timeout(function() {
      $scope.showcategory(sub.name);
    }, 300);
  }

  $scope.showwindow = function(e, data, visible) {
    for (var i = 0; i < infowindowarray.length; i++) {
      if (infowindowarray[i][1] == data[1] && infowindowarray[i][2] == data[2]) {
        visible = false;
      }
    }
    if (visible) {
      infowindow = new google.maps.InfoWindow();
      infowindow.setContent('

' + '' + '	' + '' + '  ' + data[8] + ' says ' + '' + data[0] + '
 Place ' + data[7] + '

Visit this checkin

' + '
');
      var center = helper.getCenter($scope.mapobj.getZoom(), data);
      infowindow.setPosition(center);
      infowindow.setZIndex(2);
      infowindow.open($scope.mapobj);
      var current_date = new Date().getTime() / 1000;
      infowindowarray[index] = [infowindow, data[1], data[2], current_date];
      index++;
    }
  };

  $scope.searchquery = function() {
    try {
      //searchtext variable referred to the text in the search box
      if ($scope.searchtext != null && $scope.searchtext.replace(/\s/g, '').length) { //to check if search text is null
        $scope.activeContainer = 'active';
        var suggestClient = dataClient.getSuggestions($scope.searchtext);
        suggestClient.on('data', function(resp) {
          //$apply_solve
          $timeout(function() {
            $scope.row = true;
            $scope.categoriesbox = false;
            $scope.suggestions = resp.suggest.mysuggester[0].options;
          }, 0);
        }).on('error', function(err) {
          console.trace(err.message);
        });
      } else {
        $scope.suggestions = null;
        $scope.categoriesbox = false;
        $scope.row = false;
        $scope.activeContainer = '';
      }
    } catch (e) {
      console.log('error in try' + e);
    }
  };

  $scope.changesearchtext = function(text) {
    $scope.searchtext = text;
    $scope.row = false;
  }

  $scope.getData = function() {
    var searchClient = dataClient.getSearchCheckin(angular.lowercase($scope.searchtext));
    searchClient.on('data', function(res) {
      console.log(res);
      searchedCheckinarray = [];
      categoryarray = [];
      places = [];
      citysearched = angular.lowercase($scope.searchtext);
      $scope.row = false; //to hide suggestions
      searchProcess(res); //to fetch the data and to mark it on map
    }).on('error', function(err) {
      console.log("caught a stream error", err);
    });
  };

  function searchProcess(response) {
    if ($scope.searchtext != null && $scope.searchtext.replace(/\s/g, '').length) {
      $scope.categoriesbox = true;
      if (response.hits) {
        var hit_length = response.hits.hits.length;
        var current_date = new Date().getTime() / 1000;
        for (var i = 0; i < hit_length; i++) {
          var current_hit = response.hits.hits[i];
          if (current_hit._source.category && current_hit._source.latitude && current_hit._source.longitude && current_hit._source.category) {
            categoryarray[current_hit._source.category] = true;
            var default_arr = helper.getMapArray(current_hit._source);
            var specific_arr = [
              'src/assets/img/red_marker.png',
              current_date
            ];
            var arr = default_arr.concat(specific_arr);
            searchedCheckinarray.push(arr);
          }
        }
      }
      //GeoCoding to search the city
      geocoder.geocode({
        "address": $scope.searchtext
      }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
          var location = results[0].geometry.location,
            latitude = location.lat(),
            longitude = location.lng();
          $scope.mapobj.setCenter({
            lat: latitude,
            lng: longitude
          });
          $scope.mapobj.setZoom(11);
          $scope.$apply();
        }
      });
      renderarray = [];
      places.push.apply(places, searchedCheckinarray);
      renderarray.push.apply(renderarray, searchedCheckinarray);
      if (draggedCheckin !== null)
        renderarray.push.apply(renderarray, draggedCheckin);
      if (streamedCheckin != null)
        renderarray.push.apply(renderarray, streamedCheckin);
      $scope.places = renderarray;
      $scope.subjects = createJson(categoryarray, Object.keys(categoryarray));
      $scope.$digest();
      $scope.$apply();
      console.log($scope.places);
    }
  }

  var realtimeClient = dataClient.getLiveData();
  realtimeClient.on('data', function(res) {
    streamProcess(res); //to fetch the data and to mark it on map
  }).on('error', function(err) {
    console.log("caught a stream error", err);
  });

  function streamProcess(response) {
    if (response._source.latitude != null && response._source.longitude != null) {
      var default_arr = helper.getMapArray(response._source);
      var specific_arr = [
        'src/assets/img/green_marker.png',
        response._source.city,
        current_date
      ];
      var arr = default_arr.concat(specific_arr);

      streamedCheckin.push(arr);
      renderarray.push(arr);
      $scope.places = renderarray;

      $scope.streamStatus = helper.getStatus(streamedCheckin.length);
      $scope.checkinfrequency = $scope.streamStatus.checkinfrequency;
      $scope.color = $scope.streamStatus.color;
      $scope.freqtext = $scope.streamStatus.freqtext;
      $scope.freqclass = $scope.streamStatus.freqclass;

      $scope.$apply();
    }
  }

  $scope.draggedmap = function() {
    draggedCheckin = [];
    if ($scope.mapobj.getZoom() >= 5) {
      var dragClient = dataClient.getDragData($scope.mapobj.getCenter().lat(), $scope.mapobj.getCenter().lng());
      dragClient.on('data', function(res) {
        dragProcess(res); //to fetch the data and to mark it on map
      }).on('error', function(err) {
        console.log("caught a stream error", err);
      });
    } else if ($scope.mapobj.getZoom() === 4) {
      draggedCheckin = [];
      renderarray = [];
      if (places != null)
        renderarray.push.apply(renderarray, places);
      if (streamedCheckin !== null)
        renderarray.push.apply(renderarray, streamedCheckin);
      $scope.places = renderarray;
    }
  }

  function dragProcess(response) {
    if (response.hits) {
      for (var i = 0; i < response.hits.hits.length; i++) {
        if (response.hits.hits[i]._source) {
          if (response.hits.hits[i]._source.latitude && response.hits.hits[i]._source.longitude) {
            if (citysearched == response.hits.hits[i]._source.city)
              continue;
            var default_arr = helper.getMapArray(response.hits.hits[i]._source);
            var specific_arr = [
              'src/assets/img/yellow_marker.png'
            ];
            var arr = default_arr.concat(specific_arr);
            draggedCheckin.push(arr);
          }
        }
      }
    }
    if (draggedCheckin.length != 0) {
      renderarray = [];
      if (places != null)
        renderarray.push.apply(renderarray, places);
      renderarray.push.apply(renderarray, draggedCheckin);
      if (streamedCheckin != null)
        renderarray.push.apply(renderarray, streamedCheckin);
      $scope.places = renderarray;
      $scope.$digest();
      $scope.$apply();
    }
  }

  $scope.showcategory = function(data) {
    places = [];
    if (categoryarray[data] == true)
      categoryarray[data] = false;
    else
      categoryarray[data] = true;
    for (var i = 0; i < searchedCheckinarray.length; i++) {
      if (categoryarray[searchedCheckinarray[i][4]] == true) {
        var arr = [];
        for (var j = 0; j < 10; j++) {
          arr[j] = searchedCheckinarray[i][j];
        }
        places.push(arr);
      }
    }
    renderarray = [];
    if (places != null) renderarray.push.apply(renderarray, places);
    if (draggedCheckin != null) renderarray.push.apply(renderarray, draggedCheckin);
    if (streamedCheckin != null) renderarray.push.apply(renderarray, streamedCheckin);
    $scope.places = renderarray;
  };

  function createJson(key, array) {
    var json = [];
    for (var i = 0; i < array.length; i++) {
      var object = {
        name: array[i],
        value: true
      };
      json.push(object);
    }
    return json;
  }

  var removecheckin = function() {
    var nowTime = new Date().getTime() / 1000;
    if (streamedCheckin.length != 0) {
      if (citysearched == streamedCheckin[0][10]) {
        streamedCheckin[0][9] = 'src/assets/img/red_marker.png';
        searchedCheckinarray.push(streamedCheckin[0]);
        categoryarray[streamedCheckin[0][4]] = true;
        $scope.subjects = createJson(categoryarray, Object.keys(categoryarray));
      }
      for (var i = places.length + draggedCheckin.length, j = 0; i < places.length + streamedCheckin.length + draggedCheckin.length; i++, j++) {
        if (nowTime - renderarray[i][11] < 5)
          break;
        if (nowTime - renderarray[i][11] >= 5) {
          renderarray.splice(i, 1);
          streamedCheckin.splice(j, 1);
        }
      }
      $scope.places = renderarray;
    }

    $scope.streamStatus = helper.getStatus(streamedCheckin.length);
    $scope.checkinfrequency = $scope.streamStatus.checkinfrequency;
    $scope.color = $scope.streamStatus.color;
    $scope.freqtext = $scope.streamStatus.freqtext;
    $scope.freqclass = $scope.streamStatus.freqclass;
    //No need $apply_solve
    // $scope.$digest();
    // $scope.$apply();
  }

  function closewindow() {
    var nowTime = new Date().getTime() / 1000;
    for (var i = 0; i < infowindowarray.length; i++) {
      if (nowTime - infowindowarray[i][3] < 3)
        break;
      if (nowTime - infowindowarray[i][3] >= 3) {
        var popup = infowindowarray[i][0]
        popup.close();
        index--;
        infowindowarray.splice(i, 1);
      }
    }
  }

  $interval(removecheckin, 5000);
  $interval(closewindow, 3000);

});
<|endoftext|>


<commit_before>/* Touch-Sortable.js */
/* https://github.com/docubuzz/touch-sortable.js */

(function(d){d.fn.sortable=function(){return this.each(function(){function h(b){var c;b?(b=b.originalEvent,c=b.touches?b.touches[0].pageY:b.pageY,c<=j?c=j:c>=k&&(c=k),c-=f,a.css("top",c)):c=a.css("top").split("px")[0];c<-e?a.prev().length&&(a.siblings().css("position","relative"),a.prev().is(":animated")||a.prev().animate({top:e},150,function(){f-=e;d(this).insertAfter(a).css({top:""});a.css("top","+="+e);h()})):c>e&&a.next().length&&(a.siblings().css("position","relative"),a.next().is(":animated")||
a.next().animate({top:-e},150,function(){d(this).insertBefore(a).css({top:""});f+=e;a.css("top","-="+e);h()}));b&&b.preventDefault()}function g(){d("body").off(".sortable");a.prev().is(":animated")||a.next().is(":animated")?setTimeout(function(){g()},50):a.animate({top:"-="+a.css("top")},150,function(){a.css("top","auto").removeClass("inMotion").css("z-index","")})}var l="ontouchstart"in document.documentElement;d(this).children().on(l?"touchstart":"mousedown",function(b){b=b.originalEvent;a=d(l?
b.touches[0].target:b.target);j=a.parent().position().top;k=j+a.parent().innerHeight()+a.height();a.addClass("inMotion").css({position:"relative","z-index":1});b.touches?(f=b.touches[0].pageY,d("body").on("touchmove.sortable",h).on("touchend.sortable",g).on("touchcancel.sortable",g)):(f=b.pageY,d("body").on("mousemove.sortable",h).on("mouseup.sortable",g).on("mouseleave.sortable",g))}).css({cursor:"move","user-select":"none"}).attr("unselectable","on").on("selectstart",!1);var a,j,k,f,e=d(this).children(":nth-child(2)").offset().top-
d(this).children(":nth-child(1)").offset().top})}})(jQuery);
<commit_msg>Changed the way onEnd detects all animation is complete<commit_after>/* Touch-Sortable.js */
/* https://github.com/docubuzz/touch-sortable.js */

(function(c){c.fn.sortable=function(){return this.each(function(){function g(b){var d;b?(b=b.originalEvent,d=b.touches?b.touches[0].pageY:b.pageY,d<=h?d=h:d>=k&&(d=k),d-=f,a.css("top",d)):d=a.css("top").split("px")[0];d<-e?a.prev().length&&(a.siblings().css("position","relative"),a.prev().is(":animated")||a.prev().animate({top:e},150,function(){f-=e;c(this).insertAfter(a).css({top:""});a.css("top","+="+e);g()})):d>e&&a.next().length&&(a.siblings().css("position","relative"),a.next().is(":animated")||
a.next().animate({top:-e},150,function(){c(this).insertBefore(a).css({top:""});f+=e;a.css("top","-="+e);g()}));b&&b.preventDefault()}function j(){c("body").off(".sortable");c(".sortable").children().promise().done(function(){console.log("complete");a.animate({top:"-="+a.css("top")},150,function(){a.css("top","auto").removeClass("inMotion").css({"z-index":""})})})}var l="ontouchstart"in document.documentElement;c(this).children().on(l?"touchstart":"mousedown",function(b){b=b.originalEvent;a=c(l?b.touches[0].target:
b.target);h=a.parent().position().top;k=h+a.parent().innerHeight()+a.height();a.addClass("inMotion").css({position:"relative","z-index":1});b.touches?(f=b.touches[0].pageY,c("body").on("touchmove.sortable",g).on("touchend.sortable",j).on("touchcancel.sortable",j)):(f=b.pageY,c("body").on("mousemove.sortable",g).on("mouseup.sortable",j).on("mouseleave.sortable",j))}).css({cursor:"move","user-select":"none"}).attr("unselectable","on").on("selectstart",!1);var a,h,k,f,e=c(this).children(":nth-child(2)").offset().top-
c(this).children(":nth-child(1)").offset().top})}})(jQuery);
<|endoftext|>


<commit_before>/**
 * Class which handles individual tabs
 */
var Tab = Backbone.View.extend({
    tagName: 'li',

    events: {
        'click a': 'select',
        'click span': 'remove'
    },

    template: function() {
        // Generate caption
        var caption = '';
        if (this.content && this.content.query && this.content.query.name) {
            caption = this.content.query.name;
        } else {
            caption = "Unsaved Query (" + this.parent.queryCount + ")";
        }

        // Create tab
        return _.template("<a href='#<%= id %>'><%= caption %>" +
                "Close tab")
            ({
                id: this.id,
                caption: caption
            });
    },

    /**
     * Assign a unique ID and assign a Backbone view
     * to handle the tab's contents
     * @param args
     */
    initialize: function(args) {
        _.extend(this, Backbone.Events);

        this.content = args && args.content ?
                args.content : new Workspace({ tab: this });
        this.id = _.uniqueId('tab_');
    },

    /**
     * Render the tab and its contents
     * @returns tab
     */
    render: function() {
        // Render the content
        this.content.render();

        // Generate the element
        $(this.el).html(this.template());

        return this;
    },

    /**
     * Destroy any data associated with this tab and ensure proper
     * garbage collection to avoid memory leaks
     */
    destroy: function() {
        // Delete data
        this.content.query.destroy();
    },

    /**
     * Select a tab
     * @param el
     */
    select: function() {
        // Deselect all tabs
        this.parent.select(this);

        // Select the selected tab
        $(this.el).addClass('selected');

        // Trigger select event
        this.trigger('tab:select');

        return false;
    },

    /**
     * Remove a tab
     * @returns {Boolean}
     */
    remove: function() {
        // Remove the tab element
        $(this.el).remove();

        // Remove the tab
        this.destroy();

        // Remote the tab object from the container
        this.parent.remove(this);

        return false;
    }
});

/**
 * Class which controls the tab collection
 */
var TabSet = Backbone.View.extend({
    className: 'tabs',
    queryCount: 0,

    _tabs: [],

    /**
     * Render the tab containers
     * @returns tab_container
     */
    render: function() {
        $(this.el).html('

')
            .appendTo($('#header'));
        this.content = $('
').appendTo($('body'));
        return this;
    },

    /**
     * Add a tab to the collection
     * @param tab
     */
    add: function(tab) {
        // Add it to the set
        this._tabs.push(tab);
        this.queryCount++;
        tab.parent = this;

        // Render it in the background, then select it
        tab.render().select();
        $(tab.el).appendTo($(this.el).find('ul'));
    },

    /**
     * Select a tab, and move its contents to the tab panel
     * @param tab
     */
    select: function(tab) {
        // Clear selections
        $(this.el).find('li').removeClass('selected');

        // Replace the contents of the tab panel with the new content
        this.content.children().detach();
        this.content.append(tab.content.el);
    },

    /**
     * Remove a tab from the collection
     * @param tab
     */
    remove: function(tab) {
        for (var i = 0; i < this._tabs.length; i++) {
            if (this._tabs[i] == tab) {
                // Remove the element
                this._tabs.splice(i, 1);

                // Add another tab if the last one has been deleted
                if (this._tabs.length == 0) {
                    this.add(new Tab);
                }

                // Select the previous, or first tab
                var next = this._tabs[i] ? i : 0;
                this._tabs[next].select();
            }
        }
    }
});<commit_msg>Middle click now gives expected behavior<commit_after>/**
 * Class which handles individual tabs
 */
var Tab = Backbone.View.extend({
    tagName: 'li',

    events: {
        'click a': 'select',
        'mousedown a': 'remove',
        'click span': 'remove'
    },

    template: function() {
        // Generate caption
        var caption = '';
        if (this.content && this.content.query && this.content.query.name) {
            caption = this.content.query.name;
        } else {
            caption = "Unsaved Query (" + this.parent.queryCount + ")";
        }

        // Create tab
        return _.template("<a href='#<%= id %>'><%= caption %>" +
                "Close tab")
            ({
                id: this.id,
                caption: caption
            });
    },

    /**
     * Assign a unique ID and assign a Backbone view
     * to handle the tab's contents
     * @param args
     */
    initialize: function(args) {
        _.extend(this, Backbone.Events);

        this.content = args && args.content ?
                args.content : new Workspace({ tab: this });
        this.id = _.uniqueId('tab_');
    },

    /**
     * Render the tab and its contents
     * @returns tab
     */
    render: function() {
        // Render the content
        this.content.render();

        // Generate the element
        $(this.el).html(this.template());

        return this;
    },

    /**
     * Destroy any data associated with this tab and ensure proper
     * garbage collection to avoid memory leaks
     */
    destroy: function() {
        // Delete data
        this.content && this.content.query && this.content.query.destroy();
    },

    /**
     * Select a tab
     * @param el
     */
    select: function() {
        // Deselect all tabs
        this.parent.select(this);

        // Select the selected tab
        $(this.el).addClass('selected');

        // Trigger select event
        this.trigger('tab:select');

        return false;
    },

    /**
     * Remove a tab
     * @returns {Boolean}
     */
    remove: function(event) {
        if (!event || event.which === 2) {
            // Remove the tab element
            $(this.el).remove();

            // Remove the tab
            this.destroy();

            // Remote the tab object from the container
            this.parent.remove(this);
        }

        return false;
    }
});

/**
 * Class which controls the tab collection
 */
var TabSet = Backbone.View.extend({
    className: 'tabs',
    queryCount: 0,

    _tabs: [],

    /**
     * Render the tab containers
     * @returns tab_container
     */
    render: function() {
        $(this.el).html('

')
            .appendTo($('#header'));
        this.content = $('
').appendTo($('body'));
        return this;
    },

    /**
     * Add a tab to the collection
     * @param tab
     */
    add: function(tab) {
        // Add it to the set
        this._tabs.push(tab);
        this.queryCount++;
        tab.parent = this;

        // Render it in the background, then select it
        tab.render().select();
        $(tab.el).appendTo($(this.el).find('ul'));
    },

    /**
     * Select a tab, and move its contents to the tab panel
     * @param tab
     */
    select: function(tab) {
        // Clear selections
        $(this.el).find('li').removeClass('selected');

        // Replace the contents of the tab panel with the new content
        this.content.children().detach();
        this.content.append(tab.content.el);
    },

    /**
     * Remove a tab from the collection
     * @param tab
     */
    remove: function(tab) {
        for (var i = 0; i < this._tabs.length; i++) {
            if (this._tabs[i] == tab) {
                // Remove the element
                this._tabs.splice(i, 1);

                // Add another tab if the last one has been deleted
                if (this._tabs.length == 0) {
                    this.add(new Tab);
                }

                // Select the previous, or first tab
                var next = this._tabs[i] ? i : 0;
                this._tabs[next].select();
            }
        }
    }
});<|endoftext|>


<commit_before>(function(window)
{
    var Gitana = window.Gitana;

    Gitana.Chainable = Base.extend(
    /** @lends Gitana.Chainable.prototype */
    {
        /**
         * @constructs
         *
         * @param {Gitana.Driver} driver
         *
         * @class Provides common chaining functions used by various interface methods
         */
        constructor: function(driver)
        {
            var self = this;

            this.base();

            /**
             * Override the Chain.__copyState method so that it utilizes a base method that we can override
             * on a per-class basis.
             */
            this.__copyState = function(other) {
                Gitana.copyInto(this, other);
                this.chainCopyState(other);
            };

            ///////////////////////////////////////////////////////////////////////////////////////////////////////
            //
            // privileged methods
            //
            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            this.getDriver = function()
            {
                return driver;
            };

            this.getFactory = function()
            {
                return new Gitana.ObjectFactory();
            };

            this.httpError = function(httpError)
            {
                var err = new Gitana.Error();
                err.name = "Http Error";
                err.message = httpError.message;
                err.status = httpError.status;
                err.statusText = httpError.statusText;

                if (httpError.errorType)
                {
                    err.errorType = httpError.errorType;
                }

                // stack trace might be available
                if (httpError.stacktrace)
                {
                    err.stacktrace = httpError.stacktrace;
                }

                // info that might come back
                if (httpError.info)
                {
                    err.info = httpError.info;
                }

                this.error(err);

                return false;
            };

            this.missingNodeError = function(id)
            {
                var err = new Gitana.Error();
                err.name = "Missing Node error";
                err.message = "The node: " + id + " could not be found";

                this.error(err);

                return false;
            };

            /////////////////////////////////////////////////////////////////////////////////////////
            //
            // PRIVILEGED
            // CHAIN HANDLERS
            //
            /////////////////////////////////////////////////////////////////////////////////////////

            /**
             * Performs a GET from the server and populates the chainable.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGet = function(chainable, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaGet(uri, params, {}, function(response) {
                        chain.handleResponse(response);
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Creates an object on the server (write + read).
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param object
             * @param uri
             * @param params
             */
            this.chainCreate = function(chainable, object, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaPost(uri, params, object, function(status) {
                        driver.gitanaGet(uri + "/" + status.getId(), null, {}, function(response) {
                            chain.handleResponse(response);
                            chain.next();
                        }, function(http) {
                            self.httpError(http);
                        });
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;

                }, "chainCreate");
            };

            /**
             * Creates an object on the server using one URL and then reads it back using another URL.
             * This exists because the security responses don't include _doc fields like other responses.
             *
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param object
             * @param createUri
             * @param readUri
             */
            this.chainCreateEx = function(chainable, object, createUri, readUri)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(createUri)) {
                        createUri = createUri.call(self);
                    }

                    // create
                    driver.gitanaPost(createUri, null, object, function(status) {

                        // allow for closures on uri for late resolution
                        if (Gitana.isFunction(readUri)) {
                            readUri = readUri.call(self, status);
                        }

                        driver.gitanaGet(readUri, null, {}, function(response) {
                            chain.handleResponse(response);
                            chain.next();
                        }, function(http) {
                            self.httpError(http);
                        });
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a POST to the server and populates the chainable with results.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             * @param payload
             */
            this.chainPost = function(chainable, uri, params, payload)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaPost(uri, params, payload, function(response) {
                        chain.handleResponse(response);
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a POST to the server.  The response is not handled.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             * @param payload (optional)
             * @param contentType (optional) - example "text/plain"
             */
            this.chainPostEmpty = function(chainable, uri, params, payload, contentType)
            {
                var self = this;

                // if no payload, set to empty
                if (!payload && contentType)
                {
                    if (contentType.indexOf("text/") > -1)
                    {
                        payload = "";
                    }
                    else if (contentType === "application/json")
                    {
                        payload = {};
                    }
                }

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaPost(uri, params, payload, function(response) {
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a POST to the server.  The response is not handled.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             * @param contentType (optional) - example "text/plain"
             * @param payload (optional)
             */
            this.chainUpload = function(chainable, uri, params, contentType, payload)
            {
                var self = this;

                // if no payload, set to empty
                if (!payload && contentType)
                {
                    if (contentType.indexOf("text/") > -1)
                    {
                        payload = "";
                    }
                    else if (contentType === "application/json")
                    {
                        payload = {};
                    }
                }

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaUpload(uri, params, contentType, payload, function(response) {
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a GET to the server and pushes the response into the chain.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGetResponse = function(chainable, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaGet(uri, params, {}, function(response) {
                        chain.next(response);
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a GET to the server and pushes the text response to the callback.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGetResponseText = function(chainable, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaRequest("GET", uri, params, "text/plain", null, {}, function(response) {
                        chain.next(response);
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a GET to the server and pushes the "rows" response attribute into the chain.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGetResponseRows = function(chainable, uri, params)
            {
                return this.chainGetResponse(chainable, uri, params).then(function(response) {
                    return response["rows"];
                });
            };

            /**
             * Performs a GET to the server and checks whether the "rows" array attribute of the response
             * has the given value.
             *
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param value
             */
            this.chainHasResponseRow = function(chainable, uri, value)
            {
                return this.chainGetResponse(chainable, uri).then(function(response) {
                    var authorized = false;
                    for (var i = 0; i < response.rows.length; i++)
                    {
                        if (response.rows[i].toLowerCase() == value.toLowerCase())
                        {
                            authorized = true;
                        }
                    }
                    return authorized;
                });
            };

            /**
             * Performs a POST to the server and pushes the response into the chain.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainPostResponse = function(chainable, uri, params, payload)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaPost(uri, params, payload, function(response) {
                        chain.next(response);
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Helper to gets the principal id for a principal object, json structure or principal id itself.
             * This returns something like "domainId/principalId"
             *
             * @param principal
             */
            this.extractPrincipalDomainQualifiedId = function(principal, defaultDomainId)
            {
                var identifiers = this.extractPrincipalIdentifiers(principal, defaultDomainId);

                return identifiers["domain"] + "/" + identifiers["principal"];
            };

            /**
             * Helper to gets the principal id for a principal object, json structure or principal id itself.
             * This returns something like "domainId/principalId"
             *
             * @param principal principal object or string (principal id or domain qualified principal id)
             * @param defaultDomainId
             */
            this.extractPrincipalIdentifiers = function(principal, defaultDomainId)
            {
                var identifiers = {};

                if (!defaultDomainId)
                {
                    defaultDomainId = "default";
                }

                if (Gitana.isString(principal))
                {
                    var x = principal.indexOf("/");
                    if (x > -1)
                    {
                        identifiers["domain"] = principal.substring(0, x);
                        identifiers["principal"] = principal.substring(x + 1);
                    }
                    else
                    {
                        identifiers["domain"] = defaultDomainId;
                        identifiers["principal"] = principal;
                    }
                }
                else if (principal.objectType && principal.objectType() == "Gitana.DomainPrincipal")
                {
                    identifiers["domain"] = principal.getDomainId();
                    identifiers["principal"] = principal.getId();
                }
                else if (principal.objectType && principal.objectType() == "Gitana.TeamMember")
                {
                    identifiers["domain"] = principal["domainId"];
                    identifiers["principal"] = principal["_doc"];
                }
                else if (principal["_doc"])
                {
                    identifiers["domain"] = defaultDomainId;
                    identifiers["principal"] = principal["_doc"];
                }
                else if (principal["name"])
                {
                    identifiers["domain"] = defaultDomainId;
                    identifiers["principal"] = principal["name"];
                }

                return identifiers;
            };
        },

        /**
         * Used internally during chain copy going forward or backward through the chain.
         *
         * This is wired into the Chain.__copyState method and allows a convenient way to override
         * chain copy behavior on a per-object-type basis.
         *
         * @param otherObject
         */
        chainCopyState: function(otherObject)
        {
        }

    });

})(window);
<commit_msg>HTTP errors retain response text and data, version bump<commit_after>(function(window)
{
    var Gitana = window.Gitana;

    Gitana.Chainable = Base.extend(
    /** @lends Gitana.Chainable.prototype */
    {
        /**
         * @constructs
         *
         * @param {Gitana.Driver} driver
         *
         * @class Provides common chaining functions used by various interface methods
         */
        constructor: function(driver)
        {
            var self = this;

            this.base();

            /**
             * Override the Chain.__copyState method so that it utilizes a base method that we can override
             * on a per-class basis.
             */
            this.__copyState = function(other) {
                Gitana.copyInto(this, other);
                this.chainCopyState(other);
            };

            ///////////////////////////////////////////////////////////////////////////////////////////////////////
            //
            // privileged methods
            //
            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            this.getDriver = function()
            {
                return driver;
            };

            this.getFactory = function()
            {
                return new Gitana.ObjectFactory();
            };

            this.httpError = function(httpError)
            {
                var err = new Gitana.Error();
                err.name = "Http Error";
                err.message = httpError.message;
                err.status = httpError.status;
                err.statusText = httpError.statusText;

                if (httpError.errorType)
                {
                    err.errorType = httpError.errorType;
                }

                // stack trace might be available
                if (httpError.stacktrace)
                {
                    err.stacktrace = httpError.stacktrace;
                }

                // info that might come back
                if (httpError.info)
                {
                    err.info = httpError.info;
                }

                // any text?  if so, capture it
                if (httpError.response && httpError.response.text)
                {
                    err.responseText = httpError.response.text;

                    // and also make an attempt to convert to JSON data
                    try {
                        err.responseData = JSON.parse(err.responseText);
                    } catch (e) { }
                }

                this.error(err);

                return false;
            };

            this.missingNodeError = function(id)
            {
                var err = new Gitana.Error();
                err.name = "Missing Node error";
                err.message = "The node: " + id + " could not be found";

                this.error(err);

                return false;
            };

            /////////////////////////////////////////////////////////////////////////////////////////
            //
            // PRIVILEGED
            // CHAIN HANDLERS
            //
            /////////////////////////////////////////////////////////////////////////////////////////

            /**
             * Performs a GET from the server and populates the chainable.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGet = function(chainable, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaGet(uri, params, {}, function(response) {
                        chain.handleResponse(response);
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Creates an object on the server (write + read).
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param object
             * @param uri
             * @param params
             */
            this.chainCreate = function(chainable, object, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaPost(uri, params, object, function(status) {
                        driver.gitanaGet(uri + "/" + status.getId(), null, {}, function(response) {
                            chain.handleResponse(response);
                            chain.next();
                        }, function(http) {
                            self.httpError(http);
                        });
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;

                }, "chainCreate");
            };

            /**
             * Creates an object on the server using one URL and then reads it back using another URL.
             * This exists because the security responses don't include _doc fields like other responses.
             *
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param object
             * @param createUri
             * @param readUri
             */
            this.chainCreateEx = function(chainable, object, createUri, readUri)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(createUri)) {
                        createUri = createUri.call(self);
                    }

                    // create
                    driver.gitanaPost(createUri, null, object, function(status) {

                        // allow for closures on uri for late resolution
                        if (Gitana.isFunction(readUri)) {
                            readUri = readUri.call(self, status);
                        }

                        driver.gitanaGet(readUri, null, {}, function(response) {
                            chain.handleResponse(response);
                            chain.next();
                        }, function(http) {
                            self.httpError(http);
                        });
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a POST to the server and populates the chainable with results.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             * @param payload
             */
            this.chainPost = function(chainable, uri, params, payload)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaPost(uri, params, payload, function(response) {
                        chain.handleResponse(response);
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a POST to the server.  The response is not handled.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             * @param payload (optional)
             * @param contentType (optional) - example "text/plain"
             */
            this.chainPostEmpty = function(chainable, uri, params, payload, contentType)
            {
                var self = this;

                // if no payload, set to empty
                if (!payload && contentType)
                {
                    if (contentType.indexOf("text/") > -1)
                    {
                        payload = "";
                    }
                    else if (contentType === "application/json")
                    {
                        payload = {};
                    }
                }

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaPost(uri, params, payload, function(response) {
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a POST to the server.  The response is not handled.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             * @param contentType (optional) - example "text/plain"
             * @param payload (optional)
             */
            this.chainUpload = function(chainable, uri, params, contentType, payload)
            {
                var self = this;

                // if no payload, set to empty
                if (!payload && contentType)
                {
                    if (contentType.indexOf("text/") > -1)
                    {
                        payload = "";
                    }
                    else if (contentType === "application/json")
                    {
                        payload = {};
                    }
                }

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    // create
                    driver.gitanaUpload(uri, params, contentType, payload, function(response) {
                        chain.next();
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a GET to the server and pushes the response into the chain.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGetResponse = function(chainable, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaGet(uri, params, {}, function(response) {
                        chain.next(response);
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a GET to the server and pushes the text response to the callback.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGetResponseText = function(chainable, uri, params)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaRequest("GET", uri, params, "text/plain", null, {}, function(response) {
                        chain.next(response);
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Performs a GET to the server and pushes the "rows" response attribute into the chain.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainGetResponseRows = function(chainable, uri, params)
            {
                return this.chainGetResponse(chainable, uri, params).then(function(response) {
                    return response["rows"];
                });
            };

            /**
             * Performs a GET to the server and checks whether the "rows" array attribute of the response
             * has the given value.
             *
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param value
             */
            this.chainHasResponseRow = function(chainable, uri, value)
            {
                return this.chainGetResponse(chainable, uri).then(function(response) {
                    var authorized = false;
                    for (var i = 0; i < response.rows.length; i++)
                    {
                        if (response.rows[i].toLowerCase() == value.toLowerCase())
                        {
                            authorized = true;
                        }
                    }
                    return authorized;
                });
            };

            /**
             * Performs a POST to the server and pushes the response into the chain.
             * Proceeds with the chain as bound to the chainable.
             *
             * @param chainable
             * @param uri
             * @param params
             */
            this.chainPostResponse = function(chainable, uri, params, payload)
            {
                var self = this;

                return this.subchain(chainable).then(function() {

                    var chain = this;

                    // allow for closures on uri for late resolution
                    if (Gitana.isFunction(uri)) {
                        uri = uri.call(self);
                    }

                    driver.gitanaPost(uri, params, payload, function(response) {
                        chain.next(response);
                    }, function(http) {
                        self.httpError(http);
                    });

                    // NOTE: we return false to tell the chain that we'll manually call next()
                    return false;
                });
            };

            /**
             * Helper to gets the principal id for a principal object, json structure or principal id itself.
             * This returns something like "domainId/principalId"
             *
             * @param principal
             */
            this.extractPrincipalDomainQualifiedId = function(principal, defaultDomainId)
            {
                var identifiers = this.extractPrincipalIdentifiers(principal, defaultDomainId);

                return identifiers["domain"] + "/" + identifiers["principal"];
            };

            /**
             * Helper to gets the principal id for a principal object, json structure or principal id itself.
             * This returns something like "domainId/principalId"
             *
             * @param principal principal object or string (principal id or domain qualified principal id)
             * @param defaultDomainId
             */
            this.extractPrincipalIdentifiers = function(principal, defaultDomainId)
            {
                var identifiers = {};

                if (!defaultDomainId)
                {
                    defaultDomainId = "default";
                }

                if (Gitana.isString(principal))
                {
                    var x = principal.indexOf("/");
                    if (x > -1)
                    {
                        identifiers["domain"] = principal.substring(0, x);
                        identifiers["principal"] = principal.substring(x + 1);
                    }
                    else
                    {
                        identifiers["domain"] = defaultDomainId;
                        identifiers["principal"] = principal;
                    }
                }
                else if (principal.objectType && principal.objectType() == "Gitana.DomainPrincipal")
                {
                    identifiers["domain"] = principal.getDomainId();
                    identifiers["principal"] = principal.getId();
                }
                else if (principal.objectType && principal.objectType() == "Gitana.TeamMember")
                {
                    identifiers["domain"] = principal["domainId"];
                    identifiers["principal"] = principal["_doc"];
                }
                else if (principal["_doc"])
                {
                    identifiers["domain"] = defaultDomainId;
                    identifiers["principal"] = principal["_doc"];
                }
                else if (principal["name"])
                {
                    identifiers["domain"] = defaultDomainId;
                    identifiers["principal"] = principal["name"];
                }

                return identifiers;
            };
        },

        /**
         * Used internally during chain copy going forward or backward through the chain.
         *
         * This is wired into the Chain.__copyState method and allows a convenient way to override
         * chain copy behavior on a per-object-type basis.
         *
         * @param otherObject
         */
        chainCopyState: function(otherObject)
        {
        }

    });

})(window);
<|endoftext|>


<commit_before>var everyauth = require('everyauth');
var users = {};
var nextUserId = 0;

everyauth.github
  .appId(process.env.GITHUB_APP_ID)
  .appSecret(process.env.GITHUB_APP_SECRET)
  .entryPath('/auth/github')
  .callbackPath('/auth/github/callback')
  .scope('user:email')
  .findOrCreateUser(function (session, accessToken, accessTokenExtra, user) {
    console.log(user.id);
    return users[user.id] || (users[user.id] = user);
  })
  .redirectPath('/');

everyauth.everymodule
  .findUserById(function (id, callback) {
    callback(null, users[id]);
  });

exports.middleware = function () {
  return everyauth.middleware();
};<commit_msg>Remove logging<commit_after>var everyauth = require('everyauth');
var users = {};
var nextUserId = 0;

everyauth.github
  .appId(process.env.GITHUB_APP_ID)
  .appSecret(process.env.GITHUB_APP_SECRET)
  .entryPath('/auth/github')
  .callbackPath('/auth/github/callback')
  .scope('user:email')
  .findOrCreateUser(function (session, accessToken, accessTokenExtra, user) {
    return users[user.id] || (users[user.id] = user);
  })
  .redirectPath('/');

everyauth.everymodule
  .findUserById(function (id, callback) {
    callback(null, users[id]);
  });

exports.middleware = function () {
  return everyauth.middleware();
};
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const glob = require('glob');
const camelCase = require('camelcase');
const ngc = require('@angular/compiler-cli/src/main').main;
const rollup = require('rollup');
const uglify = require('rollup-plugin-uglify');
const sourcemaps = require('rollup-plugin-sourcemaps');
const nodeResolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');

const inlineResources = require('./inline-resources');

const libName = require('./package.json').name;
const rootFolder = path.join(__dirname);
const compilationFolder = path.join(rootFolder, 'out-tsc');
const srcFolder = path.join(rootFolder, 'src/lib');
const distFolder = path.join(rootFolder, 'dist');
const tempLibFolder = path.join(compilationFolder, 'lib');
const es5OutputFolder = path.join(compilationFolder, 'lib-es5');
const es2015OutputFolder = path.join(compilationFolder, 'lib-es2015');

return Promise.resolve()
  // Copy library to temporary folder and inline html/css.
  .then(() => _relativeCopy(`**/*`, srcFolder, tempLibFolder)
    .then(() => inlineResources(tempLibFolder))
    .then(() => console.log('Inlining succeeded.'))
  )
  // Compile to ES2015.
  .then(() => ngc({ project: `${tempLibFolder}/tsconfig.lib.json` })
    .then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
    .then(() => console.log('ES2015 compilation succeeded.'))
  )
  // Compile to ES5.
  .then(() => ngc({ project: `${tempLibFolder}/tsconfig.es5.json` })
    .then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
    .then(() => console.log('ES5 compilation succeeded.'))
  )
  // Copy typings and metadata to `dist/` folder.
  .then(() => Promise.resolve()
    .then(() => _relativeCopy('**/*.d.ts', es2015OutputFolder, distFolder))
    .then(() => _relativeCopy('**/*.metadata.json', es2015OutputFolder, distFolder))
    .then(() => console.log('Typings and metadata copy succeeded.'))
  )
  // Bundle lib.
  .then(() => {
    // Base configuration.
    const es5Entry = path.join(es5OutputFolder, `${libName}.js`);
    const es2015Entry = path.join(es2015OutputFolder, `${libName}.js`);
    const rollupBaseConfig = {
      moduleName: camelCase(libName),
      sourceMap: true,
      // ATTENTION:
      // Add any dependency or peer dependency your library to `globals` and `external`.
      // This is required for UMD bundle users.
      globals: {
        // The key here is library name, and the value is the the name of the global variable name
        // the window object.
        // See https://github.com/rollup/rollup/wiki/JavaScript-API#globals for more.
        '@angular/core': 'ng.core'
      },
      external: [
        // List of dependencies
        // See https://github.com/rollup/rollup/wiki/JavaScript-API#external for more.
        '@angular/core'
      ],
      plugins: [
        commonjs({
          include: ['node_modules/rxjs/**']
        }),
        sourcemaps(),
        nodeResolve({ jsnext: true, module: true })
      ]
    };

    // UMD bundle.
    const umdConfig = Object.assign({}, rollupBaseConfig, {
      entry: es5Entry,
      dest: path.join(distFolder, `bundles`, `${libName}.umd.js`),
      format: 'umd',
    });

    // Minified UMD bundle.
    const minifiedUmdConfig = Object.assign({}, rollupBaseConfig, {
      entry: es5Entry,
      dest: path.join(distFolder, `bundles`, `${libName}.umd.min.js`),
      format: 'umd',
      plugins: rollupBaseConfig.plugins.concat([uglify({})])
    });

    // ESM+ES5 flat module bundle.
    const fesm5config = Object.assign({}, rollupBaseConfig, {
      entry: es5Entry,
      dest: path.join(distFolder, `${libName}.es5.js`),
      format: 'es'
    });

    // ESM+ES2015 flat module bundle.
    const fesm2015config = Object.assign({}, rollupBaseConfig, {
      entry: es2015Entry,
      dest: path.join(distFolder, `${libName}.js`),
      format: 'es'
    });

    const allBundles = [
      umdConfig,
      minifiedUmdConfig,
      fesm5config,
      fesm2015config
    ].map(cfg => rollup.rollup(cfg).then(bundle => bundle.write(cfg)));

    return Promise.all(allBundles)
      .then(() => console.log('All bundles generated successfully.'))
  })
  // Copy package files
  .then(() => Promise.resolve()
    .then(() => _relativeCopy('LICENSE', rootFolder, distFolder))
    .then(() => _relativeCopy('package.json', rootFolder, distFolder))
    .then(() => _relativeCopy('README.md', rootFolder, distFolder))
    .then(() => console.log('Package files copy succeeded.'))
  )
  .catch(e => {
    console.error('\Build failed. See below for errors.\n');
    console.error(e);
    process.exit(1);
  });

// Copy files maintaining relative paths.
function _relativeCopy(fileGlob, from, to) {
  return new Promise((resolve, reject) => {
    glob(fileGlob, { cwd: from, nodir: true }, (err, files) => {
      if (err) reject(err);
      files.forEach(file => {
        const origin = path.join(from, file);
        const dest = path.join(to, file);
        const data = fs.readFileSync(origin, 'utf-8');
        _recursiveMkDir(path.dirname(dest));
        fs.writeFileSync(dest, data);
        resolve();
      })
    })
  });
}

// Recursively create a dir.
function _recursiveMkDir(dir) {
  if (!fs.existsSync(dir)) {
    _recursiveMkDir(path.dirname(dir));
    fs.mkdirSync(dir);
  }
}
<commit_msg>Add @angular/forms to rollup globals<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const glob = require('glob');
const camelCase = require('camelcase');
const ngc = require('@angular/compiler-cli/src/main').main;
const rollup = require('rollup');
const uglify = require('rollup-plugin-uglify');
const sourcemaps = require('rollup-plugin-sourcemaps');
const nodeResolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');

const inlineResources = require('./inline-resources');

const libName = require('./package.json').name;
const rootFolder = path.join(__dirname);
const compilationFolder = path.join(rootFolder, 'out-tsc');
const srcFolder = path.join(rootFolder, 'src/lib');
const distFolder = path.join(rootFolder, 'dist');
const tempLibFolder = path.join(compilationFolder, 'lib');
const es5OutputFolder = path.join(compilationFolder, 'lib-es5');
const es2015OutputFolder = path.join(compilationFolder, 'lib-es2015');

return Promise.resolve()
  // Copy library to temporary folder and inline html/css.
  .then(() => _relativeCopy(`**/*`, srcFolder, tempLibFolder)
    .then(() => inlineResources(tempLibFolder))
    .then(() => console.log('Inlining succeeded.'))
  )
  // Compile to ES2015.
  .then(() => ngc({ project: `${tempLibFolder}/tsconfig.lib.json` })
    .then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
    .then(() => console.log('ES2015 compilation succeeded.'))
  )
  // Compile to ES5.
  .then(() => ngc({ project: `${tempLibFolder}/tsconfig.es5.json` })
    .then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
    .then(() => console.log('ES5 compilation succeeded.'))
  )
  // Copy typings and metadata to `dist/` folder.
  .then(() => Promise.resolve()
    .then(() => _relativeCopy('**/*.d.ts', es2015OutputFolder, distFolder))
    .then(() => _relativeCopy('**/*.metadata.json', es2015OutputFolder, distFolder))
    .then(() => console.log('Typings and metadata copy succeeded.'))
  )
  // Bundle lib.
  .then(() => {
    // Base configuration.
    const es5Entry = path.join(es5OutputFolder, `${libName}.js`);
    const es2015Entry = path.join(es2015OutputFolder, `${libName}.js`);
    const rollupBaseConfig = {
      moduleName: camelCase(libName),
      sourceMap: true,
      // ATTENTION:
      // Add any dependency or peer dependency your library to `globals` and `external`.
      // This is required for UMD bundle users.
      globals: {
        // The key here is library name, and the value is the the name of the global variable name
        // the window object.
        // See https://github.com/rollup/rollup/wiki/JavaScript-API#globals for more.
        '@angular/core': 'ng.core',
        '@angular/forms': 'ng.forms',
      },
      external: [
        // List of dependencies
        // See https://github.com/rollup/rollup/wiki/JavaScript-API#external for more.
        '@angular/core',
        '@angular/forms',
      ],
      plugins: [
        commonjs({
          include: ['node_modules/rxjs/**']
        }),
        sourcemaps(),
        nodeResolve({ jsnext: true, module: true })
      ]
    };

    // UMD bundle.
    const umdConfig = Object.assign({}, rollupBaseConfig, {
      entry: es5Entry,
      dest: path.join(distFolder, `bundles`, `${libName}.umd.js`),
      format: 'umd',
    });

    // Minified UMD bundle.
    const minifiedUmdConfig = Object.assign({}, rollupBaseConfig, {
      entry: es5Entry,
      dest: path.join(distFolder, `bundles`, `${libName}.umd.min.js`),
      format: 'umd',
      plugins: rollupBaseConfig.plugins.concat([uglify({})])
    });

    // ESM+ES5 flat module bundle.
    const fesm5config = Object.assign({}, rollupBaseConfig, {
      entry: es5Entry,
      dest: path.join(distFolder, `${libName}.es5.js`),
      format: 'es'
    });

    // ESM+ES2015 flat module bundle.
    const fesm2015config = Object.assign({}, rollupBaseConfig, {
      entry: es2015Entry,
      dest: path.join(distFolder, `${libName}.js`),
      format: 'es'
    });

    const allBundles = [
      umdConfig,
      minifiedUmdConfig,
      fesm5config,
      fesm2015config
    ].map(cfg => rollup.rollup(cfg).then(bundle => bundle.write(cfg)));

    return Promise.all(allBundles)
      .then(() => console.log('All bundles generated successfully.'))
  })
  // Copy package files
  .then(() => Promise.resolve()
    .then(() => _relativeCopy('LICENSE', rootFolder, distFolder))
    .then(() => _relativeCopy('package.json', rootFolder, distFolder))
    .then(() => _relativeCopy('README.md', rootFolder, distFolder))
    .then(() => console.log('Package files copy succeeded.'))
  )
  .catch(e => {
    console.error('\Build failed. See below for errors.\n');
    console.error(e);
    process.exit(1);
  });

// Copy files maintaining relative paths.
function _relativeCopy(fileGlob, from, to) {
  return new Promise((resolve, reject) => {
    glob(fileGlob, { cwd: from, nodir: true }, (err, files) => {
      if (err) reject(err);
      files.forEach(file => {
        const origin = path.join(from, file);
        const dest = path.join(to, file);
        const data = fs.readFileSync(origin, 'utf-8');
        _recursiveMkDir(path.dirname(dest));
        fs.writeFileSync(dest, data);
        resolve();
      })
    })
  });
}

// Recursively create a dir.
function _recursiveMkDir(dir) {
  if (!fs.existsSync(dir)) {
    _recursiveMkDir(path.dirname(dir));
    fs.mkdirSync(dir);
  }
}
<|endoftext|>


<commit_before>game.SpendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('exp-screen')), -10); // TODO

		me.input.bindKey(me.input.KEY.ENTER, "start");

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [10, 10, 300, 50]);
				this.font = new me.Font("Arial", 46, "white");
			},

			draw: function(renderer){
				this.font.draw(renderer.getContext(), "PRESS F1-F4 TO BUY, F5 TO SKIP", this.pos.x, this.pos.y);
				this.font.draw(renderer.getContext(), "CURRENT EXP: " + game.data.exp.toString(), this.pos.x + 100, this.pos.y + 50);
				this.font.draw(renderer.getContext(), "F1: INCREASE GOLD PRODUCTION " + game.data.exp.toString(), this.pos.x + 200, this.pos.y + 100);
				this.font.draw(renderer.getContext(), "F2: ADD STARTING GOLD " + game.data.exp.toString(), this.pos.x + 200, this.pos.y + 150);
				this.font.draw(renderer.getContext(), "F3: INCREASE ATTACK DAMAGE: " + game.data.exp.toString(), this.pos.x + 200, this.pos.y + 200);
				this.font.draw(renderer.getContext(), "F4: INCREASE STARTING HEALTH " + game.data.exp.toString(), this.pos.x + 200, this.pos.y + 250);
			}

		})));

	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {

	}
});
<commit_msg>video 44 finshing spendEXP<commit_after>game.SpendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('exp-screen')), -10); // TODO

		me.input.bindKey(me.input.KEY.F1, "F1");
		me.input.bindKey(me.input.KEY.F2, "F2");
		me.input.bindKey(me.input.KEY.F3, "F3");
		me.input.bindKey(me.input.KEY.F4, "F4");
		me.input.bindKey(me.input.KEY.F5, "F5");

		me.input.bindKey(me.input.KEY.ENTER, "start");

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [10, 10, 300, 50]);
				this.font = new me.Font("Arial", 26, "white");
			},

			draw: function(renderer){
				this.font.draw(renderer.getContext(), "PRESS F1-F4 TO BUY, F5 TO SKIP", this.pos.x, this.pos.y);
				this.font.draw(renderer.getContext(), "CURRENT EXP: " + game.data.exp.toString(), this.pos.x + 100, this.pos.y + 50);
				this.font.draw(renderer.getContext(), "F1: INCREASE GOLD PRODUCTION CURRENT LEVEL: " + game.data.exp1.toString() + " COST: " + ((game.data.exp1 + 1) + 10), this.pos.x, this.pos.y + 100);
				this.font.draw(renderer.getContext(), "F2: ADD STARTING GOLD ", this.pos.x, this.pos.y + 150);
				this.font.draw(renderer.getContext(), "F3: INCREASE ATTACK DAMAGE: ", this.pos.x, this.pos.y + 200);
				this.font.draw(renderer.getContext(), "F4: INCREASE STARTING HEALTH ", this.pos.x, this.pos.y + 250);
			}

		})));

		this.handler = me.event.subscribe(me.event.KEYDOWN, function (action, keyCode, edge) {
			if(action === "F1"){

			}else if(action === "F2"){

			}else if(action === "F3"){

			}else if(action === "F4"){

			}else if(action === "F5"){
				me.state.change(me.state.PLAY);
			}
		});
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		me.input.unbindKey(me.input.KEY.F1, "F1");
		me.input.unbindKey(me.input.KEY.F2, "F2");
		me.input.unbindKey(me.input.KEY.F3, "F3");
		me.input.unbindKey(me.input.KEY.F4, "F4");
		me.input.unbindKey(me.input.KEY.F5, "F5");
		me.event.unsubscribe(this.handler);
	}
});
<|endoftext|>


<commit_before>var _gpio,
  yellowLed = 40,
  redLed = 38,
  heartbeatDelayTime = 5000,
  heartbeatOnTime = 250;
exports.setup = function(gpio){
  _gpio = gpio;
  _gpio.setup(yellowLed, _gpio.DIR_OUT,heartbeat);
  _gpio.setup(redLed, _gpio.DIR_OUT);
}
function heartbeat(){
  _gpio.write(yellowLed, false);
  setTimeout(function() {
    _gpio.write(yellowLed, false, function(err) {
      if (err) throw err;
      off();
    });
  }, heartbeatDelayTime);
}
function off() {
    setTimeout(function() {
      _gpio.write(yellowLed, true, function(err) {
        if (err) throw err;
        on();
      });
    }, heartbeatOnTime);
}
<commit_msg>started junctionbox firmware and modules<commit_after>var _gpio,
  yellowLed = 40,
  redLed = 38,
  heartbeatDelayTime = 5000,
  heartbeatOnTime = 250;
exports.setup = function(gpio){
  _gpio = gpio;
  _gpio.setup(yellowLed, _gpio.DIR_OUT,heartbeat);
  _gpio.setup(redLed, _gpio.DIR_OUT);
}
function heartbeat(){
  _gpio.write(yellowLed, false);
  setTimeout(function() {
    _gpio.write(yellowLed, false, function(err) {
      if (err) throw err;
      off();
    });
  }, heartbeatDelayTime);
}
function off() {
    setTimeout(function() {
      _gpio.write(yellowLed, true, function(err) {
        if (err) throw err;
        heartbeat();
      });
    }, heartbeatOnTime);
}
<|endoftext|>


<commit_before>iD.behavior.Draw = function(context) {
    var event = d3.dispatch('move', 'click', 'clickWay', 'clickNode', 'clickMidpoint', 'undo', 'cancel', 'finish'),
        keybinding = d3.keybinding('draw'),
        hover = iD.behavior.Hover(),
        down;

    function datum() {
        if (d3.event.altKey) {
            return {};
        } else {
            return d3.event.target.__data__ || {};
        }
    }

    function mousedown() {
        down = true;
    }

    function mouseup() {
        down = false;
    }

    function mousemove() {
        if (!down) {
            event.move(datum());
        }
    }

    function click() {
        var d = datum();
        if (d.type === 'way') {
            var choice = iD.geo.chooseIndex(d, d3.mouse(context.surface().node()), context);
            event.clickWay(d, choice.loc, choice.index);

        } else if (d.type === 'node') {
            event.clickNode(d);

        } else if (d.type === 'midpoint') {
            event.clickMidpoint(d);

        } else {
            event.click(context.map().mouseCoordinates());
        }
    }

    function keydown() {
        if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
            context.uninstall(hover);
        }
    }

    function keyup() {
        if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
            context.install(hover);
        }
    }

    function backspace() {
        d3.event.preventDefault();
        event.undo();
    }

    function del() {
        d3.event.preventDefault();
        event.cancel();
    }

    function ret() {
        d3.event.preventDefault();
        event.finish();
    }

    function draw(selection) {
        context.install(hover);

        keybinding
            .on('⌫', backspace)
            .on('⌦', del)
            .on('⎋', ret)
            .on('↩', ret);

        selection
            .on('mousedown.draw', mousedown)
            .on('mouseup.draw', mouseup)
            .on('mousemove.draw', mousemove)
            .on('click.draw', click);

        d3.select(document)
            .call(keybinding)
            .on('keydown.draw', keydown)
            .on('keyup.draw', keyup);

        return draw;
    }

    draw.off = function(selection) {
        context.uninstall(hover);

        selection
            .on('mousedown.draw', null)
            .on('mouseup.draw', null)
            .on('mousemove.draw', null)
            .on('click.draw', null);

        d3.select(document)
            .call(keybinding.off)
            .on('keydown.draw', null)
            .on('keyup.draw', null);
    };

    return d3.rebind(draw, event, 'on');
};
<commit_msg>Fix dragging cursor off of edge while drawing<commit_after>iD.behavior.Draw = function(context) {
    var event = d3.dispatch('move', 'click', 'clickWay', 'clickNode', 'clickMidpoint', 'undo', 'cancel', 'finish'),
        keybinding = d3.keybinding('draw'),
        hover = iD.behavior.Hover();

    function datum() {
        if (d3.event.altKey) {
            return {};
        } else {
            return d3.event.target.__data__ || {};
        }
    }

    function mousedown() {
        var selection = d3.select(this);
        selection.on('mousemove.draw', null);

        d3.select(window)
            .on('mouseup.draw', function() {
            selection.on('mousemove.draw', mousemove);
        });
    }

    function mousemove() {
        event.move(datum());
    }

    function click() {
        var d = datum();
        if (d.type === 'way') {
            var choice = iD.geo.chooseIndex(d, d3.mouse(context.surface().node()), context);
            event.clickWay(d, choice.loc, choice.index);

        } else if (d.type === 'node') {
            event.clickNode(d);

        } else if (d.type === 'midpoint') {
            event.clickMidpoint(d);

        } else {
            event.click(context.map().mouseCoordinates());
        }
    }

    function keydown() {
        if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
            context.uninstall(hover);
        }
    }

    function keyup() {
        if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
            context.install(hover);
        }
    }

    function backspace() {
        d3.event.preventDefault();
        event.undo();
    }

    function del() {
        d3.event.preventDefault();
        event.cancel();
    }

    function ret() {
        d3.event.preventDefault();
        event.finish();
    }

    function draw(selection) {
        context.install(hover);

        keybinding
            .on('⌫', backspace)
            .on('⌦', del)
            .on('⎋', ret)
            .on('↩', ret);

        selection
            .on('mousedown.draw', mousedown)
            .on('mousemove.draw', mousemove)
            .on('click.draw', click);

        d3.select(document)
            .call(keybinding)
            .on('keydown.draw', keydown)
            .on('keyup.draw', keyup);

        return draw;
    }

    draw.off = function(selection) {
        context.uninstall(hover);

        selection
            .on('mousedown.draw', null)
            .on('mousemove.draw', null)
            .on('click.draw', null);

        d3.select(document)
            .call(keybinding.off)
            .on('keydown.draw', null)
            .on('keyup.draw', null);
    };

    return d3.rebind(draw, event, 'on');
};
<|endoftext|>