<commit_before>(function() {
/* Start angularLocalStorage */
'use strict';
var angularLocalStorage = angular.module('LocalStorageModule', []);

angularLocalStorage.provider('localStorageService', function(){
  // You should set a prefix to avoid overwriting any local storage variables from the rest of your app
  // e.g. localStorageServiceProvider.setPrefix('youAppName');
  // With provider you can use config as this:
  // myApp.config(function (localStorageServiceProvider) {
  //    localStorageServiceProvider.prefix = 'yourAppName';
  // });

  this.prefix = 'ls';

  // Cookie options (usually in case of fallback)
  // expiry = Number of days before cookies expire // 0 = Does not expire
  // path = The web path the cookie represents
  this.cookie = {
    expiry: 30,
    path: '/'
  };

  // Send signals for each of the following actions?
  this.notify = {
    setItem: true,
    removeItem: false
  };

  // Setter for the prefix
  this.setPrefix = function(prefix){
    this.prefix = prefix;
  };

  // Setter for cookie config
  this.setStorageCookie = function(exp, path){
    this.cookie = {
      expiry: exp,
      path: path
    };
  };

  // Setter for notification config
  // itemSet & itemRemove should be booleans
  this.setNotify = function(itemSet, itemRemove){
    this.notify = {
      setItem: itemSet,
      removeItem: itemRemove
    };
  };

  this.$get = ['$rootScope', '$window', '$document', function($rootScope, $window, $document){

    var prefix = this.prefix;
    var cookie = this.cookie;
    var notify = this.notify;

    // If there is a prefix set in the config lets use that with an appended period for readability
    if (prefix.substr(-1) !== '.') {
      prefix = !!prefix ? prefix + '.' : '';
    }

    // Checks the browser to see if local storage is supported
    var browserSupportsLocalStorage = (function () {
      try {
        var supported = ('localStorage' in $window && $window['localStorage'] !== null);

        // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
        // is available, but trying to call .setItem throws an exception.
        //
        // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
        // that exceeded the quota."
        var key = prefix + '__' + Math.round(Math.random() * 1e7);
        if (supported) {
          localStorage.setItem(key, '');
          localStorage.removeItem(key);
        }

        return true;
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return false;
      }
    }());

    // Directly adds a value to local storage
    // If local storage is not available in the browser use cookies
    // Example use: localStorageService.add('library','angular');
    var addToLocalStorage = function (key, value) {

      // If this browser does not support local storage use cookies
      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        if (notify.setItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
        }
        return addToCookies(key, value);
      }

      // Let's convert undefined values to null to get the value consistent
      if (typeof value === "undefined") {
        value = null;
      }

      try {
        if (angular.isObject(value) || angular.isArray(value)) {
          value = angular.toJson(value);
        }
        localStorage.setItem(prefix + key, value);
        if (notify.setItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'localStorage'});
        }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return addToCookies(key, value);
      }
      return true;
    };

    // Directly get a value from local storage
    // Example use: localStorageService.get('library'); // returns 'angular'
    var getFromLocalStorage = function (key) {

      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
        return getFromCookies(key);
      }

      var item = localStorage.getItem(prefix + key);
      // angular.toJson will convert null to 'null', so a proper conversion is needed
      // FIXME not a perfect solution, since a valid 'null' string can't be stored
      if (!item || item === 'null') {
        return null;
      }

      if (item.charAt(0) === "{" || item.charAt(0) === "[") {
        return angular.fromJson(item);
      }

      return item;
    };

    // Remove an item from local storage
    // Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
    var removeFromLocalStorage = function (key) {
      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        if (notify.removeItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
        }
        return removeFromCookies(key);
      }

      try {
        localStorage.removeItem(prefix+key);
        if (notify.removeItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'localStorage'});
        }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return removeFromCookies(key);
      }
      return true;
    };

    // Return array of keys for local storage
    // Example use: var keys = localStorageService.keys()
    var getKeysForLocalStorage = function () {

      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        return false;
      }

      var prefixLength = prefix.length;
      var keys = [];
      for (var key in localStorage) {
        // Only return keys that are for this app
        if (key.substr(0,prefixLength) === prefix) {
          try {
            keys.push(key.substr(prefixLength));
          } catch (e) {
            $rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
            return [];
          }
        }
      }
      return keys;
    };

    // Remove all data for this app from local storage
    // Also optionally takes a regular expression string and removes the matching key-value pairs
    // Example use: localStorageService.clearAll();
    // Should be used mostly for development purposes
    var clearAllFromLocalStorage = function (regularExpression) {

      var regularExpression = regularExpression || "";
      //accounting for the '.' in the prefix when creating a regex
      var tempPrefix = prefix.slice(0, -1) + "\.";
      var testRegex = RegExp(tempPrefix + regularExpression);

      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        return clearAllFromCookies();
      }

      var prefixLength = prefix.length;

      for (var key in localStorage) {
        // Only remove items that are for this app and match the regular expression
        if (testRegex.test(key)) {
          try {
            removeFromLocalStorage(key.substr(prefixLength));
          } catch (e) {
            $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
            return clearAllFromCookies();
          }
        }
      }
      return true;
    };

    // Checks the browser to see if cookies are supported
    var browserSupportsCookies = function() {
      try {
        return navigator.cookieEnabled ||
          ("cookie" in $document && ($document.cookie.length > 0 ||
          ($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
      } catch (e) {
          $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
          return false;
      }
    };

    // Directly adds a value to cookies
    // Typically used as a fallback is local storage is not available in the browser
    // Example use: localStorageService.cookie.add('library','angular');
    var addToCookies = function (key, value) {

      if (typeof value === "undefined") {
        return false;
      }

      if (!browserSupportsCookies()) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
        return false;
      }

      try {
        var expiry = '',
            expiryDate = new Date();

        if (value === null) {
          // Mark that the cookie has expired one day ago
          expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
          expiry = "; expires=" + expiryDate.toGMTString();
          value = '';
        } else if (cookie.expiry !== 0) {
          expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
          expiry = "; expires=" + expiryDate.toGMTString();
        }
        if (!!key) {
          $document.cookie = prefix + key + "=" + encodeURIComponent(value) + expiry + "; path="+cookie.path;
          }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
        return false;
      }
      return true;
    };

    // Directly get a value from a cookie
    // Example use: localStorageService.cookie.get('library'); // returns 'angular'
    var getFromCookies = function (key) {
      if (!browserSupportsCookies()) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
        return false;
      }

      var cookies = $document.cookie.split(';');
      for(var i=0;i < cookies.length;i++) {
        var thisCookie = cookies[i];
        while (thisCookie.charAt(0)===' ') {
          thisCookie = thisCookie.substring(1,thisCookie.length);
        }
        if (thisCookie.indexOf(prefix + key + '=') === 0) {
          return decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length));
        }
      }
      return null;
    };

    var removeFromCookies = function (key) {
      addToCookies(key,null);
    };

    var clearAllFromCookies = function () {
      var thisCookie = null, thisKey = null;
      var prefixLength = prefix.length;
      var cookies = $document.cookie.split(';');
      for(var i = 0; i < cookies.length; i++) {
        thisCookie = cookies[i];

        while (thisCookie.charAt(0) === ' ') {
          thisCookie = thisCookie.substring(1, thisCookie.length);
        }

        var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
        removeFromCookies(key);
      }
    };

    return {
      isSupported: browserSupportsLocalStorage,
      set: addToLocalStorage,
      add: addToLocalStorage, //DEPRECATED
      get: getFromLocalStorage,
      keys: getKeysForLocalStorage,
      remove: removeFromLocalStorage,
      clearAll: clearAllFromLocalStorage,
      cookie: {
        set: addToCookies,
        add: addToCookies, //DEPRECATED
        get: getFromCookies,
        remove: removeFromCookies,
        clearAll: clearAllFromCookies
      }
    };
  }]
});
}).call(this);

<commit_msg>Added setCookieDomain option<commit_after>(function() {
/* Start angularLocalStorage */
'use strict';
var angularLocalStorage = angular.module('LocalStorageModule', []);

angularLocalStorage.provider('localStorageService', function(){
  // You should set a prefix to avoid overwriting any local storage variables from the rest of your app
  // e.g. localStorageServiceProvider.setPrefix('youAppName');
  // With provider you can use config as this:
  // myApp.config(function (localStorageServiceProvider) {
  //    localStorageServiceProvider.prefix = 'yourAppName';
  // });

  this.prefix = 'ls';

  // Cookie options (usually in case of fallback)
  // expiry = Number of days before cookies expire // 0 = Does not expire
  // path = The web path the cookie represents
  this.cookie = {
    expiry: 30,
    path: '/'
  };

  // Send signals for each of the following actions?
  this.notify = {
    setItem: true,
    removeItem: false
  };

  // Setter for the prefix
  this.setPrefix = function(prefix){
    this.prefix = prefix;
  };

  // Setter for cookie config
  this.setStorageCookie = function(exp, path){
    this.cookie = {
      expiry: exp,
      path: path
    };
  };

  // Setter for cookie domain
  this.setStorageCookieDomain = function(domain){
    this.cookie.domain = domain;
  };

  // Setter for notification config
  // itemSet & itemRemove should be booleans
  this.setNotify = function(itemSet, itemRemove){
    this.notify = {
      setItem: itemSet,
      removeItem: itemRemove
    };
  };

  this.$get = ['$rootScope', '$window', '$document', function($rootScope, $window, $document){

    var prefix = this.prefix;
    var cookie = this.cookie;
    var notify = this.notify;

    // If there is a prefix set in the config lets use that with an appended period for readability
    if (prefix.substr(-1) !== '.') {
      prefix = !!prefix ? prefix + '.' : '';
    }

    // Checks the browser to see if local storage is supported
    var browserSupportsLocalStorage = (function () {
      try {
        var supported = ('localStorage' in $window && $window['localStorage'] !== null);

        // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
        // is available, but trying to call .setItem throws an exception.
        //
        // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
        // that exceeded the quota."
        var key = prefix + '__' + Math.round(Math.random() * 1e7);
        if (supported) {
          localStorage.setItem(key, '');
          localStorage.removeItem(key);
        }

        return true;
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return false;
      }
    }());

    // Directly adds a value to local storage
    // If local storage is not available in the browser use cookies
    // Example use: localStorageService.add('library','angular');
    var addToLocalStorage = function (key, value) {

      // If this browser does not support local storage use cookies
      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        if (notify.setItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
        }
        return addToCookies(key, value);
      }

      // Let's convert undefined values to null to get the value consistent
      if (typeof value === "undefined") {
        value = null;
      }

      try {
        if (angular.isObject(value) || angular.isArray(value)) {
          value = angular.toJson(value);
        }
        localStorage.setItem(prefix + key, value);
        if (notify.setItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'localStorage'});
        }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return addToCookies(key, value);
      }
      return true;
    };

    // Directly get a value from local storage
    // Example use: localStorageService.get('library'); // returns 'angular'
    var getFromLocalStorage = function (key) {

      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
        return getFromCookies(key);
      }

      var item = localStorage.getItem(prefix + key);
      // angular.toJson will convert null to 'null', so a proper conversion is needed
      // FIXME not a perfect solution, since a valid 'null' string can't be stored
      if (!item || item === 'null') {
        return null;
      }

      if (item.charAt(0) === "{" || item.charAt(0) === "[") {
        return angular.fromJson(item);
      }

      return item;
    };

    // Remove an item from local storage
    // Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
    var removeFromLocalStorage = function (key) {
      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        if (notify.removeItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
        }
        return removeFromCookies(key);
      }

      try {
        localStorage.removeItem(prefix+key);
        if (notify.removeItem) {
          $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'localStorage'});
        }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
        return removeFromCookies(key);
      }
      return true;
    };

    // Return array of keys for local storage
    // Example use: var keys = localStorageService.keys()
    var getKeysForLocalStorage = function () {

      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        return false;
      }

      var prefixLength = prefix.length;
      var keys = [];
      for (var key in localStorage) {
        // Only return keys that are for this app
        if (key.substr(0,prefixLength) === prefix) {
          try {
            keys.push(key.substr(prefixLength));
          } catch (e) {
            $rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
            return [];
          }
        }
      }
      return keys;
    };

    // Remove all data for this app from local storage
    // Also optionally takes a regular expression string and removes the matching key-value pairs
    // Example use: localStorageService.clearAll();
    // Should be used mostly for development purposes
    var clearAllFromLocalStorage = function (regularExpression) {

      var regularExpression = regularExpression || "";
      //accounting for the '.' in the prefix when creating a regex
      var tempPrefix = prefix.slice(0, -1) + "\.";
      var testRegex = RegExp(tempPrefix + regularExpression);

      if (!browserSupportsLocalStorage) {
        $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
        return clearAllFromCookies();
      }

      var prefixLength = prefix.length;

      for (var key in localStorage) {
        // Only remove items that are for this app and match the regular expression
        if (testRegex.test(key)) {
          try {
            removeFromLocalStorage(key.substr(prefixLength));
          } catch (e) {
            $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
            return clearAllFromCookies();
          }
        }
      }
      return true;
    };

    // Checks the browser to see if cookies are supported
    var browserSupportsCookies = function() {
      try {
        return navigator.cookieEnabled ||
          ("cookie" in $document && ($document.cookie.length > 0 ||
          ($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
      } catch (e) {
          $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
          return false;
      }
    };

    // Directly adds a value to cookies
    // Typically used as a fallback is local storage is not available in the browser
    // Example use: localStorageService.cookie.add('library','angular');
    var addToCookies = function (key, value) {

      if (typeof value === "undefined") {
        return false;
      }

      if (!browserSupportsCookies()) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
        return false;
      }

      try {
        var expiry = '',
            expiryDate = new Date(),
            cookieDomain = '';

        if (value === null) {
          // Mark that the cookie has expired one day ago
          expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
          expiry = "; expires=" + expiryDate.toGMTString();
          value = '';
        } else if (cookie.expiry !== 0) {
          expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
          expiry = "; expires=" + expiryDate.toGMTString();
        }
        if (!!key) {
          var cookiePath = "; path=" + cookie.path;
          if(cookie.domain){
            cookieDomain = "; domain=" + cookie.domain;
          }
          $document.cookie = prefix + key + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain;
        }
      } catch (e) {
        $rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
        return false;
      }
      return true;
    };

    // Directly get a value from a cookie
    // Example use: localStorageService.cookie.get('library'); // returns 'angular'
    var getFromCookies = function (key) {
      if (!browserSupportsCookies()) {
        $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
        return false;
      }

      var cookies = $document.cookie.split(';');
      for(var i=0;i < cookies.length;i++) {
        var thisCookie = cookies[i];
        while (thisCookie.charAt(0)===' ') {
          thisCookie = thisCookie.substring(1,thisCookie.length);
        }
        if (thisCookie.indexOf(prefix + key + '=') === 0) {
          return decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length));
        }
      }
      return null;
    };

    var removeFromCookies = function (key) {
      addToCookies(key,null);
    };

    var clearAllFromCookies = function () {
      var thisCookie = null, thisKey = null;
      var prefixLength = prefix.length;
      var cookies = $document.cookie.split(';');
      for(var i = 0; i < cookies.length; i++) {
        thisCookie = cookies[i];

        while (thisCookie.charAt(0) === ' ') {
          thisCookie = thisCookie.substring(1, thisCookie.length);
        }

        var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
        removeFromCookies(key);
      }
    };

    return {
      isSupported: browserSupportsLocalStorage,
      set: addToLocalStorage,
      add: addToLocalStorage, //DEPRECATED
      get: getFromLocalStorage,
      keys: getKeysForLocalStorage,
      remove: removeFromLocalStorage,
      clearAll: clearAllFromLocalStorage,
      cookie: {
        set: addToCookies,
        add: addToCookies, //DEPRECATED
        get: getFromCookies,
        remove: removeFromCookies,
        clearAll: clearAllFromCookies
      }
    };
  }]
});
}).call(this);

<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var moment = require('moment');
var Reflux = require('reflux');
var db = require('app/database');

var sharedMethods = require('app/stores/component-store.shared');

var ComponentStore = Reflux.createStore(_.merge({}, sharedMethods, {
    components: {},
    componentSummaries: [],
    lastUpdated: Date.now(),

    get: function(name) {
        return this.components[name];
    },

    getLastUpdated: function() {
        return this.lastUpdated;
    },

    getMostRecentlyCreated: function(limit) {
        return (
            _.sortBy(this.components, 'created')
            .reverse()
            .slice(0, limit || 10)
        );
    },

    getMostRecentlyUpdated: function(limit) {
        var mostRecent  = this.getMostRecentlyCreated();
        var lastUpdated = _.sortBy(this.components, 'modified').reverse();

        return _.without.apply(null,
            [lastUpdated].concat(mostRecent)
        ).slice(0, limit || 10);
    },

    getMostStarred: function(limit) {
        return (
            _.sortBy(this.componentSummaries, 'stars')
            .reverse()
            .slice(0, limit || 10)
        );
    },

    populateFromDatabase: function() {
        var addComponent = this.addComponent.bind(this);

        db.getModules(function(err, modules) {
            if (err) {
                return console.error('Failed to fetch modules from DB: ', err);
            }

            modules.forEach(addComponent);

            this.trigger('change');
            this.lastUpdated = Date.now();
        }.bind(this));
    },

    parseAuthor: function(component) {
        var distTags = component['dist-tags'] || {},
            latest   = component.versions[distTags.latest] || {};

        return (latest._npmUser || component.author).name;
    },

    parseComponentSummary: function(component) {
        return {
            name: component.name,
            description: component.description,
            author: this.parseAuthor(component),
            modified: moment.utc(component.time.modified),
            created: moment.utc(component.time.created),
            keywords: component.keywords.filter(this.isUncommonKeyword),
            downloads: component.downloads || 0,
            stars: component.starCount
        };
    },

    parseComponent: function(component) {
        var distTags = component['dist-tags'] || {},
            latest   = component.versions[distTags.latest] || {};

        component.created  = component.time.created;
        component.modified = component.time.modified;
        component.branch   = latest.gitHead || 'master';

        return component;
    },

    addComponent: function(component) {
        this.components[component.name] = this.parseComponent(component);

        var existing = _.find(this.componentSummaries, { name: component.name });
        _.pull(this.componentSummaries, existing);

        this.componentSummaries.push(this.parseComponentSummary(component));
    }
}));

module.exports = ComponentStore;<commit_msg>Fixed a possible crash if no versions exist for a module<commit_after>'use strict';

var _ = require('lodash');
var moment = require('moment');
var Reflux = require('reflux');
var db = require('app/database');

var sharedMethods = require('app/stores/component-store.shared');

var ComponentStore = Reflux.createStore(_.merge({}, sharedMethods, {
    components: {},
    componentSummaries: [],
    lastUpdated: Date.now(),

    get: function(name) {
        return this.components[name];
    },

    getLastUpdated: function() {
        return this.lastUpdated;
    },

    getMostRecentlyCreated: function(limit) {
        return (
            _.sortBy(this.components, 'created')
            .reverse()
            .slice(0, limit || 10)
        );
    },

    getMostRecentlyUpdated: function(limit) {
        var mostRecent  = this.getMostRecentlyCreated();
        var lastUpdated = _.sortBy(this.components, 'modified').reverse();

        return _.without.apply(null,
            [lastUpdated].concat(mostRecent)
        ).slice(0, limit || 10);
    },

    getMostStarred: function(limit) {
        return (
            _.sortBy(this.componentSummaries, 'stars')
            .reverse()
            .slice(0, limit || 10)
        );
    },

    populateFromDatabase: function() {
        var addComponent = this.addComponent.bind(this);

        db.getModules(function(err, modules) {
            if (err) {
                return console.error('Failed to fetch modules from DB: ', err);
            }

            modules.forEach(addComponent);

            this.trigger('change');
            this.lastUpdated = Date.now();
        }.bind(this));
    },

    parseAuthor: function(component) {
        var distTags = component['dist-tags'] || {},
            latest   = component.versions[distTags.latest] || {};

        return (latest._npmUser || component.author).name;
    },

    parseComponentSummary: function(component) {
        return {
            name: component.name,
            description: component.description,
            author: this.parseAuthor(component),
            modified: moment.utc(component.time.modified),
            created: moment.utc(component.time.created),
            keywords: component.keywords.filter(this.isUncommonKeyword),
            downloads: component.downloads || 0,
            stars: component.starCount
        };
    },

    parseComponent: function(component) {
        var distTags = component['dist-tags'] || {},
            versions = component.versions || {},
            latest   = versions[distTags.latest] || {};

        component.created  = component.time.created;
        component.modified = component.time.modified;
        component.branch   = latest.gitHead || 'master';

        return component;
    },

    addComponent: function(component) {
        this.components[component.name] = this.parseComponent(component);

        var existing = _.find(this.componentSummaries, { name: component.name });
        _.pull(this.componentSummaries, existing);

        this.componentSummaries.push(this.parseComponentSummary(component));
    }
}));

module.exports = ComponentStore;<|endoftext|>


<commit_before>/**
 * @author Pedro Sanders
 * @since v1
 */
const getConfig = require('@routr/core/config_util')
const LocatorUtils = require('@routr/location/utils')
const {
    Status
} = require('@routr/core/status')
const moment = require('moment')

const SipFactory = Java.type('javax.sip.SipFactory')
const SipUtils = Java.type('gov.nist.javax.sip.Utils')
const Request = Java.type('javax.sip.message.Request')
const InetAddress = Java.type('java.net.InetAddress')
const Caffeine = Java.type('com.github.benmanes.caffeine.cache.Caffeine')
const TimeUnit = Java.type('java.util.concurrent.TimeUnit')
const LogManager = Java.type('org.apache.logging.log4j.LogManager')

const LOG = LogManager.getLogger()
var cseq = 0

class Registry {

    constructor(sipProvider, dataAPIs) {
        this.gatewaysAPI = dataAPIs.GatewaysAPI
        this.checkExpiresTime = 1
        this.sipProvider = sipProvider
        this.config = getConfig()
        this.messageFactory = SipFactory.getInstance().createMessageFactory()
        this.headerFactory = SipFactory.getInstance().createHeaderFactory()
        this.addressFactory = SipFactory.getInstance().createAddressFactory()
        this.userAgent = new java.util.ArrayList()
        this.userAgent.add(this.config.metadata.userAgent)
        this.registry = Caffeine.newBuilder()
            .expireAfterWrite(this.checkExpiresTime, TimeUnit.MINUTES)
            .build()
    }

    getLPAddress(transport, received, rport) {
        try {
            const lp = this.sipProvider.getListeningPoint(transport)
            const host = this.config.spec.externAddr ? this.config.spec.externAddr : lp.getIPAddress()
            const port = rport ? LocatorUtils.fixPort(rport) : LocatorUtils.fixPort(lp.getPort())
            return received ? {
                host: received,
                port: port
            } : {
                host: host,
                port: port
            }
        } catch (e) {
            LOG.error(`Transport ${transport} not found in configs => .spec.transport.[*]`)
            return
        }
    }

    requestChallenge(username, gwRef, gwHost, transport, received, rport, expires) {
        const contactAddr = this.getLPAddress(transport, received, rport)
        const viaAddr = this.getLPAddress(transport)
        const request = this.messageFactory.createRequest(`REGISTER sip:${gwHost} SIP/2.0\r\n\r\n`)
        const fromAddress = this.addressFactory.createAddress(`sip:${username}@${gwHost}`)
        const contactAddress = this.addressFactory.createAddress(`sip:${contactAddr.host}:${contactAddr.port};bnc`)
        const contactHeader = this.headerFactory.createContactHeader(contactAddress)
        const viaHeader = this.headerFactory.createViaHeader(viaAddr.host, viaAddr.port, transport, null)
        viaHeader.setRPort()

        const headers = []

        headers.push(viaHeader)
        headers.push(this.sipProvider.getNewCallId())
        headers.push(this.headerFactory.createProxyRequireHeader('gin'))
        headers.push(this.headerFactory.createRequireHeader('gin'))
        headers.push(this.headerFactory.createExpiresHeader(expires))
        headers.push(this.headerFactory.createMaxForwardsHeader(70))
        headers.push(this.headerFactory.createCSeqHeader(cseq++, Request.REGISTER))
        headers.push(this.headerFactory.createFromHeader(fromAddress, new SipUtils().generateTag()))
        headers.push(this.headerFactory.createToHeader(fromAddress, null))
        headers.push(contactHeader)
        headers.push(this.headerFactory.createUserAgentHeader(this.userAgent))
        headers.push(this.headerFactory.createAllowHeader('INVITE'))
        headers.push(this.headerFactory.createAllowHeader('ACK'))
        headers.push(this.headerFactory.createAllowHeader('BYE'))
        headers.push(this.headerFactory.createAllowHeader('CANCEL'))
        headers.push(this.headerFactory.createAllowHeader('REGISTER'))
        headers.push(this.headerFactory.createAllowHeader('OPTIONS'))
        headers.push(this.headerFactory.createSupportedHeader('path'))
        headers.push(this.headerFactory.createHeader('X-Gateway-Ref', gwRef))
        headers.forEach(header => request.addHeader(header))
        this.sendRequest(request, gwHost)
    }

    sendRequest(request, gwHost) {
        try {
            const clientTransaction = this.sipProvider.getNewClientTransaction(request)
            clientTransaction.sendRequest()
        } catch (e) {
            print('DBG001')
            this.handleChallengeException(e, gwHost)
        }
        LOG.debug(request)
    }

    handleChallengeException(e, gwHost) {
        print('DBG002')
        this.registry.invalidate(gwHost)
        if (e instanceof Java.type('javax.sip.TransactionUnavailableException') ||
            e instanceof Java.type('javax.sip.SipException')) {
            LOG.warn(`Unable to register with Gateway -> ${gwHost}. (Verify your network status)`)
        } else {
            LOG.warn(e)
        }
    }

    storeRegistry(gwURI, expires) {
        // Re-register before actual time expiration
        //let actualExpires = expires - 2 * 60 * this.checkExpiresTime
                print('DBG004')

        const reg = {
            username: gwURI.getUser(),
            host: gwURI.getHost(),
            ip: InetAddress.getByName(gwURI.getHost()).getHostAddress(),
            //expires: actualExpires,
            expires: expires,
            registeredOn: Date.now(),
            regOnFormatted: moment(new Date(Date.now())).fromNow()
        }

        this.registry.put(gwURI.toString(), reg)
    }

    removeRegistry(gwURIStr) {
              print('DBG005')
        this.registry.invalidate(gwURIStr)
    }

    listAsJSON() {
        const s = []
        const iterator = this.registry.asMap().values().iterator()

        while (iterator.hasNext()) {
            const reg = iterator.next()
            s.push(reg)
        }

        return s
    }

    isExpired(gwURIStr) {
        const reg = this.registry.getIfPresent(gwURIStr)

        if (reg === null) {
            return true
        }

        const elapsed = (Date.now() - reg.registeredOn) / 1000
        return reg.expires - elapsed <= 0
    }

    start() {
        LOG.info('Starting Registry service')
        const self = this

        global.timer.schedule(
            () => {
                const response = self.gatewaysAPI.getGateways()

                if (response.status === Status.OK) {
                    for (const cnt in response.result) {
                        const gateway = response.result[cnt]

                        if (gateway.spec.credentials === undefined) continue

                        const gwURIStr = `sip:${gateway.spec.credentials.username}@${gateway.spec.host}`
                        const expires = gateway.spec.expires ? gateway.spec.expires : 3600
                        if (self.isExpired(gwURIStr)) {
                            LOG.debug(`Register with ${gateway.metadata.name} using ${gateway.spec.credentials.username}@${gateway.spec.host}`)
                            self.requestChallenge(gateway.spec.credentials.username,
                                gateway.metadata.ref, gateway.spec.host, gateway.spec.transport, null, null, expires)
                        }

                        let registries = gateway.spec.registries

                        if (registries !== undefined) {
                            registries.forEach(function(h) {
                                if (self.isExpired(gwURIStr)) {
                                    LOG.debug(`Register with ${gateway.metadata.name} using ${gateway.spec.credentials.username}@${h}`)
                                    self.requestChallenge(gateway.spec.credentials.username, gateway.metadata.ref, h, gateway.spec.transport, null, null, expires)
                                }
                            })
                        }
                    }
                }
            },
            10000,
            this.checkExpiresTime * 60 * 1000
        )
    }

    stop() {
        // ??
    }
}

module.exports = Registry
<commit_msg>Cleanup<commit_after>/**
 * @author Pedro Sanders
 * @since v1
 */
const getConfig = require('@routr/core/config_util')
const LocatorUtils = require('@routr/location/utils')
const {
    Status
} = require('@routr/core/status')
const moment = require('moment')

const SipFactory = Java.type('javax.sip.SipFactory')
const SipUtils = Java.type('gov.nist.javax.sip.Utils')
const Request = Java.type('javax.sip.message.Request')
const InetAddress = Java.type('java.net.InetAddress')
const Caffeine = Java.type('com.github.benmanes.caffeine.cache.Caffeine')
const TimeUnit = Java.type('java.util.concurrent.TimeUnit')
const LogManager = Java.type('org.apache.logging.log4j.LogManager')

const LOG = LogManager.getLogger()
var cseq = 0

class Registry {

    constructor(sipProvider, dataAPIs) {
        this.gatewaysAPI = dataAPIs.GatewaysAPI
        this.checkExpiresTime = 1
        this.sipProvider = sipProvider
        this.config = getConfig()
        this.messageFactory = SipFactory.getInstance().createMessageFactory()
        this.headerFactory = SipFactory.getInstance().createHeaderFactory()
        this.addressFactory = SipFactory.getInstance().createAddressFactory()
        this.userAgent = new java.util.ArrayList()
        this.userAgent.add(this.config.metadata.userAgent)
        this.registry = Caffeine.newBuilder()
            .expireAfterWrite(this.checkExpiresTime, TimeUnit.MINUTES)
            .build()
    }

    getLPAddress(transport, received, rport) {
        try {
            const lp = this.sipProvider.getListeningPoint(transport)
            const host = this.config.spec.externAddr ? this.config.spec.externAddr : lp.getIPAddress()
            const port = rport ? LocatorUtils.fixPort(rport) : LocatorUtils.fixPort(lp.getPort())
            return received ? {
                host: received,
                port: port
            } : {
                host: host,
                port: port
            }
        } catch (e) {
            LOG.error(`Transport ${transport} not found in configs => .spec.transport.[*]`)
            return
        }
    }

    requestChallenge(username, gwRef, gwHost, transport, received, rport, expires) {
        const contactAddr = this.getLPAddress(transport, received, rport)
        const viaAddr = this.getLPAddress(transport)
        const request = this.messageFactory.createRequest(`REGISTER sip:${gwHost} SIP/2.0\r\n\r\n`)
        const fromAddress = this.addressFactory.createAddress(`sip:${username}@${gwHost}`)
        const contactAddress = this.addressFactory.createAddress(`sip:${contactAddr.host}:${contactAddr.port};bnc`)
        const contactHeader = this.headerFactory.createContactHeader(contactAddress)
        const viaHeader = this.headerFactory.createViaHeader(viaAddr.host, viaAddr.port, transport, null)
        viaHeader.setRPort()

        const headers = []

        headers.push(viaHeader)
        headers.push(this.sipProvider.getNewCallId())
        headers.push(this.headerFactory.createProxyRequireHeader('gin'))
        headers.push(this.headerFactory.createRequireHeader('gin'))
        headers.push(this.headerFactory.createExpiresHeader(expires))
        headers.push(this.headerFactory.createMaxForwardsHeader(70))
        headers.push(this.headerFactory.createCSeqHeader(cseq++, Request.REGISTER))
        headers.push(this.headerFactory.createFromHeader(fromAddress, new SipUtils().generateTag()))
        headers.push(this.headerFactory.createToHeader(fromAddress, null))
        headers.push(contactHeader)
        headers.push(this.headerFactory.createUserAgentHeader(this.userAgent))
        headers.push(this.headerFactory.createAllowHeader('INVITE'))
        headers.push(this.headerFactory.createAllowHeader('ACK'))
        headers.push(this.headerFactory.createAllowHeader('BYE'))
        headers.push(this.headerFactory.createAllowHeader('CANCEL'))
        headers.push(this.headerFactory.createAllowHeader('REGISTER'))
        headers.push(this.headerFactory.createAllowHeader('OPTIONS'))
        headers.push(this.headerFactory.createSupportedHeader('path'))
        headers.push(this.headerFactory.createHeader('X-Gateway-Ref', gwRef))
        headers.forEach(header => request.addHeader(header))
        this.sendRequest(request, gwHost)
    }

    sendRequest(request, gwHost) {
        try {
            const clientTransaction = this.sipProvider.getNewClientTransaction(request)
            clientTransaction.sendRequest()
        } catch (e) {
            this.handleChallengeException(e, gwHost)
        }
        LOG.debug(request)
    }

    handleChallengeException(e, gwHost) {
        this.registry.invalidate(gwHost)
        if (e instanceof Java.type('javax.sip.TransactionUnavailableException') ||
            e instanceof Java.type('javax.sip.SipException')) {
            LOG.warn(`Unable to register with Gateway -> ${gwHost}. (Verify your network status)`)
        } else {
            LOG.warn(e)
        }
    }

    storeRegistry(gwURI, expires) {
        // Re-register before actual time expiration
        //let actualExpires = expires - 2 * 60 * this.checkExpiresTime

        const reg = {
            username: gwURI.getUser(),
            host: gwURI.getHost(),
            ip: InetAddress.getByName(gwURI.getHost()).getHostAddress(),
            //expires: actualExpires,
            expires: expires,
            registeredOn: Date.now(),
            regOnFormatted: moment(new Date(Date.now())).fromNow()
        }

        this.registry.put(gwURI.toString(), reg)
    }

    removeRegistry(gwURIStr) {
        this.registry.invalidate(gwURIStr)
    }

    listAsJSON() {
        const s = []
        const iterator = this.registry.asMap().values().iterator()

        while (iterator.hasNext()) {
            const reg = iterator.next()
            s.push(reg)
        }

        return s
    }

    isExpired(gwURIStr) {
        const reg = this.registry.getIfPresent(gwURIStr)

        if (reg === null) {
            return true
        }

        const elapsed = (Date.now() - reg.registeredOn) / 1000
        return reg.expires - elapsed <= 0
    }

    start() {
        LOG.info('Starting Registry service')
        const self = this

        global.timer.schedule(
            () => {
                const response = self.gatewaysAPI.getGateways()

                if (response.status === Status.OK) {
                    for (const cnt in response.result) {
                        const gateway = response.result[cnt]

                        if (gateway.spec.credentials === undefined) continue

                        const gwURIStr = `sip:${gateway.spec.credentials.username}@${gateway.spec.host}`
                        const expires = gateway.spec.expires ? gateway.spec.expires : 3600
                        if (self.isExpired(gwURIStr)) {
                            LOG.debug(`Register with ${gateway.metadata.name} using ${gateway.spec.credentials.username}@${gateway.spec.host}`)
                            self.requestChallenge(gateway.spec.credentials.username,
                                gateway.metadata.ref, gateway.spec.host, gateway.spec.transport, null, null, expires)
                        }

                        let registries = gateway.spec.registries

                        if (registries !== undefined) {
                            registries.forEach(function(h) {
                                if (self.isExpired(gwURIStr)) {
                                    LOG.debug(`Register with ${gateway.metadata.name} using ${gateway.spec.credentials.username}@${h}`)
                                    self.requestChallenge(gateway.spec.credentials.username, gateway.metadata.ref, h, gateway.spec.transport, null, null, expires)
                                }
                            })
                        }
                    }
                }
            },
            10000,
            this.checkExpiresTime * 60 * 1000
        )
    }

    stop() {
        // ??
    }
}

module.exports = Registry
<|endoftext|>


<commit_before>/**
 * This is the HTTP server
 */
var express = require('express');
var path = require('path');
var app = express();

// SHORTCUT for system properties
var env = process.env;
var DEV_MODE = env.DEV_MODE === "true";

/**
 * GZIP content
 */
console.log('using compression');
app.use(require('compression')({
  level: 4
}));

/**
 * Serve static assets
 */
var wbdm;
if (DEV_MODE) {
  var webpackDevMiddleware = require("webpack-dev-middleware");
  var webpack = require("webpack");

  var compiler = webpack(require('./webpack-base.config'));

  wbdm = webpackDevMiddleware(compiler, {
    // webpack dev middleware options
  });
  app.use(wbdm);
} else {
  // just serve the static assets from dist
  app.use('/', express.static('dist'));
}

/**
 * Use prerender.io for SEO
 */
if (typeof env.PRERENDER_TOKEN === "string") {
  app.use(require('prerender-node').set('prerenderToken', env.PRERENDER_TOKEN));
}

/**
 * Pass some client configuration stored in environment variables to the client via a script tag
 */
app.get('/config.js', function (req, res) {
  res.setHeader('Content-Type', 'application/javascript');
  res.send('var config = ' + JSON.stringify({
      API_URL: env.API_URL
    }) + ';');
});

/**
 * Send all requests for other files to index html
 */
app.get('*', function (req, res) {
  var indexPath = path.join(__dirname, 'dist/index.html');
  if (DEV_MODE) {
    res.end(wbdm.fileSystem.readFileSync(indexPath));
  } else {
    res.end(indexPath);
  }
});

/**
 * Serve on 3000 or the passed in port
 */
var server = app.listen(env.PORT || 3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Listening on http://%s:%s', host, port);
});<commit_msg>fix index issue<commit_after>/**
 * This is the HTTP server
 */
var express = require('express');
var path = require('path');
var app = express();

// SHORTCUT for system properties
var env = process.env;
var DEV_MODE = env.DEV_MODE === "true";

/**
 * GZIP content
 */
console.log('using compression');
app.use(require('compression')({
  level: 4
}));

/**
 * Serve static assets
 */
var wbdm;
if (DEV_MODE) {
  var webpackDevMiddleware = require("webpack-dev-middleware");
  var webpack = require("webpack");

  var compiler = webpack(require('./webpack-base.config'));

  wbdm = webpackDevMiddleware(compiler, {
    // webpack dev middleware options
  });
  app.use(wbdm);
} else {
  // just serve the static assets from dist
  app.use('/', express.static('dist'));
}

/**
 * Use prerender.io for SEO
 */
if (typeof env.PRERENDER_TOKEN === "string") {
  app.use(require('prerender-node').set('prerenderToken', env.PRERENDER_TOKEN));
}

/**
 * Pass some client configuration stored in environment variables to the client via a script tag
 */
app.get('/config.js', function (req, res) {
  res.setHeader('Content-Type', 'application/javascript');
  res.send('var config = ' + JSON.stringify({
      API_URL: env.API_URL
    }) + ';');
});

/**
 * Send all requests for other files to index html
 */
app.get('*', function (req, res) {
  var indexPath = path.join(__dirname, 'dist/index.html');
  if (DEV_MODE) {
    res.end(wbdm.fileSystem.readFileSync(indexPath));
  } else {
    res.sendFile(indexPath);
  }
});

/**
 * Serve on 3000 or the passed in port
 */
var server = app.listen(env.PORT || 3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Listening on http://%s:%s', host, port);
});<|endoftext|>


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

var auth = require('../../lib/auth');
var db = require('../../db');
var user = require('../../lib/user');

module.exports = function(server) {
    // Sample usage:
    // % curl 'http://localhost:5000/user/friends?_user=ssatoken'
    /*
    Optional params:
    ?only={online|played|playedOnline|playing}
    &game=<game>
    */
    server.get({
        url: '/user/friends',
        validation: {
            _user: {
                description: "A user's SSA token",
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var GET = req.params;

        var _user = GET._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_error'});
                done();
                return;
            }

            (function(cb) {
                var friends = 'friends:' + id;
                if (GET.only === 'online') {
                    return client.sinter(friends, 'authenticated', cb);
                } else if (GET.only === 'played' && GET.game) {
                    return client.sinter(friends, 'gamePlayed:' + GET.game, cb);
                } else if (GET.only === 'playedOnline' && GET.game) {
                    return client.sinter(friends, 'authenticated', 'gamePlayed:' + GET.game, cb);
                } else if (GET.only === 'playing' && GET.game) {
                    return client.sinter(friends, 'gamePlaying:' + GET.game, cb);
                } else {
                    return client.smembers(friends, cb);
                }
            })(function(err, friends) {
                if (err || !friends) {
                    res.json(400, {error: 'no_friends'});
                    done();
                    return;
                }
                user.getPublicUserObjList(client, friends, function(objs) {
                    done();
                    res.json(objs);
                });
            });
        });
    }));

    // Sample usage:
    // % curl -X POST 'http://localhost:5000/user/friends' -d '_user=ssatoken&recipient=uid'
    server.post({
        url: '/user/friends/request',
        swagger: {
            nickname: 'request-friend',
            notes: 'Requests two users become friends',
            summary: 'Send friend request'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token.',
                isRequired: true
            },
            recipient: {
                description: 'The user ID of the friend request recipient',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var POST = req.params;

        var _user = POST._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        var recipient = POST.recipient;

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_eror'});
                done();
                return;
            }
            checkRecipient(id);
        });

        function checkRecipient(id) {
            client.hexists('users', recipient, function(err, resp) {
                if (err || !resp) {
                    res.json(400, {error: 'bad_recipient'});
                    done();
                    return;
                }
                checkNotFriends(id);
            });
        }
        function checkNotFriends(id) {
            client.sismember('friends:' + id, recipient, function(err, resp) {
                if (err || resp) {
                    res.json(400, {error: 'already_friends'});
                    done();
                    return;
                }
                checkNotFriendRequested(id);
            });
        }
        function checkNotFriendRequested(id) {
            client.sismember('friendRequests:' + id, recipient, function(err, resp) {
                if (err || resp) {
                    res.json(400, {error: 'already_requested'});
                    done();
                    return;
                }
                addFriendRequest(id);
            });
        }
        function addFriendRequest(id) {
            client.sadd('friendRequests:' + recipient, id);
            res.json(204, {error: null});
            // If the sender's request is fulfilled, publish the recipient a notification.
            client.sismember('ignoredFriendRequests:' + recipient, id, function(err, resp) {
                if (!resp) {
                    user.getUserFromID(client, id, function(err, publicUser) {
                        if (err || !publicUser) {
                            done();
                            return;
                        }
                        client.publish('user:' + recipient, JSON.stringify({
                            type: 'notification',
                            notification_type: 'friend_request',
                            from: publicUser
                        }));
                        done();
                    });
                }
            });
        }
    }));

    server.get({
        url: '/user/friends/requests',
        swagger: {
            nickname: 'friend-requests',
            notes: 'Returns a list of friend requests for the user.',
            summary: 'List of friend requests'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var GET = req.params;

        var _user = GET._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_eror'});
                done();
                return;
            }
            client.sdiff(
                'friendRequests:' + id,
                'ignoredFriendRequests:' + id,
                function(err, friends) {
                    if (err || !friends) {
                        res.json(500, {error: 'no_friends'});
                        done();
                        return;
                    }
                    user.getPublicUserObjList(client, friends, function(objs) {
                        done();
                        res.json(objs);
                    });
                }
            );
        });
    }));

    server.post({
        url: '/user/friends/accept',
        swagger: {
            nickname: 'accept-friend',
            notes: 'Accepts a friend request',
            summary: 'Accept friend request'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token.',
                isRequired: true
            },
            acceptee: {
                description: 'The user ID of someone who sent a friend request to the user',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var POST = req.params;

        var _user = POST._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        var acceptee = POST.acceptee;

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_eror'});
                done();
                return;
            }
            checkRequestExists(id);
        });

        function checkRequestExists(id) {
            client.sismember('friendRequests:' + id, acceptee, function(err, resp) {
                if (err || !resp) {
                    res.json(400, {error: 'request_not_found'});
                    done();
                    return;
                }
                addFriends(id);
            });
        }
        function addFriends(id) {
            client.sadd('friends:' + acceptee, id);
            client.sadd('friends:' + id, acceptee);
            client.srem('friendRequests:' + acceptee, id);
            client.srem('friendRequests:' + id, acceptee);
            client.srem('ignoreFriendRequests:' + acceptee, id);
            client.srem('ignoreFriendRequests:' + id, acceptee);
            res.json(204, {error: null});
            // If the sender's request is fulfilled, publish the recipient a notification.
            user.getUserFromID(client, id, function(err, publicUser) {
                if (err || !publicUser) {
                    done();
                    return;
                }
                client.publish('user:' + acceptee, JSON.stringify({
                    type: 'notification',
                    notification_type: 'friend_request_accepted',
                    from: publicUser
                }));
                done();
            });
        }
    }));

    server.post({
        url: '/user/friends/ignore',
        swagger: {
            nickname: 'ignore-friend',
            notes: 'Ignored an incoming friend request',
            summary: 'Ignore friend request'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token.',
                isRequired: true
            },
            acceptee: {
                description: 'The user ID of someone who sent a friend request to the user',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var POST = req.params;

        var _user = POST._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        var rejectee = POST.rejectee;

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_eror'});
                done();
                return;
            }
            client.sismember('friendRequests:' + id, rejectee, function(err, resp) {
                if (err || !resp) {
                    res.json(400, {error: 'request_not_found'});
                    done();
                    return;
                }
                client.sadd('ignoreFriendRequests:' + id, rejectee);
                res.json(204, {error: null});
                done();
            });
        });

    }));
};
<commit_msg>allow user to unfriend friends (fixes #8)<commit_after>var _ = require('lodash');

var auth = require('../../lib/auth');
var db = require('../../db');
var user = require('../../lib/user');

module.exports = function(server) {
    // Sample usage:
    // % curl 'http://localhost:5000/user/friends?_user=ssatoken'
    /*
    Optional params:
    ?only={online|played|playedOnline|playing}
    &game=<game>
    */
    server.get({
        url: '/user/friends',
        validation: {
            _user: {
                description: "A user's SSA token",
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var GET = req.params;

        var _user = GET._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_error'});
                done();
                return;
            }

            (function(cb) {
                var friends = 'friends:' + id;
                if (GET.only === 'online') {
                    return client.sinter(friends, 'authenticated', cb);
                } else if (GET.only === 'played' && GET.game) {
                    return client.sinter(friends, 'gamePlayed:' + GET.game, cb);
                } else if (GET.only === 'playedOnline' && GET.game) {
                    return client.sinter(friends, 'authenticated', 'gamePlayed:' + GET.game, cb);
                } else if (GET.only === 'playing' && GET.game) {
                    return client.sinter(friends, 'gamePlaying:' + GET.game, cb);
                } else {
                    return client.smembers(friends, cb);
                }
            })(function(err, friends) {
                if (err || !friends) {
                    res.json(400, {error: 'no_friends'});
                    done();
                    return;
                }
                user.getPublicUserObjList(client, friends, function(objs) {
                    done();
                    res.json(objs);
                });
            });
        });
    }));

    // Sample usage:
    // % curl -X POST 'http://localhost:5000/user/friends' -d '_user=ssatoken&recipient=uid'
    server.post({
        url: '/user/friends/request',
        swagger: {
            nickname: 'request-friend',
            notes: 'Requests two users become friends',
            summary: 'Send friend request'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token.',
                isRequired: true
            },
            recipient: {
                description: 'The user ID of the friend request recipient',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var POST = req.params;

        var _user = POST._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        var recipient = POST.recipient;

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_error'});
                done();
                return;
            }
            checkRecipient(id);
        });

        function checkRecipient(id) {
            client.hexists('users', recipient, function(err, resp) {
                if (err || !resp) {
                    res.json(400, {error: 'bad_recipient'});
                    done();
                    return;
                }
                checkNotFriends(id);
            });
        }
        function checkNotFriends(id) {
            client.sismember('friends:' + id, recipient, function(err, resp) {
                if (err || resp) {
                    res.json(400, {error: 'already_friends'});
                    done();
                    return;
                }
                checkNotFriendRequested(id);
            });
        }
        function checkNotFriendRequested(id) {
            client.sismember('friendRequests:' + id, recipient, function(err, resp) {
                if (err || resp) {
                    res.json(400, {error: 'already_requested'});
                    done();
                    return;
                }
                addFriendRequest(id);
            });
        }
        function addFriendRequest(id) {
            client.sadd('friendRequests:' + recipient, id);
            res.json(202, {success: true});
            // If the sender's request is fulfilled, publish the recipient a notification.
            client.sismember('ignoredFriendRequests:' + recipient, id, function(err, resp) {
                if (!resp) {
                    user.getUserFromID(client, id, function(err, publicUser) {
                        if (err || !publicUser) {
                            done();
                            return;
                        }
                        client.publish('user:' + recipient, JSON.stringify({
                            type: 'notification',
                            notification_type: 'friend_request',
                            from: publicUser
                        }));
                        done();
                    });
                }
            });
        }
    }));

    server.get({
        url: '/user/friends/requests',
        swagger: {
            nickname: 'friend-requests',
            notes: 'Returns a list of friend requests for the user.',
            summary: 'List of friend requests'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var GET = req.params;

        var _user = GET._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_error'});
                done();
                return;
            }
            client.sdiff(
                'friendRequests:' + id,
                'ignoredFriendRequests:' + id,
                function(err, friends) {
                    if (err || !friends) {
                        res.json(500, {error: 'no_friends'});
                        done();
                        return;
                    }
                    user.getPublicUserObjList(client, friends, function(objs) {
                        done();
                        res.json(objs);
                    });
                }
            );
        });
    }));

    server.post({
        url: '/user/friends/accept',
        swagger: {
            nickname: 'accept-friend',
            notes: 'Accepts a friend request',
            summary: 'Accept friend request'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token.',
                isRequired: true
            },
            acceptee: {
                description: 'The user ID of someone who sent a friend request to the user',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var POST = req.params;

        var _user = POST._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        var acceptee = POST.acceptee;

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_error'});
                done();
                return;
            }
            checkRequestExists(id);
        });

        function checkRequestExists(id) {
            client.sismember('friendRequests:' + id, acceptee, function(err, resp) {
                if (err || !resp) {
                    res.json(400, {error: 'request_not_found'});
                    done();
                    return;
                }
                addFriends(id);
            });
        }

        function addFriends(id) {
            client.sadd('friends:' + acceptee, id);
            client.sadd('friends:' + id, acceptee);
            client.srem('friendRequests:' + acceptee, id);
            client.srem('friendRequests:' + id, acceptee);
            client.srem('ignoreFriendRequests:' + acceptee, id);
            client.srem('ignoreFriendRequests:' + id, acceptee);
            res.json(202, {success: true});
            // If the sender's request is fulfilled, publish the recipient a notification.
            user.getUserFromID(client, id, function(err, publicUser) {
                if (err || !publicUser) {
                    done();
                    return;
                }
                client.publish('user:' + acceptee, JSON.stringify({
                    type: 'notification',
                    notification_type: 'friend_request_accepted',
                    from: publicUser
                }));
                done();
            });
        }
    }));

    server.post({
        url: '/user/friends/ignore',
        swagger: {
            nickname: 'ignore-friend',
            notes: 'Ignored an incoming friend request',
            summary: 'Ignore friend request'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token.',
                isRequired: true
            },
            acceptee: {
                description: 'The user ID of someone who sent a friend request to the user',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var POST = req.params;

        var _user = POST._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        var rejectee = POST.rejectee;

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_error'});
                done();
                return;
            }
            client.sismember('friendRequests:' + id, rejectee, function(err, resp) {
                if (err || !resp) {
                    res.json(400, {error: 'request_not_found'});
                    done();
                    return;
                }
                client.sadd('ignoreFriendRequests:' + id, rejectee);
                res.json(202, {success: true});
                done();
            });
        });
    }));

    server.post({
        url: '/user/friends/unfriend',
        swagger: {
            nickname: 'unfriend-friend',
            notes: 'Unfriends a friend',
            summary: 'Unfriend friend'
        },
        validation: {
            _user: {
                description: 'A user\'s SSA token.',
                isRequired: true
            },
            exfriend: {
                description: 'The user ID of someone whom to the user wants to unfriend',
                isRequired: true
            }
        }
    }, db.redisView(function(client, done, req, res) {
        var POST = req.params;

        var _user = POST._user;
        var email;
        if (!(email = auth.verifySSA(_user))) {
            res.json(403, {error: 'bad_user'});
            done();
            return;
        }

        var exfriend = POST.exfriend;

        user.getUserIDFromEmail(client, email, function(err, id) {
            if (err || !id) {
                res.json(500, {error: err || 'db_error'});
                done();
                return;
            }
            checkFriendExists(id);
        });

        function checkFriendExists(id) {
            client.sismember('friends:' + id, exfriend, function(err, resp) {
                if (err || !resp) {
                    res.json(400, {error: 'friend_not_found'});
                    done();
                    return;
                }
                unfriendFriend(id);
            });
        }

        function unfriendFriend(id) {
            client.srem('friends:' + exfriend, id);
            client.srem('friends:' + id, exfriend);
            res.json(202, {success: true});
            done();
        }
    }));
};
<|endoftext|>


<commit_before>(function() {
  'use strict';

  // This file defines Angular filters for DIM that may be shared among
  // different parts of DIM.

  const mod = angular.module('dimApp');

  /**
   * Take an icon path and make a full Bungie.net URL out of it
   */
  mod.filter('bungieIcon', ['$sce', function($sce) {
    return function(icon) {
      return $sce.trustAsResourceUrl('https://www.bungie.net' + icon);
    };
  }]);

  /**
   * Set the background-image of an element to a bungie icon URL.
   */
  mod.filter('bungieBackground', function() {
    return function backgroundImage(value) {
      return {
        'background-image': 'url(https://www.bungie.net' + value + ')'
      };
    };
  });

  /**
   * Filter a list of items down to only the equipped (or unequipped) items.
   * Usage: items | equipped:true
   */
  mod.filter('equipped', function() {
    return function(items, isEquipped) {
      return _.select(items || [], function(item) {
        return item.equipped === isEquipped;
      });
    };
  });

  /**
   * Sort the stores according to the user's preferences (via the order parameter).
   */
  mod.filter('sortStores', function() {
    return function sortStores(stores, order) {
      if (order === 'mostRecent') {
        return _.sortBy(stores, 'lastPlayed').reverse();
      } else if (order === 'mostRecentReverse') {
        return _.sortBy(stores, function(store) {
          if (store.isVault) {
            return Infinity;
          } else {
            return store.lastPlayed;
          }
        });
      } else {
        return _.sortBy(stores, 'id');
      }
    };
  });

  /**
   * Sort items according to the user's preferences (via the sort parameter).
   */
  mod.filter('sortItems', function() {
    return function(items, sort) {
      // Don't resort postmaster items - that way people can see
      // what'll get bumped when it's full.
      if (items.length && items[0].location.inPostmaster) {
        return items;
      }
      items = _.sortBy(items || [], 'name');
      if (sort === 'primaryStat' || sort === 'rarityThenPrimary' || sort === 'quality') {
        items = _.sortBy(items, function(item) {
          return (item.primStat) ? (-1 * item.primStat.value) : 1000;
        });
      }
      if (sort === 'quality') {
        items = _.sortBy(items, function(item) {
          return item.quality && item.quality.min ? -item.quality.min : 1000;
        });
      }
      if (sort === 'rarity' || sort === 'rarityThenPrimary') {
        items = _.sortBy(items, function(item) {
          switch (item.tier) {
          case 'Exotic':
            return 0;
          case 'Legendary':
            return 1;
          case 'Rare':
            return 2;
          case 'Uncommon':
            return 3;
          case 'Common':
            return 4;
          default:
            return 5;
          }
        });
      }
      return items;
    };
  });

  /**
   * A filter that will heatmap-color a background according to a percentage.
   */
  mod.filter('qualityColor', function() {
    return function getColor(value, property) {
      property = property || 'background-color';
      var color = 0;
      if (value <= 85) {
        color = 0;
      } else if (value <= 90) {
        color = 20;
      } else if (value <= 95) {
        color = 60;
      } else if (value <= 99) {
        color = 120;
      } else if (value >= 100) {
        color = 190;
      } else {
        return 'white';
      }
      var result = {};
      result[property] = 'hsl(' + color + ',85%,60%)';
      return result;
    };
  });

  /**
   * Reduce a string to its first letter.
   */
  mod.filter('firstLetter', function() {
    return function(str) {
      return str.substring(0, 1);
    };
  });

  /**
   * inserts the evaluated value of the "svg-bind-viewbox" attribute
   * into the "viewBox" attribute, making sure to capitalize the "B",
   * as this SVG attribute name is case-sensitive.
   */
  mod.directive('svgBindViewbox', function() {
    return {
      link: function(scope, element, attrs) {
        attrs.$observe('svgBindViewbox', function(value) {
          element.get(0).setAttribute('viewBox', value);
        });
      }
    };
  });
})();
<commit_msg>Added a hash list to manually sort consumables and materials in the inventory.<commit_after>(function() {
  'use strict';

  // This file defines Angular filters for DIM that may be shared among
  // different parts of DIM.

  const mod = angular.module('dimApp');

  /**
   * Take an icon path and make a full Bungie.net URL out of it
   */
  mod.filter('bungieIcon', ['$sce', function($sce) {
    return function(icon) {
      return $sce.trustAsResourceUrl('https://www.bungie.net' + icon);
    };
  }]);

  /**
   * Set the background-image of an element to a bungie icon URL.
   */
  mod.filter('bungieBackground', function() {
    return function backgroundImage(value) {
      return {
        'background-image': 'url(https://www.bungie.net' + value + ')'
      };
    };
  });

  /**
   * Filter a list of items down to only the equipped (or unequipped) items.
   * Usage: items | equipped:true
   */
  mod.filter('equipped', function() {
    return function(items, isEquipped) {
      return _.select(items || [], function(item) {
        return item.equipped === isEquipped;
      });
    };
  });

  /**
   * Sort the stores according to the user's preferences (via the order parameter).
   */
  mod.filter('sortStores', function() {
    return function sortStores(stores, order) {
      if (order === 'mostRecent') {
        return _.sortBy(stores, 'lastPlayed').reverse();
      } else if (order === 'mostRecentReverse') {
        return _.sortBy(stores, function(store) {
          if (store.isVault) {
            return Infinity;
          } else {
            return store.lastPlayed;
          }
        });
      } else {
        return _.sortBy(stores, 'id');
      }
    };
  });

  /**
   * Sort items according to the user's preferences (via the sort parameter).
   */
  mod.filter('sortItems', function() {
    return function(items, sort) {
      // Don't resort postmaster items - that way people can see
      // what'll get bumped when it's full.
      if (items.length && items[0].location.inPostmaster) {
        return items;
      }

      var specific_sort_order = []
      // Group like items in the General Section
      if (items.length && items[0].location.id == "BUCKET_CONSUMABLES") {
        specific_sort_order = [
          1043138475, // black-wax-idol
          1772853454, // blue-polyphage
          3783295803, // ether-seeds
          3446457162, // resupply-codes
          269776572,  // house-banners
          3632619276, // silken-codex
          2904517731, // axiomatic-beads
          1932910919, // network-keys

          417308266,  // three of coins

          2180254632, // ammo-synth
          928169143,  // special-ammo-synth
          211861343,  // heavy-ammo-synth

          705234570,  // primary telemetry
          3371478409, // special telemetry
          2929837733, // heavy telemetry
          4159731660, // auto rifle telemetry
          846470091,  // hand cannon telemetry
          2610276738, // pulse telemetry
          323927027,  // scout telemetry
          729893597,  // fusion rifle telemetry
          4141501356, // shotgun telemetry
          927802664,  // sniper rifle telemetry
          1485751393, // machine gun telemetry
          3036931873, // rocket launcher telemetry

          2220921114, // vanguard rep boost
          1500229041, // crucible rep boost
          1603376703, // HoJ rep boost

          2575095887, // Splicer Intel Relay
          3815757277, // Splicer Cache Key
          4244618453, // Splicer Key
        ]
      }

      // Group like items in the General Section
      if (items.length && items[0].location.id == "BUCKET_MATERIALS") {
        specific_sort_order = [
          1797491610, // Helium
          3242866270, // Relic Iron
          2882093969, // Spin Metal
          2254123540, // Spirit Bloom
          3164836592, // Wormspore
          3164836593, // Hadium Flakes

          452597397,  // Exotic Shard
          1542293174, // Armor Materials
          1898539128, // Weapon Materials

          937555249, // Motes of Light

          1738186005, // Strange Coins

          258181985,  // Ascendant Shards
          1893498008, // Ascendant Energy
          769865458,  // Radiant Shards
          616706469,  // Radiant Energy

          342707701,  // Reciprocal Rune
          342707700,  // Stolen Rune
          2906158273, // Antiquated Rune
          2620224196, // Stolen Rune (Charging)
          2906158273, // Antiquated Rune (Charging)
        ]
      }

      if (specific_sort_order.length > 0) {
        items = _.sortBy(items, function(item) {
          var ix = specific_sort_order.indexOf(item.hash);
          return (ix == -1) ? 999 : ix;
        })
        return items;
      }

      items = _.sortBy(items || [], 'name');
      if (sort === 'primaryStat' || sort === 'rarityThenPrimary' || sort === 'quality') {
        items = _.sortBy(items, function(item) {
          return (item.primStat) ? (-1 * item.primStat.value) : 1000;
        });
      }
      if (sort === 'quality') {
        items = _.sortBy(items, function(item) {
          return item.quality && item.quality.min ? -item.quality.min : 1000;
        });
      }
      if (sort === 'rarity' || sort === 'rarityThenPrimary') {
        items = _.sortBy(items, function(item) {
          switch (item.tier) {
          case 'Exotic':
            return 0;
          case 'Legendary':
            return 1;
          case 'Rare':
            return 2;
          case 'Uncommon':
            return 3;
          case 'Common':
            return 4;
          default:
            return 5;
          }
        });
      }
      return items;
    };
  });

  /**
   * A filter that will heatmap-color a background according to a percentage.
   */
  mod.filter('qualityColor', function() {
    return function getColor(value, property) {
      property = property || 'background-color';
      var color = 0;
      if (value <= 85) {
        color = 0;
      } else if (value <= 90) {
        color = 20;
      } else if (value <= 95) {
        color = 60;
      } else if (value <= 99) {
        color = 120;
      } else if (value >= 100) {
        color = 190;
      } else {
        return 'white';
      }
      var result = {};
      result[property] = 'hsl(' + color + ',85%,60%)';
      return result;
    };
  });

  /**
   * Reduce a string to its first letter.
   */
  mod.filter('firstLetter', function() {
    return function(str) {
      return str.substring(0, 1);
    };
  });

  /**
   * inserts the evaluated value of the "svg-bind-viewbox" attribute
   * into the "viewBox" attribute, making sure to capitalize the "B",
   * as this SVG attribute name is case-sensitive.
   */
  mod.directive('svgBindViewbox', function() {
    return {
      link: function(scope, element, attrs) {
        attrs.$observe('svgBindViewbox', function(value) {
          element.get(0).setAttribute('viewBox', value);
        });
      }
    };
  });
})();
<|endoftext|>


<commit_before>if(!JAVAFX_APP_JNLP_SUBDOMAIN){
	JAVAFX_APP_JNLP_SUBDOMAIN = "apps";
}

function launchApplication(jnlpfile) {
	dtjava.launch(            {
			url : 'http://' +JAVAFX_APP_JNLP_SUBDOMAIN +'.jrebirth.org/' + JAVAFX_APP_JNLP,
			jnlp_content : ''
		},
		{
			javafx : '2.0+'
		},
		{}
	);
	return false;
}
function javafxEmbed() {
	dtjava.embed(
		{
			url : 'http://'+JAVAFX_APP_JNLP_SUBDOMAIN+'.jrebirth.org/' + JAVAFX_APP_JNLP,
			placeholder : 'javafx-app-placeholder',
			width : JAVAFX_APP_WIDTH,
			height : JAVAFX_APP_HEIGHT,
			jnlp_content : ''
		},
		{
			javafx : '2.0+'
		},
		{}
	);
}
<!-- Embed FX application into web page once page is loaded -->
dtjava.addOnloadCallback(javafxEmbed);<commit_msg>Fix Website launcher :(<commit_after>if(typeof JAVAFX_APP_JNLP_SUBDOMAIN === 'undefined'){
	JAVAFX_APP_JNLP_SUBDOMAIN = "apps";
}

function launchApplication(jnlpfile) {
	dtjava.launch(            {
			url : 'http://' +JAVAFX_APP_JNLP_SUBDOMAIN +'.jrebirth.org/' + JAVAFX_APP_JNLP,
			jnlp_content : ''
		},
		{
			javafx : '2.0+'
		},
		{}
	);
	return false;
}
function javafxEmbed() {
	dtjava.embed(
		{
			url : 'http://'+JAVAFX_APP_JNLP_SUBDOMAIN+'.jrebirth.org/' + JAVAFX_APP_JNLP,
			placeholder : 'javafx-app-placeholder',
			width : JAVAFX_APP_WIDTH,
			height : JAVAFX_APP_HEIGHT,
			jnlp_content : ''
		},
		{
			javafx : '2.0+'
		},
		{}
	);
}
<!-- Embed FX application into web page once page is loaded -->
dtjava.addOnloadCallback(javafxEmbed);<|endoftext|>


<commit_before>/**
 * @class app
 * @description
 * @time 2014-12-05 18:56
 * @author StarZou
 **/
(function (window, document) {
    'use strict';

    console.log(_.compact([0, 1, false, 2, '', 3]));

    console.log(_.difference([1, 2, 3, 4, 5], [5, 2, 10]));

})(window, document);<commit_msg>添加 ui-router 示例<commit_after>/**
 * @class app
 * @description
 * @time 2014-12-05 18:56
 * @author StarZou
 **/
(function (window, document) {
    'use strict';

    //var value, obj = {};
    //
    //value = _.map({'one': 1, 'two': 2, 'three': 3}, function (value, key) {
    //    obj[key] = value * 3;
    //
    //    console.log(arguments);
    //
    //    return value * 3;
    //});
    //
    //
    //value = _.map([1, 2, 3], function (value, key) {
    //    obj[key] = value * 3;
    //
    //    console.log(arguments);
    //
    //    return value * 3;
    //});
    //
    //console.log(value);
    //console.log(obj);

    //var v = _.invoke([1, 2, 3], function () {
    //    return this * 3;
    //});
    //console.log(v);

    //var sum = _.reduce(['a', 'b', 'x'], function (sum, num) {
    //    console.log(arguments);
    //    return sum + num;
    //});

    //var mapped = _.reduce({'a': 8, 'b': 6, 'c': 7}, function (o, num, key) {
    //    console.log(arguments);
    //    return o + num;
    //});
    //console.log(mapped);

})(window, document);<|endoftext|>