<commit_before><<<<<<< HEAD
var barraProgreso = document.getElementById('progress'),
	barraVacia = document.getElementById('inactiveProgress'),
	barraText = document.getElementsByTagName('progress-helper'),
	progreso = document.getElementById('progressController'),
	barraVaciaContext = barraVacia.getContext("2d");

$(document).ready(function() {

//cambio de click para hacer reveal card//
   	$(document).on('click', '.agregar-marca', function(e) {

   		     $(this).parent().find('.card-panel').css('overflow', 'hidden');

   		    $(this).parent().find('.card-reveal').css({ display: 'block'}).velocity("stop", false).velocity({translateY: '-100%'}, {duration: 300, queue: false, easing: 'easeInOutQuad'});

   	});

/*Pintamos la barra de progeso*/
	var barraVaciaContext = barraVacia.getContext("2d"),
		porcentaje = $(progreso).val() / 100;

	//cambios en el input range para pintar
	$(progreso).on('change', function(){
		var porcentaje = $(this).val() / 100;
		console.log(porcentaje + '%');
		pintarProg(barraProgreso, porcentaje, barraText);
	});

	barraSinProg(barraVaciaContext);

	function barraSinProg (barraVaciaContext) {
		barraVaciaContext.beginPath(),
		barraVaciaContext.lineWidth = 5,
		barraVaciaContext.strokeStyle = '#fff',
		barraVaciaContext.arc(60, 60, 55, 0, 2*Math.PI),
		barraVaciaContext.stroke();

	};

	function pintarProg(bar, porcentaje, barraText){
		var barCTX = bar.getContext("2d");
		var quarterTurn = Math.PI / 2;
		var endingAngle = ((2*porcentaje) * Math.PI) - quarterTurn;
		var startingAngle = 0 - quarterTurn;

		bar.width = bar.width;
		barCTX.lineCap = 'square';

		barCTX.beginPath();
		barCTX.lineWidth = 5;
		barCTX.strokeStyle = '#448ccb';
		barCTX.arc(60, 60, 55,startingAngle, endingAngle);
		barCTX.stroke();

		$(barraText).text( (parseInt(porcentaje * 100, 10)) + '%');
	}

		pintarProg(barraProgreso, porcentaje, barraText);

});

=======
var marcas = "";
$(function() {
    var $write = $('#search'),
        shift = false,
        capslock = false;

    $('#keyboard li').click(function() {
        //  alert("click")
        var $this = $(this),
            character = $this.html(); // If it's a lowercase letter, nothing happens to this variable
        // alert(character);
        // Shift keys
        if ($this.hasClass('left-shift') || $this.hasClass('right-shift')) {
            $('.letter').toggleClass('uppercase');
            $('.symbol span').toggle();

            shift = (shift === true) ? false : true;
            capslock = false;
            return false;
        }

        // Caps lock
        if ($this.hasClass('capslock')) {
            $('.letter').toggleClass('uppercase');
            capslock = true;
            return false;
        }

        // Delete
        if ($this.hasClass('delete')) {
            var html = $write.val();

            $write.val(html.substr(0, html.length - 1));
            searchBrand($write.val());
            return false;
        }

        // Special characters
        if ($this.hasClass('symbol')) character = $('span:visible', $this).html();
        if ($this.hasClass('space')) character = ' ';
        if ($this.hasClass('tab')) character = "\t";
        if ($this.hasClass('return')) character = "\n";

        // Uppercase letter
        if ($this.hasClass('uppercase')) character = character.toUpperCase();

        // Remove shift once a key is clicked.
        if (shift === true) {
            $('.symbol span').toggle();
            if (capslock === false) $('.letter').toggleClass('uppercase');

            shift = false;
        }

        // Add the character
        $write.val($write.val() + character);
        searchBrand($write.val());
    });
});

function animate(div, x) {
    $('#' + div).show().removeClass().addClass(x + ' animated').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
        $(this).removeClass();
    });
};

function searchBrand(term) {
    var n = term.length;
    var $resultCont=$('.resultados-marcas');
    if (n >= 3) {
        $resultCont.html('');
        $.each(marcas, function(i, v) {
            //console.log(v)
            var re = new RegExp(term.toLowerCase());
            var name = v.name.toLowerCase();
            if (name.search(re) != -1) {
                // alert(v.picture);
                $resultCont.append('

' + v.name + '
');
                return;
            }
        });
    }else{
        $resultCont.html('');
    }
}
/// funciones cuando el documento este listo
$(document).ready(function() {
    $.ajax({
        url: 'buscar.php',
        dataType: 'json',
        success: function(data) {
            marcas = data;
        },
        type: 'GET'
    });

    $('#search').focusin(function() {
        animate("keyboard_parent", "bounceIn");
    }).focusout(function() {

    });
});
>>>>>>> d5df7147a5cc0e202dd1f4e11691920193081113
<commit_msg>fix merge conflict<commit_after>var barraProgreso = document.getElementById('progress'),
	barraVacia = document.getElementById('inactiveProgress'),
	barraText = document.getElementsByTagName('progress-helper'),
	progreso = document.getElementById('progressController'),
	barraVaciaContext = barraVacia.getContext("2d");

$(document).ready(function() {

//cambio de click para hacer reveal card//
   	$(document).on('click', '.agregar-marca', function(e) {

   		     $(this).parent().find('.card-panel').css('overflow', 'hidden');

   		    $(this).parent().find('.card-reveal').css({ display: 'block'}).velocity("stop", false).velocity({translateY: '-100%'}, {duration: 300, queue: false, easing: 'easeInOutQuad'});

   	});

/*Pintamos la barra de progeso*/
	var barraVaciaContext = barraVacia.getContext("2d"),
		porcentaje = $(progreso).val() / 100;

	//cambios en el input range para pintar
	$(progreso).on('change', function(){
		var porcentaje = $(this).val() / 100;
		console.log(porcentaje + '%');
		pintarProg(barraProgreso, porcentaje, barraText);
	});

	barraSinProg(barraVaciaContext);

	function barraSinProg (barraVaciaContext) {
		barraVaciaContext.beginPath(),
		barraVaciaContext.lineWidth = 5,
		barraVaciaContext.strokeStyle = '#fff',
		barraVaciaContext.arc(60, 60, 55, 0, 2*Math.PI),
		barraVaciaContext.stroke();

	};

	function pintarProg(bar, porcentaje, barraText){
		var barCTX = bar.getContext("2d");
		var quarterTurn = Math.PI / 2;
		var endingAngle = ((2*porcentaje) * Math.PI) - quarterTurn;
		var startingAngle = 0 - quarterTurn;

		bar.width = bar.width;
		barCTX.lineCap = 'square';

		barCTX.beginPath();
		barCTX.lineWidth = 5;
		barCTX.strokeStyle = '#448ccb';
		barCTX.arc(60, 60, 55,startingAngle, endingAngle);
		barCTX.stroke();

		$(barraText).text( (parseInt(porcentaje * 100, 10)) + '%');
	}

		pintarProg(barraProgreso, porcentaje, barraText);

});

var marcas = "";
$(function() {
    var $write = $('#search'),
        shift = false,
        capslock = false;

    $('#keyboard li').click(function() {
        //  alert("click")
        var $this = $(this),
            character = $this.html(); // If it's a lowercase letter, nothing happens to this variable
        // alert(character);
        // Shift keys
        if ($this.hasClass('left-shift') || $this.hasClass('right-shift')) {
            $('.letter').toggleClass('uppercase');
            $('.symbol span').toggle();

            shift = (shift === true) ? false : true;
            capslock = false;
            return false;
        }

        // Caps lock
        if ($this.hasClass('capslock')) {
            $('.letter').toggleClass('uppercase');
            capslock = true;
            return false;
        }

        // Delete
        if ($this.hasClass('delete')) {
            var html = $write.val();

            $write.val(html.substr(0, html.length - 1));
            searchBrand($write.val());
            return false;
        }

        // Special characters
        if ($this.hasClass('symbol')) character = $('span:visible', $this).html();
        if ($this.hasClass('space')) character = ' ';
        if ($this.hasClass('tab')) character = "\t";
        if ($this.hasClass('return')) character = "\n";

        // Uppercase letter
        if ($this.hasClass('uppercase')) character = character.toUpperCase();

        // Remove shift once a key is clicked.
        if (shift === true) {
            $('.symbol span').toggle();
            if (capslock === false) $('.letter').toggleClass('uppercase');

            shift = false;
        }

        // Add the character
        $write.val($write.val() + character);
        searchBrand($write.val());
    });
});

function animate(div, x) {
    $('#' + div).show().removeClass().addClass(x + ' animated').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
        $(this).removeClass();
    });
};

function searchBrand(term) {
    var n = term.length;
    var $resultCont=$('.resultados-marcas');
    if (n >= 3) {
        $resultCont.html('');
        $.each(marcas, function(i, v) {
            //console.log(v)
            var re = new RegExp(term.toLowerCase());
            var name = v.name.toLowerCase();
            if (name.search(re) != -1) {
                // alert(v.picture);
                $resultCont.append('

' + v.name + '
');
                return;
            }
        });
    }else{
        $resultCont.html('');
    }
}
/// funciones cuando el documento este listo
$(document).ready(function() {
    $.ajax({
        url: 'buscar.php',
        dataType: 'json',
        success: function(data) {
            marcas = data;
        },
        type: 'GET'
    });

    $('#search').focusin(function() {
        animate("keyboard_parent", "bounceIn");
    }).focusout(function() {

    });
});

<|endoftext|>


<commit_before>var News = {
  newsMinLimit: 1,
  newsMaxLimit: 15,
  backupImage: 'img/logo-sponsor-placeholder.png',
  msgNewsLimit: 'Nyhetsantall må være et tall mellom '+this.newsMinLimit+' og '+this.newsMaxLimit,
  msgConnectionError: 'Frakoblet fra feed: ',
  msgUnsupportedFeed: 'Feeden støttes ikke',
  msgCallbackRequired: 'Callback er påkrevd, legg resultatene inn i DOMen',

  debug: 1,

  feeds: {
    // Linjeforeninger
    'berg': 'http://bergstud.no/feed/',
    'delta': 'http://org.ntnu.no/delta/wp/?feed=rss2',
    'emil': 'http://emilweb.no/feed/',
    'online': 'https://online.ntnu.no/feeds/news/',
    'nabla': 'http://nabla.no/feed/',
    'spanskrøret': 'http://spanskroret.no/feed/',
    // Medier
    'dusken': 'http://dusken.no/feed/',
    'universitetsavisa': 'http://www.universitetsavisa.no/?service=rss',
    // Store studentorganisasjoner
    'samfundet': 'http://www.samfundet.no/arrangement/rss',
    // Studentdemokrati
    'studenttinget': 'http://www.studenttinget.no/feed/',
    'velferdstinget': 'http://www.velferdstinget.no/feed/rss/',
    // NTNU
    'ntnu': 'https://www.retriever-info.com/feed/2002900/generell_arkiv166/index.xml',
    'rektoratet': 'http://www.ntnu.no/blogger/rektoratet/feed/',
  },

  // Get is called by background.html periodically, with News.unreadCount as
  // callback. Fetchfeed is also called by popup.html when requested, but
  // without the callback as we already know the amount of unread posts.
  get: function(feedName, limit, callback) {
    if (this.feeds[feedName] === undefined) {
      if (this.debug) console.log('ERROR:', this.msgUnsupportedFeed);
      callback(this.msgUnsupportedFeed);
      return;
    }
    if (isNaN(limit) || (limit < 1 && 20 < limit)) {
      if (this.debug) console.log('ERROR:', this.msgNewsLimit);
      callback(this.msgNewsLimit);
      return;
    }
    if (callback == undefined) {
      console.log('ERROR:', this.msgCallbackRequired);
      callback(this.msgCallbackRequired);
      return;
    }

    feedName = feedName.toLowerCase();
    var rssUrl = this.feeds[feedName];

    var self = this;
    $.ajax({
      url: rssUrl, // permission to use url granted in manifest.json
      dataType: 'xml',
      success: function(xml) {
        // ls.lastResponseData = xmlstring;
        self.parseFeed(xml, feedName, limit, callback);
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR:', self.msgConnectionError, feedName);
        callback(self.msgConnectionError);
      },
    });
  },

  parseFeed: function(xml, feedName, limit, callback) {
    var items = [];
    var self = this;
    var count = 0;
    $(xml).find('item').each( function() {
      if (count++ < limit) {
        var item = self.parseItem(this, feedName);
        items.push(item);
      }
    });
    callback(items);
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  parseItem: function(item, feedName) {
    var post = {};
    post.title = $(item).find("title").text();
    post.link = $(item).find("link").text();
    post.description = $(item).find("description").text();
    post.creator = $(item).find("dc:creator").text();

    post.date = $(item).find("pubDate").text().substr(5, 11); /////////////////////
    post.image = this.backupImage; ////////////////////////////////////////////////

    // Check for alternative links in description
    post.altLink = this.checkForAltLink(post.description);

    // Shorten 'bedriftspresentasjon' to 'bedpres'
    post.title = post.title.replace(/edrift(s)?presentasjon/gi, 'edpres');
    post.description = post.description.replace(/edrift(s)?presentasjon/gi, 'edpres');

    // Remove excessive whitespace...
    if (post.description.match(/<\w+>|<\/\w+>/g) !== null) { // Check if string contains markup
      // ...and ludicrous formatting (HTML)
      post.description = $.trim($(post.description).text());
    }
    else {
      post.description = post.description.trim();
    }

    // In case browser does not grok tags with colons, stupid browser
    if (post.creator == '') {
      var tag = ("dc\\:creator").replace( /.*(\:)(.*)/, "$2" );
      $(item).find(tag).each(function(){
        post.creator = $(this).text().trim();
      });
    }
    // Didn't find a creator, set the feedname as creator
    if (post.creator.length == 0) {
      post.creator = feedName.capitalize();
    }
    // Abbreviate long creator names
    post.creator = this.abbreviateName(post.creator);

    // title + description must not exceed 5 lines
    var line = 50; // conservative estimation
    var desclength = line * 3;
    // double line titles will shorten the description by 1 line
    if (line <= post.title.length)
      desclength -= line;
    // shorten description according to desclength
    if (desclength < post.description.length)
      post.description = post.description.substr(0, desclength) + '...';

    return post;
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  unreadCount: function(xmlstring) {

    return; //

    var unread_count = 0;

    // Parse the feed
    var xmldoc = $.parseXML(xmlstring);
    $xml = $(xmldoc);
    var items = $xml.find("item");
    var idList = []; // New || Updated

    // Count feed items
    items.each( function(index, element) {

      var id = $(element).find("guid").text().split('/')[4];

      // Counting...
      if (id != localStorage.mostRecentRead) {
        unread_count++;
        idList.push(id); // New || Updated
        // Send a desktop notification about the first unread element
        if (unread_count == 1) {
          if (localStorage.lastNotified != id) {
            this.showNotification(element);
          }
          localStorage.mostRecentUnread = id;
        }
      }
      // All counted :)
      else {
        if (unread_count == 0) {
          if (this.debug) console.log('no new posts');
          Browser.setBadgeText('');
        }
        else if (unread_count >= this.maxNewsAmount) {
          if (this.debug) console.log(this.maxNewsAmount + '+ unread posts');
          Browser.setBadgeText(this.maxNewsAmount + '+');
        }
        else {
          if (this.debug) console.log('1-' + (this.maxNewsAmount - 1) + ' unread posts');
          Browser.setBadgeText(String(unread_count));
        }
        localStorage.unreadCount = unread_count;
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }

      // Stop counting if unread number is greater than 9
      if (index > (this.maxNewsAmount - 1)) { // Remember index is counting 0
        if (this.debug) console.log(this.maxNewsAmount + '+ unread posts (stopped counting)');
        Browser.setBadgeText(this.maxNewsAmount + '+');
        localStorage.unreadCount = this.maxNewsAmount;
        // New or updated?
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }
    });
  },

  showNotification: function(item) {
    if (localStorage.showNotifications == 'true') {
      var post = this.parseItem(item);
      // Remember this
      localStorage.lastNotified = post.link;
      // Get content
      localStorage.notificationTitle = post.title;
      localStorage.notificationLink = post.link;
      localStorage.notificationDescription = post.description;
      localStorage.notificationCreator = post.creator;
      // Show desktop notification
      Browser.createNotification('notification.html');
    }
  },

  checkForAltLink: function(description) {
    // Looking for alternative link, find the first and best full link
    var altLink = description.match(/href="(http.*)"/);
    if (altLink != null) {
      if (typeof altLink[1] == 'string') {
        return altLink[1];
      }
    }
    return null;
  },

  abbreviateName: function(oldName) {
    if (oldName != undefined) {
      // Abbreviate middle names if name is long
      if (18 < oldName.length) {
        var pieces = oldName.split(' ');
        if (2 < pieces.length) {
          // Add first name
          var newName = pieces[0];
          // Add one letter per middle name
          for (var i = 1; i < pieces.length - 1; i++)
            newName += ' ' + pieces[i].charAt(0).toUpperCase() + '.';
          // Add last name
          newName += ' ' + pieces[pieces.length-1];
          return newName;
        }
      }
    }
    else {
      if (this.debug) console.log('ERROR: cannot abbreviate an undefined name');
    }
    return oldName;
  },

  // Organization specific functions

  online_getImage: function(link, callback) {
    var id = link.split('/')[4]; // id is stored in the link
    var image = 'undefined';
    var api = 'https://online.ntnu.no/api/f5be90e5ec1d2d454ae9/news_image_by_id/';
    $.getJSON(api + id, function(json) {
      if (json['online_news_image']) {
        image = json['online_news_image']['0']['image'];
        callback(link, image);
      }
      else {
        image = this.backupImage;
        if (this.debug) console.log('ERROR: no image exists for id: ' + id);
        callback(link, image);
      }
    })
    .error(function() {
      image = this.backupImage;
      if (this.debug) console.log('ERROR: couldn\'t connect API to get image links, returning default image');
      callback(link, image);
    });
  },

}

/*
felles:
    feeds
    get
    parseFeed
    parseItem
    showNotification
    unreadCount
    fletting

hver for seg:
    // last read
    keep list of recent posts
    get post image
*/

<commit_msg>news: new system for backup images, one for each organzation<commit_after>var News = {
  newsMinLimit: 1,
  newsMaxLimit: 15,
  msgNewsLimit: 'Nyhetsantall må være et tall mellom '+this.newsMinLimit+' og '+this.newsMaxLimit,
  msgConnectionError: 'Frakoblet fra feed: ',
  msgUnsupportedFeed: 'Feeden støttes ikke',
  msgCallbackRequired: 'Callback er påkrevd, legg resultatene inn i DOMen',

  debug: 1,

  feeds: {
    // Linjeforeninger
    'berg': 'http://bergstud.no/feed/',
    'delta': 'http://org.ntnu.no/delta/wp/?feed=rss2',
    'emil': 'http://emilweb.no/feed/',
    'online': 'https://online.ntnu.no/feeds/news/',
    'nabla': 'http://nabla.no/feed/',
    'spanskrøret': 'http://spanskroret.no/feed/',
    // Medier
    'dusken': 'http://dusken.no/feed/',
    'universitetsavisa': 'http://www.universitetsavisa.no/?service=rss',
    // Store studentorganisasjoner
    'samfundet': 'http://www.samfundet.no/arrangement/rss',
    // Studentdemokrati
    'studenttinget': 'http://www.studenttinget.no/feed/',
    'velferdstinget': 'http://www.velferdstinget.no/feed/rss/',
    // NTNU
    'ntnu': 'https://www.retriever-info.com/feed/2002900/generell_arkiv166/index.xml',
    'rektoratet': 'http://www.ntnu.no/blogger/rektoratet/feed/',
  },

  images: {
    // Linjeforeninger
    'berg': 'img/logo-sponsor-placeholder.png',
    'delta': 'img/logo-sponsor-placeholder.png',
    'emil': 'img/logo-sponsor-placeholder.png',
    'online': 'img/logo-sponsor-placeholder.png',
    'nabla': 'img/logo-sponsor-placeholder.png',
    'spanskrøret': 'img/logo-sponsor-placeholder.png',
    // Medier
    'dusken': 'img/logo-sponsor-placeholder.png',
    'universitetsavisa': 'img/logo-sponsor-placeholder.png',
    // Store studentorganisasjoner
    'samfundet': 'img/logo-sponsor-placeholder.png',
    // Studentdemokrati
    'studenttinget': 'img/logo-sponsor-placeholder.png',
    'velferdstinget': 'img/logo-sponsor-placeholder.png',
    // NTNU
    'ntnu': 'img/logo-sponsor-placeholder.png',
    'rektoratet': 'img/logo-sponsor-placeholder.png',
  }

  // Get is called by background.html periodically, with News.unreadCount as
  // callback. Fetchfeed is also called by popup.html when requested, but
  // without the callback as we already know the amount of unread posts.
  get: function(feedName, limit, callback) {
    if (this.feeds[feedName] === undefined) {
      if (this.debug) console.log('ERROR:', this.msgUnsupportedFeed);
      callback(this.msgUnsupportedFeed);
      return;
    }
    if (isNaN(limit) || (limit < 1 && 20 < limit)) {
      if (this.debug) console.log('ERROR:', this.msgNewsLimit);
      callback(this.msgNewsLimit);
      return;
    }
    if (callback == undefined) {
      console.log('ERROR:', this.msgCallbackRequired);
      callback(this.msgCallbackRequired);
      return;
    }

    feedName = feedName.toLowerCase();
    var rssUrl = this.feeds[feedName];

    var self = this;
    $.ajax({
      url: rssUrl, // permission to use url granted in manifest.json
      dataType: 'xml',
      success: function(xml) {
        // ls.lastResponseData = xmlstring;
        self.parseFeed(xml, feedName, limit, callback);
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR:', self.msgConnectionError, feedName);
        callback(self.msgConnectionError);
      },
    });
  },

  parseFeed: function(xml, feedName, limit, callback) {
    var items = [];
    var self = this;
    var count = 0;
    $(xml).find('item').each( function() {
      if (count++ < limit) {
        var item = self.parseItem(this, feedName);
        items.push(item);
      }
    });
    callback(items);
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  parseItem: function(item, feedName) {
    var post = {};
    post.title = $(item).find("title").text();
    post.link = $(item).find("link").text();
    post.description = $(item).find("description").text();
    post.creator = $(item).find("dc:creator").text();

    post.date = $(item).find("pubDate").text().substr(5, 11); /////////////////////
    post.image = this.images[feedName];

    // Check for alternative links in description
    post.altLink = this.checkForAltLink(post.description);

    // Shorten 'bedriftspresentasjon' to 'bedpres'
    post.title = post.title.replace(/edrift(s)?presentasjon/gi, 'edpres');
    post.description = post.description.replace(/edrift(s)?presentasjon/gi, 'edpres');

    // Remove excessive whitespace...
    if (post.description.match(/<\w+>|<\/\w+>/g) !== null) { // Check if string contains markup
      // ...and ludicrous formatting (HTML)
      post.description = $.trim($(post.description).text());
    }
    else {
      post.description = post.description.trim();
    }

    // In case browser does not grok tags with colons, stupid browser
    if (post.creator == '') {
      var tag = ("dc\\:creator").replace( /.*(\:)(.*)/, "$2" );
      $(item).find(tag).each(function(){
        post.creator = $(this).text().trim();
      });
    }
    // Didn't find a creator, set the feedname as creator
    if (post.creator.length == 0) {
      post.creator = feedName.capitalize();
    }
    // Abbreviate long creator names
    post.creator = this.abbreviateName(post.creator);

    // title + description must not exceed 5 lines
    var line = 50; // conservative estimation
    var desclength = line * 3;
    // double line titles will shorten the description by 1 line
    if (line <= post.title.length)
      desclength -= line;
    // shorten description according to desclength
    if (desclength < post.description.length)
      post.description = post.description.substr(0, desclength) + '...';

    return post;
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  unreadCount: function(xmlstring) {

    return; //

    var unread_count = 0;

    // Parse the feed
    var xmldoc = $.parseXML(xmlstring);
    $xml = $(xmldoc);
    var items = $xml.find("item");
    var idList = []; // New || Updated

    // Count feed items
    items.each( function(index, element) {

      var id = $(element).find("guid").text().split('/')[4];

      // Counting...
      if (id != localStorage.mostRecentRead) {
        unread_count++;
        idList.push(id); // New || Updated
        // Send a desktop notification about the first unread element
        if (unread_count == 1) {
          if (localStorage.lastNotified != id) {
            this.showNotification(element);
          }
          localStorage.mostRecentUnread = id;
        }
      }
      // All counted :)
      else {
        if (unread_count == 0) {
          if (this.debug) console.log('no new posts');
          Browser.setBadgeText('');
        }
        else if (unread_count >= this.maxNewsAmount) {
          if (this.debug) console.log(this.maxNewsAmount + '+ unread posts');
          Browser.setBadgeText(this.maxNewsAmount + '+');
        }
        else {
          if (this.debug) console.log('1-' + (this.maxNewsAmount - 1) + ' unread posts');
          Browser.setBadgeText(String(unread_count));
        }
        localStorage.unreadCount = unread_count;
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }

      // Stop counting if unread number is greater than 9
      if (index > (this.maxNewsAmount - 1)) { // Remember index is counting 0
        if (this.debug) console.log(this.maxNewsAmount + '+ unread posts (stopped counting)');
        Browser.setBadgeText(this.maxNewsAmount + '+');
        localStorage.unreadCount = this.maxNewsAmount;
        // New or updated?
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }
    });
  },

  showNotification: function(item) {
    if (localStorage.showNotifications == 'true') {
      var post = this.parseItem(item);
      // Remember this
      localStorage.lastNotified = post.link;
      // Get content
      localStorage.notificationTitle = post.title;
      localStorage.notificationLink = post.link;
      localStorage.notificationDescription = post.description;
      localStorage.notificationCreator = post.creator;
      // Show desktop notification
      Browser.createNotification('notification.html');
    }
  },

  checkForAltLink: function(description) {
    // Looking for alternative link, find the first and best full link
    var altLink = description.match(/href="(http.*)"/);
    if (altLink != null) {
      if (typeof altLink[1] == 'string') {
        return altLink[1];
      }
    }
    return null;
  },

  abbreviateName: function(oldName) {
    if (oldName != undefined) {
      // Abbreviate middle names if name is long
      if (18 < oldName.length) {
        var pieces = oldName.split(' ');
        if (2 < pieces.length) {
          // Add first name
          var newName = pieces[0];
          // Add one letter per middle name
          for (var i = 1; i < pieces.length - 1; i++)
            newName += ' ' + pieces[i].charAt(0).toUpperCase() + '.';
          // Add last name
          newName += ' ' + pieces[pieces.length-1];
          return newName;
        }
      }
    }
    else {
      if (this.debug) console.log('ERROR: cannot abbreviate an undefined name');
    }
    return oldName;
  },

  // Organization specific functions

  online_getImage: function(link, callback) {
    var id = link.split('/')[4]; // id is stored in the link
    var image = 'undefined';
    var api = 'https://online.ntnu.no/api/f5be90e5ec1d2d454ae9/news_image_by_id/';
    $.getJSON(api + id, function(json) {
      if (json['online_news_image']) {
        image = json['online_news_image']['0']['image'];
        callback(link, image);
      }
      else {
        image = this.images['online'];
        if (this.debug) console.log('ERROR: no image exists for id: ' + id);
        callback(link, image);
      }
    })
    .error(function() {
      image = this.images['online'];
      if (this.debug) console.log('ERROR: couldn\'t connect API to get image links, returning default image');
      callback(link, image);
    });
  },

}

/*
felles:
    feeds
    get
    parseFeed
    parseItem
    showNotification
    unreadCount
    fletting

hver for seg:
    // last read
    keep list of recent posts
    get post image
*/

<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class nova extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'nova',
            'name': 'Novaexchange',
            'countries': [ 'TZ' ], // Tanzania
            'rateLimit': 2000,
            'version': 'v2',
            'has': {
                'CORS': false,
                'createMarketOrder': false,
                'createDepositAddress': true,
                'fetchDepositAddress': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30518571-78ca0bca-9b8a-11e7-8840-64b83a4a94b2.jpg',
                'api': 'https://novaexchange.com/remote',
                'www': 'https://novaexchange.com',
                'doc': 'https://novaexchange.com/remote/faq',
            },
            'api': {
                'public': {
                    'get': [
                        'markets/',
                        'markets/{basecurrency}/',
                        'market/info/{pair}/',
                        'market/orderhistory/{pair}/',
                        'market/openorders/{pair}/buy/',
                        'market/openorders/{pair}/sell/',
                        'market/openorders/{pair}/both/',
                        'market/openorders/{pair}/{ordertype}/',
                    ],
                },
                'private': {
                    'post': [
                        'getbalances/',
                        'getbalance/{currency}/',
                        'getdeposits/',
                        'getwithdrawals/',
                        'getnewdepositaddress/{currency}/',
                        'getdepositaddress/{currency}/',
                        'myopenorders/',
                        'myopenorders_market/{pair}/',
                        'cancelorder/{orderid}/',
                        'withdraw/{currency}/',
                        'trade/{pair}/',
                        'tradehistory/',
                        'getdeposithistory/',
                        'getwithdrawalhistory/',
                        'walletstatus/',
                        'walletstatus/{currency}/',
                    ],
                },
            },
        });
    }

    async fetchMarkets (params = {}) {
        let response = await this.publicGetMarkets ();
        let markets = response['markets'];
        let result = [];
        for (let i = 0; i < markets.length; i++) {
            let market = markets[i];
            let id = market['marketname'];
            let [ quote, base ] = id.split ('_');
            let symbol = base + '/' + quote;
            let active = true;
            if (market['disabled'])
                active = false;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': active,
                'info': market,
            });
        }
        return result;
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetMarketOpenordersPairBoth (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'buyorders', 'sellorders', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetMarketInfoPair (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        let ticker = response['markets'][0];
        let timestamp = this.milliseconds ();
        let last = this.safeFloat (ticker, 'last_price');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high24h'),
            'low': this.safeFloat (ticker, 'low24h'),
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': this.safeFloat (ticker, 'change24h'),
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'volume24h'),
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        let timestamp = trade['unix_t_datestamp'] * 1000;
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'id': undefined,
            'order': undefined,
            'type': undefined,
            'side': trade['tradetype'].toLowerCase (),
            'price': this.safeFloat (trade, 'price'),
            'amount': this.safeFloat (trade, 'amount'),
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketOrderhistoryPair (this.extend ({
            'pair': market['id'],
        }, params));
        return this.parseTrades (response['items'], market, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostGetbalances ();
        let balances = response['balances'];
        let result = { 'info': response };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let lockbox = parseFloat (balance['amount_lockbox']);
            let trades = parseFloat (balance['amount_trades']);
            let account = {
                'free': parseFloat (balance['amount']),
                'used': this.sum (lockbox, trades),
                'total': parseFloat (balance['amount_total']),
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        if (type === 'market')
            throw new ExchangeError (this.id + ' allows limit orders only');
        await this.loadMarkets ();
        amount = amount.toString ();
        price = price.toString ();
        let market = this.market (symbol);
        let order = {
            'tradetype': side.toUpperCase (),
            'tradeamount': amount,
            'tradeprice': price,
            'tradebase': 1,
            'pair': market['id'],
        };
        let response = await this.privatePostTradePair (this.extend (order, params));
        let orderid = undefined;
        const tradeitems = this.safeValue (response, 'tradeitems');
        if (tradeitems !== undefined) {
            for (let i = 0; i < tradeitems.length; i++) {
                if (this.safeString (tradeitems[i], 'type') === 'created') {
                    orderid = this.safeString (tradeitems[i], 'orderid');
                }
            }
        }
        return {
            'info': response,
            'id': orderid,
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        return await this.privatePostCancelorder (this.extend ({
            'orderid': id,
        }, params));
    }

    async createDepositAddress (code, params = {}) {
        await this.loadMarkets ();
        const currency = this.currency (code);
        let response = await this.privatePostGetnewdepositaddressCurrency (this.extend ({
            'currency': currency,
        }, params));
        const address = this.safeString (response, 'address');
        this.checkAddress (address);
        const tag = this.safeString (response, 'tag');
        return {
            'currency': code,
            'address': address,
            'tag': tag,
            'info': response,
        };
    }

    async fetchDepositAddress (code, params = {}) {
        await this.loadMarkets ();
        const currency = this.currency (code);
        let response = await this.privatePostGetdepositaddressCurrency (this.extend ({
            'currency': currency,
        }, params));
        const address = this.safeString (response, 'address');
        this.checkAddress (address);
        const tag = this.safeString (response, 'tag');
        return {
            'currency': code,
            'address': address,
            'tag': tag,
            'info': response,
        };
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/';
        if (api === 'private')
            url += api + '/';
        url += this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            url += '?' + this.urlencode ({ 'nonce': nonce });
            let signature = this.hmac (this.encode (url), this.encode (this.secret), 'sha512', 'base64');
            body = this.urlencode (this.extend ({
                'apikey': this.apiKey,
                'signature': signature,
            }, query));
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('status' in response)
            if (response['status'] !== 'success')
                throw new ExchangeError (this.id + ' ' + this.json (response));
        return response;
    }
};
<commit_msg>nova createOrder response edits<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class nova extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'nova',
            'name': 'Novaexchange',
            'countries': [ 'TZ' ], // Tanzania
            'rateLimit': 2000,
            'version': 'v2',
            'has': {
                'CORS': false,
                'createMarketOrder': false,
                'createDepositAddress': true,
                'fetchDepositAddress': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30518571-78ca0bca-9b8a-11e7-8840-64b83a4a94b2.jpg',
                'api': 'https://novaexchange.com/remote',
                'www': 'https://novaexchange.com',
                'doc': 'https://novaexchange.com/remote/faq',
            },
            'api': {
                'public': {
                    'get': [
                        'markets/',
                        'markets/{basecurrency}/',
                        'market/info/{pair}/',
                        'market/orderhistory/{pair}/',
                        'market/openorders/{pair}/buy/',
                        'market/openorders/{pair}/sell/',
                        'market/openorders/{pair}/both/',
                        'market/openorders/{pair}/{ordertype}/',
                    ],
                },
                'private': {
                    'post': [
                        'getbalances/',
                        'getbalance/{currency}/',
                        'getdeposits/',
                        'getwithdrawals/',
                        'getnewdepositaddress/{currency}/',
                        'getdepositaddress/{currency}/',
                        'myopenorders/',
                        'myopenorders_market/{pair}/',
                        'cancelorder/{orderid}/',
                        'withdraw/{currency}/',
                        'trade/{pair}/',
                        'tradehistory/',
                        'getdeposithistory/',
                        'getwithdrawalhistory/',
                        'walletstatus/',
                        'walletstatus/{currency}/',
                    ],
                },
            },
        });
    }

    async fetchMarkets (params = {}) {
        let response = await this.publicGetMarkets ();
        let markets = response['markets'];
        let result = [];
        for (let i = 0; i < markets.length; i++) {
            let market = markets[i];
            let id = market['marketname'];
            let [ quote, base ] = id.split ('_');
            let symbol = base + '/' + quote;
            let active = true;
            if (market['disabled'])
                active = false;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': active,
                'info': market,
            });
        }
        return result;
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetMarketOpenordersPairBoth (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'buyorders', 'sellorders', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetMarketInfoPair (this.extend ({
            'pair': this.marketId (symbol),
        }, params));
        let ticker = response['markets'][0];
        let timestamp = this.milliseconds ();
        let last = this.safeFloat (ticker, 'last_price');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high24h'),
            'low': this.safeFloat (ticker, 'low24h'),
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': this.safeFloat (ticker, 'change24h'),
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'volume24h'),
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        let timestamp = trade['unix_t_datestamp'] * 1000;
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'id': undefined,
            'order': undefined,
            'type': undefined,
            'side': trade['tradetype'].toLowerCase (),
            'price': this.safeFloat (trade, 'price'),
            'amount': this.safeFloat (trade, 'amount'),
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketOrderhistoryPair (this.extend ({
            'pair': market['id'],
        }, params));
        return this.parseTrades (response['items'], market, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostGetbalances ();
        let balances = response['balances'];
        let result = { 'info': response };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let lockbox = parseFloat (balance['amount_lockbox']);
            let trades = parseFloat (balance['amount_trades']);
            let account = {
                'free': parseFloat (balance['amount']),
                'used': this.sum (lockbox, trades),
                'total': parseFloat (balance['amount_total']),
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        if (type === 'market')
            throw new ExchangeError (this.id + ' allows limit orders only');
        await this.loadMarkets ();
        amount = amount.toString ();
        price = price.toString ();
        const market = this.market (symbol);
        const order = {
            'tradetype': side.toUpperCase (),
            'tradeamount': amount,
            'tradeprice': price,
            'tradebase': 1,
            'pair': market['id'],
        };
        const response = await this.privatePostTradePair (this.extend (order, params));
        const tradeItems = this.safeValue (response, 'tradeitems', []);
        const tradeItemsByType = this.indexBy (tradeItems, 'type');
        const created = this.safeValue (tradeItemsByType, 'created', {});
        const orderId = this.safeString (created, 'orderid');
        return {
            'info': response,
            'id': orderId,
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        return await this.privatePostCancelorder (this.extend ({
            'orderid': id,
        }, params));
    }

    async createDepositAddress (code, params = {}) {
        await this.loadMarkets ();
        const currency = this.currency (code);
        let response = await this.privatePostGetnewdepositaddressCurrency (this.extend ({
            'currency': currency,
        }, params));
        const address = this.safeString (response, 'address');
        this.checkAddress (address);
        const tag = this.safeString (response, 'tag');
        return {
            'currency': code,
            'address': address,
            'tag': tag,
            'info': response,
        };
    }

    async fetchDepositAddress (code, params = {}) {
        await this.loadMarkets ();
        const currency = this.currency (code);
        let response = await this.privatePostGetdepositaddressCurrency (this.extend ({
            'currency': currency,
        }, params));
        const address = this.safeString (response, 'address');
        this.checkAddress (address);
        const tag = this.safeString (response, 'tag');
        return {
            'currency': code,
            'address': address,
            'tag': tag,
            'info': response,
        };
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/';
        if (api === 'private')
            url += api + '/';
        url += this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            url += '?' + this.urlencode ({ 'nonce': nonce });
            let signature = this.hmac (this.encode (url), this.encode (this.secret), 'sha512', 'base64');
            body = this.urlencode (this.extend ({
                'apikey': this.apiKey,
                'signature': signature,
            }, query));
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('status' in response)
            if (response['status'] !== 'success')
                throw new ExchangeError (this.id + ' ' + this.json (response));
        return response;
    }
};
<|endoftext|>


<commit_before>/*!
 * Copyright (c) 2015-2019 Cisco Systems, Inc. See LICENSE file.
 */

/* eslint-disable require-jsdoc */
const debug = require('debug')('tooling:test');
const dotenv = require('dotenv');

dotenv.config();
dotenv.config({path: '.env.default'});
process.env.NODE_ENV = process.env.NODE_ENV || 'test';

const {
  gatherFiles
} = require('./common');
const mochaTest = require('./mocha').test;
const karmaTest = require('./karma').test;

const path = require('path');

const {
  collect,
  combine,
  deinstrument,
  instrument
} = require('../../util/coverage');
const {glob} = require('../../util/package');

/* eslint-disable complexity */

exports.testPackage = async function testPackage(options, packageName) {
  // eslint-disable-next-line global-require
  require('babel-register')({
    only: [
      './packages/node_modules/**/*.js'
    ],
    plugins: [
      path.resolve(__dirname, '../../babel-plugin-inject-package-version')
    ],
    sourceMaps: true
  });

  const currentPackageString = `===== Testing ${packageName} =====`;

  console.info(`\n${'='.repeat(currentPackageString.length)}`);
  console.info(currentPackageString);
  console.info(`${'='.repeat(currentPackageString.length)}\n`);

  if (packageName === 'generator-ciscospark') {
    await runNodeSuite(packageName);

    return;
  }

  if (options.node) {
    if (options.coverage) {
      await instrument(packageName);
    }
    try {
      await runNodeSuite(options, packageName);
    }
    finally {
      if (options.coverage) {
        await deinstrument(packageName);
      }
    }
  }

  if (options.browser) {
    await runBrowserSuite(options, packageName);
  }

  if (options.automation) {
    await runAutomationSuite(options, packageName);
  }

  // Note: running docs test last because the babel transform interferes with
  // other test suites' test code. We should probably look at how to unload the
  // jsdoctrine transform once the doc tests complete.
  if (options.documentation) {
    await runDocsSuite(options, packageName);
  }

  if (options.coverage) {
    await collect(packageName);
    await combine(packageName);
  }
};

async function runDocsSuite(options, packageName) {
  debug(`Running documentation tests for ${packageName}`);
  const files = await glob('dist/**/*.js', {packageName});

  // eslint-disable-next-line global-require
  require(`${process.cwd()}/packages/node_modules/@webex/jsdoctrinetest`);
  await mochaTest(options, packageName, 'documentation', files.map((f) => `packages/node_modules/${packageName}/${f}`));
  debug(`Finished documentation suite for ${packageName}`);
}

async function runNodeSuite(options, packageName) {
  debug(`Running node suite for ${packageName}`);
  const files = await gatherFiles(options, packageName);

  if (files.length === 0) {
    debug(`no files found for ${packageName}`);

    return;
  }

  // Intercept require statements for the module under test and instead load the
  // instrumented files. This *should* continue to isolate code coverage since
  // we're running each package's test in a separate process, even when simply
  // running `npm test`.
  const load = require.extensions['.js'];

  if (options.coverage) {
    require.extensions['.js'] = function loadCoveredFile(m, filename) {
      if (filename.includes(packageName)) {
        filename = filename.replace(`${packageName}/dist`, `${packageName}/.coverage/src`);
      }

      return load(m, filename);
    };
  }

  await mochaTest(options, packageName, 'node', files);
  if (options.coverage) {
    require.extensions['.js'] = load;
  }

  debug(`Finished node suite for ${packageName}`);
}

async function runBrowserSuite(options, packageName) {
  debug(`Running browser suite for ${packageName}`);
  const files = await gatherFiles(options, packageName);

  if (files.length === 0) {
    debug(`no files found for ${packageName}`);

    return;
  }

  await karmaTest(options, packageName, files);

  debug(`Finished browser suite for ${packageName}`);
}

async function runAutomationSuite(options, packageName) {
  debug(`Running automation suite for ${packageName}`);
  const files = (await glob('test/automation/spec/**/*.js', {packageName}))
    .map((f) => `packages/node_modules/${packageName}/${f}`);

  if (files.length === 0) {
    debug(`no files found for ${packageName}`);

    return;
  }

  await mochaTest(options, packageName, 'automation', files);

  debug(`Finished automation suite for ${packageName}`);
}
<commit_msg>fix(tooling): stop yargs test command from setting NODE_ENV<commit_after>/*!
 * Copyright (c) 2015-2019 Cisco Systems, Inc. See LICENSE file.
 */

/* eslint-disable require-jsdoc */
const debug = require('debug')('tooling:test');
const dotenv = require('dotenv');

dotenv.config();
dotenv.config({path: '.env.default'});

const {
  gatherFiles
} = require('./common');
const mochaTest = require('./mocha').test;
const karmaTest = require('./karma').test;

const path = require('path');

const {
  collect,
  combine,
  deinstrument,
  instrument
} = require('../../util/coverage');
const {glob} = require('../../util/package');

/* eslint-disable complexity */

exports.testPackage = async function testPackage(options, packageName) {
  // Move NODE_ENV override into the exported function since babel-node is processing everything above
  process.env.NODE_ENV = process.env.NODE_ENV || 'test';

  // eslint-disable-next-line global-require
  require('babel-register')({
    only: [
      './packages/node_modules/**/*.js'
    ],
    plugins: [
      path.resolve(__dirname, '../../babel-plugin-inject-package-version')
    ],
    sourceMaps: true
  });

  const currentPackageString = `===== Testing ${packageName} =====`;

  console.info(`\n${'='.repeat(currentPackageString.length)}`);
  console.info(currentPackageString);
  console.info(`${'='.repeat(currentPackageString.length)}\n`);

  if (packageName === 'generator-ciscospark') {
    await runNodeSuite(packageName);

    return;
  }

  if (options.node) {
    if (options.coverage) {
      await instrument(packageName);
    }
    try {
      await runNodeSuite(options, packageName);
    }
    finally {
      if (options.coverage) {
        await deinstrument(packageName);
      }
    }
  }

  if (options.browser) {
    await runBrowserSuite(options, packageName);
  }

  if (options.automation) {
    await runAutomationSuite(options, packageName);
  }

  // Note: running docs test last because the babel transform interferes with
  // other test suites' test code. We should probably look at how to unload the
  // jsdoctrine transform once the doc tests complete.
  if (options.documentation) {
    await runDocsSuite(options, packageName);
  }

  if (options.coverage) {
    await collect(packageName);
    await combine(packageName);
  }
};

async function runDocsSuite(options, packageName) {
  debug(`Running documentation tests for ${packageName}`);
  const files = await glob('dist/**/*.js', {packageName});

  // eslint-disable-next-line global-require
  require(`${process.cwd()}/packages/node_modules/@webex/jsdoctrinetest`);
  await mochaTest(options, packageName, 'documentation', files.map((f) => `packages/node_modules/${packageName}/${f}`));
  debug(`Finished documentation suite for ${packageName}`);
}

async function runNodeSuite(options, packageName) {
  debug(`Running node suite for ${packageName}`);
  const files = await gatherFiles(options, packageName);

  if (files.length === 0) {
    debug(`no files found for ${packageName}`);

    return;
  }

  // Intercept require statements for the module under test and instead load the
  // instrumented files. This *should* continue to isolate code coverage since
  // we're running each package's test in a separate process, even when simply
  // running `npm test`.
  const load = require.extensions['.js'];

  if (options.coverage) {
    require.extensions['.js'] = function loadCoveredFile(m, filename) {
      if (filename.includes(packageName)) {
        filename = filename.replace(`${packageName}/dist`, `${packageName}/.coverage/src`);
      }

      return load(m, filename);
    };
  }

  await mochaTest(options, packageName, 'node', files);
  if (options.coverage) {
    require.extensions['.js'] = load;
  }

  debug(`Finished node suite for ${packageName}`);
}

async function runBrowserSuite(options, packageName) {
  debug(`Running browser suite for ${packageName}`);
  const files = await gatherFiles(options, packageName);

  if (files.length === 0) {
    debug(`no files found for ${packageName}`);

    return;
  }

  await karmaTest(options, packageName, files);

  debug(`Finished browser suite for ${packageName}`);
}

async function runAutomationSuite(options, packageName) {
  debug(`Running automation suite for ${packageName}`);
  const files = (await glob('test/automation/spec/**/*.js', {packageName}))
    .map((f) => `packages/node_modules/${packageName}/${f}`);

  if (files.length === 0) {
    debug(`no files found for ${packageName}`);

    return;
  }

  await mochaTest(options, packageName, 'automation', files);

  debug(`Finished automation suite for ${packageName}`);
}
<|endoftext|>


<commit_before>class PERT
{
    constructor()
    {
        this.config = new DataStore('pert');
        this.uiCache = {};
        this.currentProject = null;
        this.currentProjectName = null;

        this.initializeUi();

        // Load the last opened project
        const projects = [];
        for (const name of this.config.keys()) {
            const accessedAt = this.config.get(name).stats.accessedAt;
            projects.push({name, accessedAt});
        }
        projects.sort((a, b) => b.accessedAt - a.accessedAt);
        for (const project of projects) {
            this.loadProject(project.name);
            break;
        }
    }

    /**
     * @param {String} name
     * @returns {HTMLElement}
     */
    ui(name)
    {
        if (!(name in this.uiCache)) {
            this.uiCache[name] = document.getElementById(name);
        }
        return this.uiCache[name];
    }

    /**
     * @param {String} prefix
     * @param {DataStore} config
     */
    findFreeKey(prefix, config)
    {
        let key, i=0;
        do {
            key = prefix + (++i);
        } while (config.has(key));
        return key;
    }

    redrawProjectsSelector()
    {
        const select = this.ui('menu-contents-projects');
        select.innerHTML = '<option disabled selected>Load a project</option>';
        for (const project of this.config.keys()) {
            const option = document.createElement('option');
            option.innerText = project;
            option.value = project;
            select.appendChild(option);
        }
    }

    /**
     * @param {String} [action]
     * @param {Boolean} [returnMessage]
     * @returns {Boolean|String}
     */
    shouldStayOnPage(action, returnMessage)
    {
        let message = 'The current project has unsaved changes which will be lost if you continue.';
        if (typeof action === 'string') {
            message += ` ${action}`;
        }
        if (this.config.changed()) {
            return returnMessage ? message : !confirm(message);
        }
        return false;
    }

    /**
     * @param {String} name
     */
    createProject(name)
    {
        this.config.reset();
        this.config.set(name, {
            resources: {},
            nodes: {},
            edges: {},
            stats: {
                accessedAt: null,
                modifiedAt: null,
                createdAt: Date.now()
            }
        });
        this.config.commit();
        this.redrawProjectsSelector();
    }

    /**
     * @param {String} name
     */
    loadProject(name)
    {
        if (this.ui('menu-contents-projects').value !== name) {
            this.ui('menu-contents-projects').value = name;
        }

        this.config.reset();
        this.currentProject = this.config.ns(name);
        this.currentProjectName = name;

        const area = this.ui('area');
        area.innerHTML = '';

        this.ui('menu-contents').classList.add('menu-contents-project-loaded');

        const config = this.currentProject.getData();
        const projectMenu = this.ui('menu-contents-project');
        projectMenu.innerHTML = '
Resources
';

        for (const id in config.resources) {
            this.createResourceInputs(id);
        }
        this.createResourceInputs();

        for (const id in config.nodes) {
            this.drawNode(id);
        }

        config.stats.accessedAt = Date.now();
        this.currentProject.commit();
    }

    saveProject()
    {
        this.currentProject.get('stats').modifiedAt = Date.now();
        this.currentProject.commit();
    }

    deleteProject()
    {
        this.config.unset(this.currentProjectName);
        this.config.commit();
        window.location.reload();
    }

    /**
     * @param {String} [id]
     */
    createResourceInputs(id)
    {
        if (typeof id !== 'string') {
            id = this.findFreeKey('r', this.currentProject.ns('resources'))
        }
        const elements = {name: null, amount: null, concurrency: null};
        const config = this.currentProject.ns('resources').getData();
        const resource = document.createElement('div');

        for (const type in elements) {
            elements[type] = document.createElement('input');
            elements[type].type = 'text';
            elements[type].placeholder = type;
            elements[type].value = config[id] ? config[id][type] : '';
            elements[type].addEventListener('change', e => this.updateResource(id, type, e.target));
            resource.appendChild(elements[type]);
        }

        resource.className = 'menu-contents-project-resource';
        this.ui('menu-contents-project').appendChild(resource);
    }

    /**
     * @param {String} id
     * @param {String} type
     * @param {HTMLElement} element
     */
    updateResource(id, type, element)
    {
        const resources = this.currentProject.ns('resources');
        let value = element.value;
        if (type !== 'name') {
            value = Math.max(0, parseFloat(value) || 0);
        }
        if (!resources.has(id)) {
            resources.set(id, {name: null, amount: null, concurrency: null});
            this.createResourceInputs();
        }
        if (type === 'name' && value === '') {
            if (confirm('Are you sure you want to delete this resource?')) {
                resources.unset(id);
                element.parentNode.parentNode.removeChild(element.parentNode);
            } else {
                element.value = resources.get(id)[type];
            }
        } else {
            element.value = resources.get(id)[type] = value;
        }
        if (type === 'name') {
            this.updateNodes();
        }
    }
    /**
     * @param {String} name
     */
    addNode(name)
    {
        const nodes = this.currentProject.ns('nodes');
        const id = this.findFreeKey('n', nodes);

        let top = 200, left = 400;
        for (const node of nodes) {
            if (left < node.left + 320) {
                left = node.left + 320;
            }
        }
        nodes.set(id, {name, top, left});

        this.drawNode(id);
    }

    /**
     * @param {String} id
     */
    deleteNode(id)
    {
        const node = this.ui(id);
        node.parentNode.removeChild(node);
        this.currentProject.ns('nodes').unset(id);
    }

    /**
     * @param {String} id
     */
    drawNode(id)
    {
        const config = this.currentProject.ns('nodes').get(id);
        const node = document.createElement('div');
        node.id = id;
        node.className = 'node';
        node.style.top = `${config.top}px`;
        node.style.left = `${config.left}px`;

        const input = document.createElement('input');
        input.type = 'text';
        input.value = config.name;
        node.appendChild(input);

        const deleteButton = document.createElement('button');
        deleteButton.innerText = 'delete';
        deleteButton.className = 'node-delete';
        node.appendChild(deleteButton);

        this.ui('area').appendChild(node);

        this.updateNode(id);

        input.addEventListener('change', e => {
            if (e.target.value === '') {
                alert('Milestone name cannot be empty.');
                e.target.value = config.name;
            } else {
                config.name = e.target.value;
            }
        });

        deleteButton.addEventListener('click', () => {
            if (confirm('Are you sure you want to delete the selected milestone? This action cannot be undone.')) {
                this.deleteNode(id);
            }
        });

        const moveListener = e => {
            if (!e.target.movedata) {
                return;
            }
            config.top = Math.max(e.target.movedata.originalTop + (e.clientY - e.target.movedata.top), 0);
            config.left = Math.max(e.target.movedata.originalLeft + (e.clientX - e.target.movedata.left), 0);
            node.style.top = `${config.top}px`;
            node.style.left = `${config.left}px`;
        };

        node.addEventListener('mousedown', e => {
            e.target.movedata = {
                top: e.clientY,
                left: e.clientX,
                originalTop: config.top,
                originalLeft: config.left
            };
            e.target.addEventListener('mousemove', moveListener);
        });

        node.addEventListener('mouseup', e => {
            e.target.removeEventListener('mousemove', moveListener);
            delete e.target.movedata;
        });
    }

    updateNodes()
    {
        for (const id of this.currentProject.ns('nodes').keys()) {
            this.updateNode(id);
        }
    }

    /**
     * @param {String} id
     */
    updateNode(id)
    {
        throw "not implemented";
    }

    initializeUi()
    {
        this.ui('menu-collapse').onclick = () => this.ui('menu').classList.toggle('menu-collapsed');

        this.redrawProjectsSelector();

        this.ui('menu-contents-new').addEventListener('click', () => {
            if (this.shouldStayOnPage()) {
                return;
            }

            let promptText = '';
            let newName = this.findFreeKey('Untitled Project ', this.config);
            while (true) {
                promptText += 'Please enter a name for the new project:';
                newName = prompt(promptText, newName);
                if (newName === null) {
                    return;
                } else if (newName === '') {
                    promptText = 'The new project name cannot be empty.\n';
                } else if (this.config.has(newName)) {
                    promptText = 'A project with the selected name already exists.\n';
                } else {
                    break;
                }
            }

            this.createProject(newName);
            this.loadProject(newName);
        });

        this.ui('menu-contents-delete').addEventListener('click', () => {
            if (confirm('Are you sure you want to delete the current project? This action cannot be undone.')) {
                this.deleteProject(name);
            }
        });

        this.ui('menu-contents-save').addEventListener('click', () => this.saveProject());
        this.ui('menu-contents-add-node').addEventListener('click', () => {
            let newName, promptText = '';
            while (true) {
                promptText += 'Please enter a name for the new milestone:';
                newName = prompt(promptText, newName);
                if (newName === null) {
                    return;
                } else if (newName === '') {
                    promptText = 'The new milestone name cannot be empty.\n';
                } else {
                    break;
                }
            }
            this.addNode(newName);
        });

        this.ui('menu-contents-projects').addEventListener('change', e => {
            if (this.shouldStayOnPage()) {
                return;
            }
            this.loadProject(e.target.options[e.target.selectedIndex].value);
        });

        window.addEventListener('beforeunload', e => {
            const message = this.shouldStayOnPage(null, true);
            if (message) {
                e.preventDefault();
                return e.returnValue = message;
            }
        });
    }
};

window.onload = () => new PERT();
<commit_msg>Made the dragging of milestones more stable<commit_after>class PERT
{
    constructor()
    {
        this.config = new DataStore('pert');
        this.uiCache = {};
        this.currentProject = null;
        this.currentProjectName = null;

        this.initializeUi();

        // Load the last opened project
        const projects = [];
        for (const name of this.config.keys()) {
            const accessedAt = this.config.get(name).stats.accessedAt;
            projects.push({name, accessedAt});
        }
        projects.sort((a, b) => b.accessedAt - a.accessedAt);
        for (const project of projects) {
            this.loadProject(project.name);
            break;
        }
    }

    /**
     * @param {String} name
     * @returns {HTMLElement}
     */
    ui(name)
    {
        if (!(name in this.uiCache)) {
            this.uiCache[name] = document.getElementById(name);
        }
        return this.uiCache[name];
    }

    /**
     * @param {String} prefix
     * @param {DataStore} config
     */
    findFreeKey(prefix, config)
    {
        let key, i=0;
        do {
            key = prefix + (++i);
        } while (config.has(key));
        return key;
    }

    redrawProjectsSelector()
    {
        const select = this.ui('menu-contents-projects');
        select.innerHTML = '<option disabled selected>Load a project</option>';
        for (const project of this.config.keys()) {
            const option = document.createElement('option');
            option.innerText = project;
            option.value = project;
            select.appendChild(option);
        }
    }

    /**
     * @param {String} [action]
     * @param {Boolean} [returnMessage]
     * @returns {Boolean|String}
     */
    shouldStayOnPage(action, returnMessage)
    {
        let message = 'The current project has unsaved changes which will be lost if you continue.';
        if (typeof action === 'string') {
            message += ` ${action}`;
        }
        if (this.config.changed()) {
            return returnMessage ? message : !confirm(message);
        }
        return false;
    }

    /**
     * @param {String} name
     */
    createProject(name)
    {
        this.config.reset();
        this.config.set(name, {
            resources: {},
            nodes: {},
            edges: {},
            stats: {
                accessedAt: null,
                modifiedAt: null,
                createdAt: Date.now()
            }
        });
        this.config.commit();
        this.redrawProjectsSelector();
    }

    /**
     * @param {String} name
     */
    loadProject(name)
    {
        if (this.ui('menu-contents-projects').value !== name) {
            this.ui('menu-contents-projects').value = name;
        }

        this.config.reset();
        this.currentProject = this.config.ns(name);
        this.currentProjectName = name;

        const area = this.ui('area');
        area.innerHTML = '';

        this.ui('menu-contents').classList.add('menu-contents-project-loaded');

        const config = this.currentProject.getData();
        const projectMenu = this.ui('menu-contents-project');
        projectMenu.innerHTML = '
Resources
';

        for (const id in config.resources) {
            this.createResourceInputs(id);
        }
        this.createResourceInputs();

        for (const id in config.nodes) {
            this.drawNode(id);
        }

        config.stats.accessedAt = Date.now();
        this.currentProject.commit();
    }

    saveProject()
    {
        this.currentProject.get('stats').modifiedAt = Date.now();
        this.currentProject.commit();
    }

    deleteProject()
    {
        this.config.unset(this.currentProjectName);
        this.config.commit();
        window.location.reload();
    }

    /**
     * @param {String} [id]
     */
    createResourceInputs(id)
    {
        if (typeof id !== 'string') {
            id = this.findFreeKey('r', this.currentProject.ns('resources'))
        }
        const elements = {name: null, amount: null, concurrency: null};
        const config = this.currentProject.ns('resources').getData();
        const resource = document.createElement('div');

        for (const type in elements) {
            elements[type] = document.createElement('input');
            elements[type].type = 'text';
            elements[type].placeholder = type;
            elements[type].value = config[id] ? config[id][type] : '';
            elements[type].addEventListener('change', e => this.updateResource(id, type, e.target));
            resource.appendChild(elements[type]);
        }

        resource.className = 'menu-contents-project-resource';
        this.ui('menu-contents-project').appendChild(resource);
    }

    /**
     * @param {String} id
     * @param {String} type
     * @param {HTMLElement} element
     */
    updateResource(id, type, element)
    {
        const resources = this.currentProject.ns('resources');
        let value = element.value;
        if (type !== 'name') {
            value = Math.max(0, parseFloat(value) || 0);
        }
        if (!resources.has(id)) {
            resources.set(id, {name: null, amount: null, concurrency: null});
            this.createResourceInputs();
        }
        if (type === 'name' && value === '') {
            if (confirm('Are you sure you want to delete this resource?')) {
                resources.unset(id);
                element.parentNode.parentNode.removeChild(element.parentNode);
            } else {
                element.value = resources.get(id)[type];
            }
        } else {
            element.value = resources.get(id)[type] = value;
        }
        if (type === 'name') {
            this.updateNodes();
        }
    }
    /**
     * @param {String} name
     */
    addNode(name)
    {
        const nodes = this.currentProject.ns('nodes');
        const id = this.findFreeKey('n', nodes);

        let top = 200, left = 400;
        for (const node of nodes) {
            if (left < node.left + 320) {
                left = node.left + 320;
            }
        }
        nodes.set(id, {name, top, left});

        this.drawNode(id);
    }

    /**
     * @param {String} id
     */
    deleteNode(id)
    {
        const node = this.ui(id);
        node.parentNode.removeChild(node);
        this.currentProject.ns('nodes').unset(id);
    }

    /**
     * @param {String} id
     */
    drawNode(id)
    {
        const config = this.currentProject.ns('nodes').get(id);
        const node = document.createElement('div');
        node.id = id;
        node.className = 'node';
        node.style.top = `${config.top}px`;
        node.style.left = `${config.left}px`;

        const input = document.createElement('input');
        input.type = 'text';
        input.value = config.name;
        node.appendChild(input);

        const deleteButton = document.createElement('button');
        deleteButton.innerText = 'delete';
        deleteButton.className = 'node-delete';
        node.appendChild(deleteButton);

        this.ui('area').appendChild(node);

        this.updateNode(id);

        input.addEventListener('change', e => {
            if (e.target.value === '') {
                alert('Milestone name cannot be empty.');
                e.target.value = config.name;
            } else {
                config.name = e.target.value;
            }
        });

        deleteButton.addEventListener('click', () => {
            if (confirm('Are you sure you want to delete the selected milestone? This action cannot be undone.')) {
                this.deleteNode(id);
            }
        });

        node.addEventListener('mousedown', e => {
            this.moveNode = {
                top: e.clientY,
                left: e.clientX,
                originalTop: config.top,
                originalLeft: config.left,
                node,
                config
            };
            e.preventDefault();
        });
    }

    updateNodes()
    {
        for (const id of this.currentProject.ns('nodes').keys()) {
            this.updateNode(id);
        }
    }

    /**
     * @param {String} id
     */
    updateNode(id)
    {
        throw "not implemented";
    }

    initializeUi()
    {
        this.ui('menu-collapse').onclick = () => this.ui('menu').classList.toggle('menu-collapsed');

        this.redrawProjectsSelector();

        this.ui('menu-contents-new').addEventListener('click', () => {
            if (this.shouldStayOnPage()) {
                return;
            }

            let promptText = '';
            let newName = this.findFreeKey('Untitled Project ', this.config);
            while (true) {
                promptText += 'Please enter a name for the new project:';
                newName = prompt(promptText, newName);
                if (newName === null) {
                    return;
                } else if (newName === '') {
                    promptText = 'The new project name cannot be empty.\n';
                } else if (this.config.has(newName)) {
                    promptText = 'A project with the selected name already exists.\n';
                } else {
                    break;
                }
            }

            this.createProject(newName);
            this.loadProject(newName);
        });

        this.ui('menu-contents-delete').addEventListener('click', () => {
            if (confirm('Are you sure you want to delete the current project? This action cannot be undone.')) {
                this.deleteProject(name);
            }
        });

        this.ui('menu-contents-save').addEventListener('click', () => this.saveProject());
        this.ui('menu-contents-add-node').addEventListener('click', () => {
            let newName, promptText = '';
            while (true) {
                promptText += 'Please enter a name for the new milestone:';
                newName = prompt(promptText, newName);
                if (newName === null) {
                    return;
                } else if (newName === '') {
                    promptText = 'The new milestone name cannot be empty.\n';
                } else {
                    break;
                }
            }
            this.addNode(newName);
        });

        this.ui('menu-contents-projects').addEventListener('change', e => {
            if (this.shouldStayOnPage()) {
                return;
            }
            this.loadProject(e.target.options[e.target.selectedIndex].value);
        });

        document.body.addEventListener('mousemove', e => {
            if (!this.moveNode) {
                return;
            }
            this.moveNode.config.top = Math.max(this.moveNode.originalTop + e.clientY - this.moveNode.top, 0);
            this.moveNode.config.left = Math.max(this.moveNode.originalLeft + e.clientX - this.moveNode.left, 0);
            this.moveNode.node.style.top = `${this.moveNode.config.top}px`;
            this.moveNode.node.style.left = `${this.moveNode.config.left}px`;
        });

        document.documentElement.addEventListener('mouseout', e => {
            if (e.fromElement.tagName === 'HTML') {
                this.moveNode = null;
            }
        });
        document.body.addEventListener('mouseup', () => this.moveNode = null);

        window.addEventListener('beforeunload', e => {
            const message = this.shouldStayOnPage(null, true);
            if (message) {
                e.preventDefault();
                return e.returnValue = message;
            }
        });
    }
};

window.onload = () => new PERT();
<|endoftext|>


<commit_before>var MyGame = MyGame || {};

MyGame.LEVEL_COUNT = 2; // the game has 2 levels, for now

MyGame.Play = function () {};

MyGame.Play.prototype = {
  preload: function () {
  },

  create: function () {
    var me = this;

    me.loadLevel();

    me.input.onDown.add(me.playerJump, me);
    me.input.keyboard.addKey(Phaser.KeyCode.UP).onDown.add(me.playerJump, me);
  },

  loadLevel: function() {
    var me = this;

    me.level = parseInt(localStorage.level) || 1;
    if (me.level < 1 || me.level > MyGame.LEVEL_COUNT) me.level = 1;

    me.createBackground();
    me.createGameMap();
    me.createEnemies();
    me.createStartAndCheckPoint();
    me.createPlayer();
    me.createHUD();
    me.createSound();

    me.time.events.loop(Phaser.Timer.SECOND, me.updateHUD, me);
  },

  stopTimer: function() {
    this.time.events.removeAll();
  },

  createSound: function() {
    var me = this;

    if (!me.s_music) me.s_music = me.add.audio('music');
    me.s_music.play('', 0, 0.3, true);

    if (!me.s_hit) me.s_hit = me.add.audio('hit');
    if (!me.s_jump) me.s_jump = me.add.audio('jump');
    if (!me.s_completed) me.s_completed = me.add.audio('completed');
  },

  createHUD: function() {
    var me = this;

    // lives
    if (me.lives) me.lives.destroy();
    me.lives = me.add.image(50, 50, 'texture-atlas', 'hud_p2');
    me.lives.anchor.set(0.5);
    me.lives.fixedToCamera = true;

    if (me.livesLabel) me.livesLabel.destroy();
    me.livesLabel = me.add.bitmapText(me.lives.x + me.lives.width + 12, me.lives.y, 'myfont', ' x ' + me.player.health, 35);
    me.livesLabel.anchor.set(0.5);
    me.livesLabel.fixedToCamera = true;

    // current meters
    if (me.metersLabel) me.metersLabel.destroy();
    me.metersLabel = me.add.bitmapText(Math.round(me.game.width/2), me.lives.y, 'myfont', (me.level - 1) * 10 + 'm', 40);
    me.metersLabel.anchor.set(0.5);
    me.metersLabel.fixedToCamera = true;
  },

  loseOneLife: function() {
    var me = this;

    me.player.health--;
    if (me.player.health <= 0) {
      me.s_music.pause();
      me.stopTimer();
      me.state.start('YouLose');
    } else {
      me.livesLabel.text = ' x ' + me.player.health;
    }
  },

  createBackground: function() {
    var me = this;

    if (me.bg) me.bg.destroy();
    me.bg = me.add.image(0, 0, 'background');
  },

  createPlayer: function() {
    var me = this;

    if (me.player) me.player.destroy();

    me.player = me.add.sprite(60, 150, 'texture-atlas', 'alienBlue_walk2');
    me.player.anchor.setTo(0.5, 0.5);
    me.player.animations.add('walking', ['alienBlue_walk1', 'alienBlue_walk2'], 5, true);

    me.physics.arcade.enable(me.player);
    me.player.body.gravity.y = 1000;
    me.camera.follow(me.player);
    me.player.health = 3;
  },

  initPlayer: function() {
    var me = this;

    me.player.animations.stop();
    me.player.x = 60;
    me.player.y = 150;
    me.player.body.velocity.x = 0;
    me.player.body.velocity.y = 0;

    me.player.body.blocked.down = false;
    me.player.alive = true;
  },

  createStartAndCheckPoint: function() {
    var me = this;

    if (me.startAndCheckPoint) me.startAndCheckPoint.destroy();

    me.startAndCheckPoint = me.game.add.group();
    me.map.createFromObjects('ObjectLayer', 'startpoint', 'texture-atlas', 'signRight', true, false, me.startAndCheckPoint);
    me.map.createFromObjects('ObjectLayer', 'checkpoint', 'texture-atlas', 'sign', true, false, me.startAndCheckPoint);

    var pos = me.startAndCheckPoint.getAt(0).position;
    me.add.bitmapText(pos.x, pos.y + 12, 'myfont', (me.level - 1) * 10 + 'm', 24);

    pos = me.startAndCheckPoint.getAt(1).position;
    me.add.bitmapText(pos.x, pos.y + 12, 'myfont', me.level * 10 + 'm', 24);
  },

  createEnemies: function() {
    var me = this;

    if (me.enemyGruop) me.enemyGruop.destroy();

    // create our enemies, put them in a group
    me.enemyGroup = me.game.add.group();
    me.enemyGroup.enableBody = true;
    me.map.createFromObjects('ObjectLayer', 'box', 'texture-atlas', 'blockerMad', true, false, me.enemyGroup);
  },

  createGameMap: function() {
    var me = this;

    if (me.groundLayer) me.groundLayer.destroy();
    if (me.backgroundLayer) me.backgroundLayer.destroy();
    if (me.map) me.map.destroy();

    me.map = me.add.tilemap('level' + me.level);
    me.map.addTilesetImage('mytileset', 'tiles');

    me.backgroundLayer = me.map.createLayer('BackgroundLayer');
    me.groundLayer = me.map.createLayer('GroundLayer');
    me.map.setCollisionBetween(1, 35, true, 'GroundLayer');

    me.groundLayer.resizeWorld();
  },

  playerJump: function(point, isDoubleTap) {
    var me = this;

    if (me.player.body.blocked.down) {
      this.s_jump.play('', 0, 1);
      me.player.animations.stop();
      me.player.frameName = 'alienBlue_walk2';
      me.player.body.velocity.y = -550;
    }
  },

  playerHit: function(player, enemy) {
    player.alive = false;
    this.s_hit.play('', 0, 1);

    this.loseOneLife();
    this.initPlayer();
  },

  levelCompleted: function() {
    var me = this;

    me.s_music.pause();
    me.s_completed.play();

    var nextLevel = me.level + 1;
    if (nextLevel > MyGame.LEVEL_COUNT) {
      localStorage.level = 1;
      me.stopTimer();
      me.state.start('YouWin');
    } else {
      localStorage.level = nextLevel;
      me.loadLevel();
    }
  },

  updateHUD: function() {
    var me = this;

    // meters
    me.metersLabel.text = (me.level - 1) * 10 + Math.round(me.player.x * 10 / me.world.width) + 'm';
  },

  update: function() {
    var me = this;

    if (me.player && me.player.alive) {
      me.physics.arcade.collide(me.player, me.groundLayer);
      me.physics.arcade.overlap(me.player, me.enemyGroup, me.playerHit, null, me);

      if (me.player.body.blocked.down) {
        me.player.body.velocity.x = 250;
        me.player.animations.play('walking');
      }

      if (me.player.x > me.world.width) me.levelCompleted();
    }
  },

  render: function() {
    this.game.debug.text(this.game.time.fps || '--', 2, 14, "#00ff00");
  }
};
<commit_msg>remove magic numbers<commit_after>var MyGame = MyGame || {};

MyGame.LEVEL_COUNT = 2; // the game has 2 levels, for now
MyGame.PLAYER_GRAVITY_Y = 1100;//1000
MyGame.PLAYER_VELOCITY_X = 280;//250;
MyGame.PLAYER_VELOCITY_Y = -550;

MyGame.Play = function () {};

MyGame.Play.prototype = {
  preload: function () {
  },

  create: function () {
    var me = this;

    me.loadLevel();

    me.input.onDown.add(me.playerJump, me);
    me.input.keyboard.addKey(Phaser.KeyCode.UP).onDown.add(me.playerJump, me);
  },

  loadLevel: function() {
    var me = this;

    me.level = parseInt(localStorage.level) || 1;
    if (me.level < 1 || me.level > MyGame.LEVEL_COUNT) me.level = 1;

    me.createBackground();
    me.createGameMap();
    me.createEnemies();
    me.createStartAndCheckPoint();
    me.createPlayer();
    me.createHUD();
    me.createSound();

    me.time.events.loop(Phaser.Timer.SECOND, me.updateHUD, me);
  },

  stopTimer: function() {
    this.time.events.removeAll();
  },

  createSound: function() {
    var me = this;

    if (!me.s_music) me.s_music = me.add.audio('music');
    me.s_music.play('', 0, 0.3, true);

    if (!me.s_hit) me.s_hit = me.add.audio('hit');
    if (!me.s_jump) me.s_jump = me.add.audio('jump');
    if (!me.s_completed) me.s_completed = me.add.audio('completed');
  },

  createHUD: function() {
    var me = this;

    // lives
    if (me.lives) me.lives.destroy();
    me.lives = me.add.image(50, 50, 'texture-atlas', 'hud_p2');
    me.lives.anchor.set(0.5);
    me.lives.fixedToCamera = true;

    if (me.livesLabel) me.livesLabel.destroy();
    me.livesLabel = me.add.bitmapText(me.lives.x + me.lives.width + 12, me.lives.y, 'myfont', ' x ' + me.player.health, 35);
    me.livesLabel.anchor.set(0.5);
    me.livesLabel.fixedToCamera = true;

    // current meters
    if (me.metersLabel) me.metersLabel.destroy();
    me.metersLabel = me.add.bitmapText(Math.round(me.game.width/2), me.lives.y, 'myfont', (me.level - 1) * 10 + 'm', 40);
    me.metersLabel.anchor.set(0.5);
    me.metersLabel.fixedToCamera = true;
  },

  loseOneLife: function() {
    var me = this;

    me.player.health--;
    if (me.player.health <= 0) {
      me.s_music.pause();
      me.stopTimer();
      me.state.start('YouLose');
    } else {
      me.livesLabel.text = ' x ' + me.player.health;
    }
  },

  createBackground: function() {
    var me = this;

    if (me.bg) me.bg.destroy();
    me.bg = me.add.image(0, 0, 'background');
  },

  createPlayer: function() {
    var me = this;

    if (me.player) me.player.destroy();

    me.player = me.add.sprite(60, 150, 'texture-atlas', 'alienBlue_walk2');
    me.player.anchor.setTo(0.5, 0.5);
    me.player.animations.add('walking', ['alienBlue_walk1', 'alienBlue_walk2'], 5, true);

    me.physics.arcade.enable(me.player);
    me.player.body.gravity.y = MyGame.PLAYER_GRAVITY_Y;
    me.camera.follow(me.player);
    me.player.health = 3;
  },

  initPlayer: function() {
    var me = this;

    me.player.animations.stop();
    me.player.x = 60;
    me.player.y = 150;
    me.player.body.velocity.x = 0;
    me.player.body.velocity.y = 0;

    me.player.body.blocked.down = false;
    me.player.alive = true;
  },

  createStartAndCheckPoint: function() {
    var me = this;

    if (me.startAndCheckPoint) me.startAndCheckPoint.destroy();

    me.startAndCheckPoint = me.game.add.group();
    me.map.createFromObjects('ObjectLayer', 'startpoint', 'texture-atlas', 'signRight', true, false, me.startAndCheckPoint);
    me.map.createFromObjects('ObjectLayer', 'checkpoint', 'texture-atlas', 'sign', true, false, me.startAndCheckPoint);

    var pos = me.startAndCheckPoint.getAt(0).position;
    me.add.bitmapText(pos.x, pos.y + 12, 'myfont', (me.level - 1) * 10 + 'm', 24);

    pos = me.startAndCheckPoint.getAt(1).position;
    me.add.bitmapText(pos.x, pos.y + 12, 'myfont', me.level * 10 + 'm', 24);
  },

  createEnemies: function() {
    var me = this;

    if (me.enemyGruop) me.enemyGruop.destroy();

    // create our enemies, put them in a group
    me.enemyGroup = me.game.add.group();
    me.enemyGroup.enableBody = true;
    me.map.createFromObjects('ObjectLayer', 'box', 'texture-atlas', 'blockerMad', true, false, me.enemyGroup);
  },

  createGameMap: function() {
    var me = this;

    if (me.groundLayer) me.groundLayer.destroy();
    if (me.backgroundLayer) me.backgroundLayer.destroy();
    if (me.map) me.map.destroy();

    me.map = me.add.tilemap('level' + me.level);
    me.map.addTilesetImage('mytileset', 'tiles');

    me.backgroundLayer = me.map.createLayer('BackgroundLayer');
    me.groundLayer = me.map.createLayer('GroundLayer');
    me.map.setCollisionBetween(1, 35, true, 'GroundLayer');

    me.groundLayer.resizeWorld();
  },

  playerJump: function(point, isDoubleTap) {
    var me = this;

    if (me.player.body.blocked.down) {
      this.s_jump.play('', 0, 0.5);
      me.player.animations.stop();
      me.player.frameName = 'alienBlue_walk2';
      me.player.body.velocity.y = MyGame.PLAYER_VELOCITY_Y;
    }
  },

  playerHit: function(player, enemy) {
    player.alive = false;
    this.s_hit.play('', 0, 0.5);

    this.loseOneLife();
    this.initPlayer();
  },

  levelCompleted: function() {
    var me = this;

    me.s_music.pause();
    me.s_completed.play();

    var nextLevel = me.level + 1;
    if (nextLevel > MyGame.LEVEL_COUNT) {
      localStorage.level = 1;
      me.stopTimer();
      me.state.start('YouWin');
    } else {
      localStorage.level = nextLevel;
      me.loadLevel();
    }
  },

  updateHUD: function() {
    var me = this;

    // meters
    me.metersLabel.text = (me.level - 1) * 10 + Math.round(me.player.x * 10 / me.world.width) + 'm';
  },

  update: function() {
    var me = this;

    if (me.player && me.player.alive) {
      me.physics.arcade.collide(me.player, me.groundLayer);
      me.physics.arcade.overlap(me.player, me.enemyGroup, me.playerHit, null, me);

      if (me.player.body.blocked.down) {
        me.player.body.velocity.x = MyGame.PLAYER_VELOCITY_X;
        me.player.animations.play('walking');
      }

      if (me.player.x > me.world.width) me.levelCompleted();
    }
  },

  render: function() {
    this.game.debug.text(this.game.time.fps || '--', 2, 14, "#00ff00");
  }
};
<|endoftext|>


<commit_before>function plus(){
    document.getElementById('number').innerHTML = parseInt(document.getElementById('number').innerHTML) + 1;
}

function reset(){
    if(confirm('Reset?')){
        document.getElementById('number').innerHTML = 0;
    }
}

var unlocked = 1;

window.onkeydown = function(e){
    if(unlocked){
        unlocked = 0;
        plus();
    }
};

window.onkeyup = function(e){
    unlocked = 1;
};
<commit_msg>added localStorage<commit_after>function get(i){
    return document.getElementById(i);
}

function plus(){
    get('number').innerHTML = parseInt(get('number').innerHTML) + 1;
}

function reset(){
    if(confirm('Reset?')){
        localStorage.removeItem('plus-0');
        get('number').innerHTML = 0;
    }
}

var unlocked = 1;
get('number').innerHTML = localStorage.getItem('plus-0') === null
    ? 0
    : localStorage.getItem('plus-0');

window.onbeforeunload = function(e){
    if(parseInt(get('number').innerHTML) > 0){
        localStorage.setItem(
            'plus-0',
            get('number').innerHTML
        );
    }
}

window.onkeydown = function(e){
    if(unlocked){
        unlocked = 0;
        plus();
    }
};

window.onkeyup = function(e){
    unlocked = 1;
};
<|endoftext|>


<commit_before>function plus(){
    document.getElementById('number').innerHTML = parseInt(document.getElementById('number').innerHTML) + 1;
}

function reset(){
    if(confirm('Reset?')){
        localStorage.removeItem('plus-0');
        document.getElementById('number').innerHTML = 0;
    }
}

var unlocked = 1;
document.getElementById('number').innerHTML = localStorage.getItem('plus-0') === null
  ? 0
  : localStorage.getItem('plus-0');

window.onbeforeunload = function(e){
    if(parseInt(document.getElementById('number').innerHTML) > 0){
        localStorage.setItem(
          'plus-0',
          document.getElementById('number').innerHTML
        );
    }
}

window.onkeydown = function(e){
    if(unlocked){
        unlocked = 0;
        plus();
    }
};

window.onkeyup = function(e){
    unlocked = 1;
};
<commit_msg>changed unlocked variable to boolean<commit_after>function plus(){
    document.getElementById('number').innerHTML = parseInt(document.getElementById('number').innerHTML) + 1;
}

function reset(){
    if(confirm('Reset?')){
        localStorage.removeItem('plus-0');
        document.getElementById('number').innerHTML = 0;
    }
}

var unlocked = true;
document.getElementById('number').innerHTML = localStorage.getItem('plus-0') === null
  ? 0
  : localStorage.getItem('plus-0');

window.onbeforeunload = function(e){
    if(parseInt(document.getElementById('number').innerHTML) > 0){
        localStorage.setItem(
          'plus-0',
          document.getElementById('number').innerHTML
        );
    }
}

window.onkeydown = function(e){
    if(unlocked){
        unlocked = false;
        plus();
    }
};

window.onkeyup = function(e){
    unlocked = true;
};
<|endoftext|>